机器学习实战~k近邻算法(上)

k-近邻算法:存在一个样本集,并知道该样本集中每一个数据与所属分类(标签)的对应关系,当输入一个没有标签的新数据时,怎么判断该数据属于哪一个分类,这时就需要用到k-邻近算法。那么具体怎么用呢?选择距离该数据最近的k个最相似数据,并选出这k个数据中出现次数最多的分类,这个分类就是新数据的分类。
举例说明:假如我是一个女生,我身边的妹子都很漂亮并且能力都很强,那由此可知我长的是不是也应该差不多的好看呢(偷笑)?能力是不是也不算太弱呢?有点人以类聚物以群分的感觉哈~~~~不瞎扯了,咳咳,开始讲解代码

以下代码是在jupyter中进行的

准备:使用python导入数据

from numpy import *
import numpy as np
import operator#运算符模块

def createDataSet():
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])#numpy中的数组(4,2)
    labels = ['A','A','B','B']#标签
    return group,labels

测试一下我们创建的数据集是否正确

group, labels = createDataSet()
print(group,labels)
print(group.shape)#读取矩阵的长度

输出:

[[ 1.   1.1]
 [ 1.   1. ]
 [ 0.   0. ]
 [ 0.   0.1]] ['A', 'A', 'B', 'B']
(4, 2)

准备好数据集,接下来当然就是k邻近算法啦,

该算法思想:找到距离某个新数据最近的k个点,并计算这k个点所属分类最的数量,从而找出落入点最多的分类。首先计算出这个新数据和数据集中各点的欧式距离,并排序。找出前k个数据

#k-近邻算法核心代码
#四个参数分别为:用于分类的输入向量inX,输入的训练样本集dataSet,标签向量labels,k表示用于选择最近邻居的数目
def classify0(x, dataSet, labels, k):
    size = dataSet.shape[0]#读取第一维度的长度
    diffMat = np.tile(x, (size, 1)) - dataSet
    #tile(x,(4,1))在列方向上重复[1,1]1次,行4次,即创建一个数组和原数据集形状相同
    sqDiffMat = diffMat ** 2
    sqDistances = sqDiffMat.sum(axis = 1)#axis=1代表将一个矩阵的每一行向量相加
    distances = sqDistances ** 0.5#开根号
    sortedDisIndicies = distances.argsort()#排序
    classCount = {}#定义一个字典
    for i in np.arange(k):#找到前k个数据,放入字典中
        voteIlabel = labels[sortedDisIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    
    value = -1
    for key in classCount:
        if value < classCount[key]:
            flag = key
            value = classCount[key]
    return flag

是不是有点看不懂了,没关系,最开始我也不懂。毕竟谁生下来都不是自带大神属性,开始剖析这段代码我相信大部分人到for循环的时候就差不多开始迷惑了,for循环中还有一个重要的知识点

python字典的get()函数

classCount.get(voteIlabel, 0)返回字典classCount中voteIlabel元素对应的值,若无,则进行初始化为0,初始化的值即为get()的第二个参数,
第一次遇到标签A,classCount.get(voteIlabel, 0)值为0,
第二次遇到标签A,classCount.get(voteIlabel, 0)时,值加1
上代码测试

import numpy as np
labels = ['A', 'A', 'B', 'B']
sortedDisIndicies =[1,2,3]
classCount = {}
for i in np.arange(3):
        # 按照从小到大,依次取出相应的 label
        voteIlabel = labels[sortedDisIndicies[i]]
        print(voteIlabel,classCount.get(voteIlabel, 0))
        # 如果字典中没该 label 就添加 value 为 1 ,如果有,则在原来基础上 value + 1
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
        
        print(voteIlabel,classCount[voteIlabel])

输出:

A 1
A 2
B 1
B 2
B 2
B 3

OK,到这,我们已经完成分类计数,接下来字典值比较
领出来再测一遍

print(classCount)
value = -1
#key是字典的键,classCount[key]该键对应的值
for key in classCount:
    if value < classCount[key]:
        flag = key
        print(flag)
        value = classCount[key]
        print(value)

输出:

{'A': 2, 'B': 3}
A
2
B
3

OK ,现在应该全懂了,我们来个例子预测一下我们的算法吧
现在我们的数据集有四个数据,四个对应的标签

group, labels = createDataSet()#创建数据集
classify0([1,1], group, labels, 3)#测试[1,1]属于哪个分类,找最近的3个数据实验

输出:

'A'

第一个分类器就构造完成了,接下来就是测试分类器,见下篇吧
源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从一个最基本的算法示例来入门机器学习 第一个分类算法 --- k-近邻算法(简单地说,k近邻算法采用测量不同特征值...
    PetitBread阅读 3,619评论 0 1
  • k-近邻算法 优点: 精度高、对异常值不敏感、无数据输入假定。 缺点: 计算复杂度高、空间复杂度高。 适用数据范围...
    KaitoLucifer阅读 2,675评论 0 0
  • k近邻算法 原理 存在一个样本数据集合,也称作训练样本集,且我们知道样本中每个数据的分类信息。当我们输入未分类的新...
    Aaaaaaaaaaayou阅读 3,226评论 1 10
  • 寒假第三周了,这个假期已经过半,每天的晨诵似乎已经养成了习惯。作为一个八岁孩子来说,能每天都记得一件事情也已经很不...
    光阴深处阅读 2,144评论 0 0
  • 遥望红尘朵朵开 笑我痴 笑我娇 千娇百媚情意浓 等你情 等你爱 轻舞罗衫花心吐 思心雨 思心露 瓣瓣花...
    大红羊阅读 2,962评论 17 37