博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
K-近邻算法的Python实现 : 源代码分析
阅读量:6426 次
发布时间:2019-06-23

本文共 2607 字,大约阅读时间需要 8 分钟。

网上介绍K-近邻算法的样例非常多。其Python实现版本号基本都是来自于机器学习的入门书籍《机器学习实战》,尽管K-近邻算法本身非常easy,但非常多刚開始学习的人对其Python版本号的源码理解不够,所以本文将对其源码进行分析。

什么是K-近邻算法?

简单的说,K-近邻算法採用不同特征值之间的距离方法进行分类。所以它是一个分类算法。

长处:无数据输入假定,对异常值不敏感

缺点:复杂度高

好了,直接先上代码,等会在分析:(这份代码来自《机器学习实战》)

def classify0(inx, dataset, lables, k):    dataSetSize = dataset.shape[0]    diffMat = tile(inx, (dataSetSize, 1)) - dataset    sqDiffMat = diffMat**2    sqDistance = sqDiffMat.sum(axis=1)    distances = sqDistance**0.5    sortedDistances = distances.argsort()    classCount={}    for i in range(k):        label = lables[sortedDistances[i]]        classCount[label] = classCount.get(label, 0) + 1    sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1), reverse=True)    return sortedClassCount[0][0]
 

该函数的原理是:

存在一个样本数据集合,也称为训练集,在样本集中每一个数据都存在标签。在我们输入没有标签的新数据后,将新数据的每一个特征与样本集中相应的特征进行比較,然后提取最相似(近期邻)的分类标签。

一般我们仅仅选样本数据集中前K 个最相似的数据。最后。出现次数最多的分类就是新数据的分类。

classify0函数的參数意义例如以下:

inx : 是输入没有标签的新数据,表示为一个向量。

dataset: 是样本集。

表示为向量数组。

labels:相应样本集的标签。

k:即所选的前K。

用于产生数据样本的简单函数:

def create_dataset():    group = array([[1.0, 1.1], [1.0, 1.1], [0, 0], [0, 0.1]])    labels = ['A', 'A', 'B', 'B']    return group, labels

注意,array是numpy里面的。

我们须要实现import进来。

from numpy import *import operator

我们在调用时。

group,labels = create_dataset()result = classify0([0,0], group, labels, 3)print result
显然,[0,0]特征向量肯定是属于B 的,上面也将打印B。

知道了这些。刚開始学习的人应该对实际代码还是非常陌生。不急,正文開始了!

源代码分析

dataSetSize = dataset.shape[0]

shape是array的属性,它描写叙述了一个数组的“形状”,也就是它的维度。比方,

In [2]: dataset = array([[1.0, 1.1], [1.0, 1.1], [0, 0], [0, 0.1]])In [3]: print dataset.shape(4, 2)
所以,dataset.shape[0] 就是样本集的个数。

diffMat = tile(inx, (dataSetSize, 1)) - dataset
tile(A,rep)函数是基于数组A来构造数组的,详细怎么构造就看第二个參数了。其API介绍有点绕,但简单的使用方法相信几个样例就能明确。

我们看看tile(inx, (4, 1))的结果,

In [5]: tile(x, (4, 1))Out[5]: array([[0, 0],       [0, 0],       [0, 0],       [0, 0]])
你看。4扩展的是数组的个数(本来1个。如今4个),1扩展的是每一个数组元素的个数(原来是2个,如今还是两个)。

为证实上面的结论,

In [6]: tile(x,(4,2))Out[6]: array([[0, 0, 0, 0],       [0, 0, 0, 0],       [0, 0, 0, 0],       [0, 0, 0, 0]])
和。

In [7]: tile(x,(2,2))Out[7]: array([[0, 0, 0, 0],       [0, 0, 0, 0]])
关于,tile的详细使用方法。请自行查阅API DOC。

得到tile后,减去dataset。

这类似一个矩阵的减法。结果仍是一个 4 * 2的数组。

In [8]: tile(x, (4, 1)) - datasetOut[8]: array([[-1. , -1.1],       [-1. , -1.1],       [ 0. ,  0. ],       [ 0. , -0.1]])
结合欧式距离的求法,后面的代码就清晰些,对上面结果平方运算,求和。开方。

我们看看求和的方法,

sqDiffMat.sum(axis=1)
当中。

In [14]: sqDiffmatOut[14]: array([[ 1.  ,  1.21],       [ 1.  ,  1.21],       [ 0.  ,  0.  ],       [ 0.  ,  0.01]])

求和的结果是对行求和,是一个N*1的数组。

假设要对列求和,

sqlDiffMat.sum(axis=0)
argsort()是对数组升序排序的。

classCount是一个字典,key是标签。value是该标签出现的次数。

这样。算法的一些详细代码细节就清楚了。

转载地址:http://ilyga.baihongyu.com/

你可能感兴趣的文章
Zabbix监控Windows主机
查看>>
IBM x3850 RAID5数据恢复方案及过程
查看>>
移动计算领域五大机遇:交通运输优势待挖掘
查看>>
如何把win7 旗舰版升级到sp1最新版本
查看>>
android 调用系统界面
查看>>
Software Enginering-------using git
查看>>
浅谈IP地址-1
查看>>
我的友情链接
查看>>
C#中的线程池使用(一)
查看>>
利用Windows Server Backup功能备份活动目录
查看>>
RAC维护手记08-ASM磁盘组信息查看常用命令
查看>>
实验08 磁盘和文件系统管理
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
FastDFS整合nginx后,nginx一直报错
查看>>
使用Fuel安装OpenStack juno之三使用OpenStack创建云主机和Volume
查看>>
zabbix安装源
查看>>
Eclipse+kafka集群 实例源码
查看>>
Vijos 1067Warcraft III 守望者的烦恼
查看>>
SQL语句
查看>>