机器学习——k近邻算法(kNN)

一、k-近邻算法介绍

1、概念

K-Nearest Neighbor算法又叫KNN算法,属于监督学习算法的一种,是机器学习里的一个经典算法。简单地说,k-近邻算法是采用测量不同特征值之间的距离方法进行分类。

2、工作原理

存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据吼,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

简单地说就是,预测样本与特征空间中的k个样本最相似(距离最近),预测样本属于这k个样本中的最多类别。

例:电影分类问题

电影名称类别与未知电影的距离
《交作业》恐怖片1.22
《2022》剧情片6.78
《机器学习》恐怖片11.26
《李白》剧情片42.6
《福建》剧情片82.65
《一棵树》剧情片73.99
《镜子》恐怖片23.87
《水龙头》剧情片112.39
《未知电影》

取k为3,可得三个距离未知电影最近的电影依次是:《交作业》、《2022》、《机器学习》。三部电影中,有一部电影属于剧情片,有两部电影属于恐怖片,样本类别最多的为恐怖片,因此判断未知电影属于恐怖片。

3、优缺点

  • 优点:精度高、对异常值不敏感、无数据输入假定。
  • 缺点:计算复杂度高、空间复杂度高
  • 适用数据范围:数值型和标称型

4、一般流程

  1. 收集数据:可以使用任何方法。
  2. 准备数据:距离计算所需要的数值,最好是结构化的数据格式。
  3. 分析数据:可以使用任何方法。
  4. 训练算法:k-近邻算法不需要。
  5. 测试算法:计算错误率。
  6. 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。

5、实现流程

  1. 选好k值
  2. 分别计算特征空间中的点与待测点之间的距离,使用欧式距离公式:在这里插入图片描述
  3. 按距离递增次序排序
  4. 选取与当前点距离最小的k个点
  5. 统计k个点所在类别出现的频率
  6. 频率最高的类别即为待测点的预测分类

6、k值大小的影响

  • k值过大:预测标签比较稳定,但可能过于平滑(例如:样本集中一共有100个样本,k值选择100,那么不管是哪个预测标签结果都是一样的)
  • k值过小:预测标签容易受到样本影响

7、要求

1.近邻点要有相同相近的类别。
2.特征维度的尺度(范围)要具备一致性。

二、代码实现`

1、先导入模块和数据

from numpy import *
import operator

def createDataSet(): 
    group = array([[3,104],[2,100],[1,81],[101,10],[99,5],[98,2],[18,90]])
    labels = ['爱情片','爱情片','爱情片','动作片','动作片','动作片','未知']
    return group,labels

2、为每组数据分类,生成一个分类器

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]   
    diffMat = tile(inX, (dataSetSize, 1))- dataSet  
    sqDiffMat = diffMat**2      
    sqDistances = sqDiffMat.sum(axis = 1)    
    distances = sqDistances**0.5             #开方,计算距离
    sortedDistIndicices = distances.argsort()   #返回distances中的元素从小到大排序后的索引
    classCount = {}    #定义一个记录类别次数的字典

    for i in range(k): 
        voteIlabel = labels[sortedDistIndicices[i]]    #前k个类别
        classCount[voteIlabel] = classCount.get(voteIlabel,0 ) + 1  
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)     
    return sortedClassCount[0][0]  #返回次数最多的类别

3、 测试结果

if __name__=="__main__":

    #训练集
    group,labels = createDataSet()
    print(group)
    print(labels)

    #测试集
    test = [100,20]
    test_class = classify0(test, group, labels, 3)
    print(test_class)

4、结果

[[  3 104]
 [  2 100]
 [  1  81]
 [101  10]
 [ 99   5]
 [ 98   2]
 [ 18  90]]
['爱情片', '爱情片', '爱情片', '动作片', '动作片', '动作片', '未知']
动作片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值