机器学习之K-近邻算法

1.橙子还是柚子该例子来自于《算法图解》,看下图中的水果是橙子还是柚子?我的思维过程类似于这样:我脑子里面有个图表图中左下的表示橙子,右上的表示柚子,取橙子和柚子的两个特征(大和红),一般而言

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

1. 橙子还是柚子

  该例子来自于《算法图解》,看下图中的水果是橙子还是柚子?

  机器学习之K-近邻算法

  我的思维过程类似于这样:我脑子里面有个图表

  机器学习之K-近邻算法

  图中左下的表示橙子,右上的表示柚子,取橙子和柚子的两个特征(大和红),一般而言,柚子更大、更红,上图的水果又大又红,因此可能是柚子,那下面的水果呢?

  机器学习之K-近邻算法

  一种办法是看它的邻居,离它最近的邻居的三个邻居中有两个橙子一个柚子,因此这个水果很可能是橙子

  上面刚使用的方法就是KNN(K-近邻算法),感觉是不是很简单

2. K-近邻算法步骤

  对未知类别属性的数据集中的每个点依次执行以下操作:

(1)计算已知类别数据集中的点与当前点之间的距离

(2)按照距离递增顺序排序

(3)选取与当前点距离最小的K个点

(4)确定前k个点所在类别的出现频率

(5)返回前k个点出现频率最高的类别作为当前点的预测分类

3. K-近邻算法实现

  使用Python按照上面的步骤实现算法

import numpy as np

def knn(labels, dataset, in_data,k):

    """
    labels:list
    dataset:ndarray
    in_data:ndarray
    k:int
    """
    row = dataset.shape[0]
    sub_set = dataset - np.tile(in_data,(row,1))
    sqrt_set = sub_set ** 2
    distance = sqrt_set.sum(axis=1) ** 0.5
    dic = {}
    sortedIndex_list = distance.argsort()
    # 算出邻居中对应的label次数
    result = {}
    for i in range(k):
        key = sortedIndex_list[i]
        result[labels[key]] = result.get(labels[key],0)+1
        
    result_list=sorted(result.items(), key=lambda x: x[1],reverse=True)
    return result_list[0][0]

4. 示例1:约会匹配

需求:

  根据数据特征值(玩游戏所耗时间百分比、每年获得的飞行里程数、每周消费的冰淇淋公升数),判断对该约会对象的喜好程度,绝对是否要去约会

准备工作:

(1)数据集:dataset\datingTestSet2.txt

(2)数据集特征:

  a. 玩游戏所耗时间百分比  —->数据集中的第一列

  b. 每年获得的飞行里程数  —->数据集中的第二列

  c. 每周消费的冰淇淋公升数 —->数据集中的第三列

(3)样本分类标签:—->数据集中的第四列

(4)测试数据集:dataset\datingTestSet.txt

实现:

(1)从文件提取数据集和标签

def file2matrix(filename):

    """将文件数据转换为numpy.ndarray"""
    
    list_lines = []
    with open(filename,'r') as pf:
        lines = pf.readlines()
        for line in lines:
            list_lines.append([float(i) for i in line.strip().split('\t')])
            
    matrix = np.array(list_lines)
    data_set = matrix[:,0:-1]
    class_labels = matrix[:,-1:]
    class_labels = class_labels.reshape(1,1000).tolist()[0]
    return data_set,class_labels

(2)对数据集中的特征值数据进行归一化处理

def auto_norm(dataset):
    """
    为了防止各特征值之间的数值差距太大而影响计算结果,
    对矩阵数据进行归一化处理,将每个特征值都转换为[0,1]
    """
    min = dataset.min(0)
    max = dataset.max(0)
    sub = max - min
    norm_dataset = np.zeros(dataset.shape)
    row = dataset.shape[0]
    norm_dataset = dataset - np.tile(min,(row,1))
    norm_dataset = norm_dataset / np.tile(sub,(row,1))
    return norm_dataset,sub,min

(3)使用测试数据集对算法进行测试

def test_datingTestSet():
    data_set,date_labels = file2matrix('dataset\\datingTestSet2.txt')
    norm_dataset,sub,min = auto_norm(data_set)

    #根据数据集测试KNN算法的正确率
    rows = norm_dataset.shape[0]
    ok = 0
    for i in range(rows):
        result = knn(date_labels,norm_dataset,norm_dataset[i,:],3)
        if result == date_labels[i]:
            ok += 1
        else:
            print("测试错误结果为{},正确结果为{}".format(result, date_labels[i]))
    print("测试总记录数为{},成功记录数为{},KNN算法成功率为{}".format(rows,ok,ok/rows))

输出:

机器学习之K-近邻算法

5. 示例2:手写识别系统

需求:

  根据dataset\trainingDigits文件夹中的样本数据和dataset\testDigits文件夹中的样本数据测试KNN算法

实现:

(1)将每个文件中的数据(32*32)转换为matrix(m*1024)

def imgae2matrix(filepath):
    filelist = os.listdir(filepath)
    m = len(filelist)
    array_m_1024 = np.zeros((m,1024))
    k = 0
    labels = []
    for file in filelist:
        #对文件名进行处理得到labels
        label = file.split('_')[0]
        labels.append(label)
        array_1_1024 = np.zeros((1,1024))
        with open(os.path.join(filepath,file),'r') as pf:
            for i in range(32):
                line = pf.readline()
                for j in range(32):
                    array_1_1024[0,32*i+j] = int(line[j])
        array_m_1024[k,:] = array_1_1024
        k+=1
    return array_m_1024,labels

(2)使用knn算法测试成功率

def test_numbers():
    array_m_1024,labels = imgae2matrix('dataset\\trainingDigits\\')
    test_array_m_1024,test_labels = imgae2matrix('dataset\\testDigits\\')
    ok = 0
    rows = test_array_m_1024.shape[0]
    for i in range(rows):
        in_data = test_array_m_1024[i,:]
        result = knn(labels, array_m_1024, in_data,5)
        if result == test_labels[i]:
            ok += 1
        else:
            print("测试错误结果为{},正确结果为{}".format(result, test_labels[i]))
    print("测试总记录数为{},成功记录数为{},KNN算法成功率为{}".format(rows,ok,ok/rows))

(3)输出

机器学习之K-近邻算法

6. 总结

  K-近邻算法是分类数据最简单有效的算法,使用算法时必须有接近实际数据的训练样本数据,如果训练数据集很大,必须使用大量的存储空间,此外由于必须对数据集中的每个数据计算距离值,实际使用时可能非常耗时。

  K-近邻算法的另一个缺陷是它无法给出任何数据的基础结构信息,因此我们也无法知晓平均实例样本和典型实例样本具有什么特征。

  代码和数据集都已上传至:https://github.com/lizoo6zhi/MachineLearn.samples

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120032.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 巡检,不再要你磨破机房门槛

    巡检,不再要你磨破机房门槛

    2021年8月1日
    63
  • JS文件相互调用

    JS文件相互调用title JS 文件相互调用 date 2019 06 2517 03 36tags JavaScript TypeScript 我们在写 js 代码的时候 常常会碰到两个 js 文件之间相互调用 直接上代码 messageText js 定义数组 varmsgArray name Infunction value 在函数 name

    2025年11月29日
    3
  • java自定义注解和使用[通俗易懂]

    自定义注解@Target自定义注解的使用范围ElementType.METHOD:方法声明ElementType.TYPE:类、接口(包括注解类型)或enum声明ElementType.CONSTRUCTOR:构造器的声明ElementType.FIELD:域声明(包括enum实例)ElementType.LOCAL_VARIABLE:局部变量声明ElementType.PACKA…

    2022年4月13日
    66
  • Linux系统安装Cache数据库配置环境

    Linux系统安装Cache数据库配置环境1 Cach 介绍 nbsp 官网 https www intersystems com 开发者社区 https community intersystems com nbsp nbsp gt gt nbsp download nbsp Cach 安装指南 https docs intersystems com latest csp docbook DocBook UI Page cls KEY G

    2025年11月8日
    3
  • Fiddler+雷电模拟器进行APP抓包

    Fiddler+雷电模拟器进行APP抓包1、Fiddler下载地址:下载最新版Fiddler,强烈建议在官网下载:https://www.telerik.com/download/fiddler雷电模拟器下载地址:选择3.0正式版(注意,高版本无法抓包,只能下载3.0正式版)https://www.ldmnq.com/other/version-history-and-release-notes.html?log=3正常傻瓜式安装,下一步,下一步,安装完毕后,先不用急于打开软件。3.下载并安装Fiddler证书生成器:http:

    2022年5月30日
    199
  • pycharm全局搜索(mac)

    pycharm全局搜索(mac)command+shift+f

    2022年5月31日
    75

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号