KNN的工作原理是:存在一个样本数 据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据 与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的 特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们 只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。 最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
从上面的概念中,可以总结出KNN算法的一般方法:
1.准备好已有的数据,每个数据都有自己的标签(分类)
2.将待判别分类的数据,与已经分类的数据集相比较,计算距离。
3.选出最相近的前K个元素。
4.K个元素中出现最多次数的标签(分类),即为该数据的标签。
从这四点出发,KNN分类器还是很好实现的,其中计算的距离为欧氏距离:
二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离:
简单实现KNN分类器
假设我们已有如下数据集:
dataSet = array([1.0,1.1],[1.0,1.0],[0,0],[0,0.1])
labels = ["A","A","B","B"] #各个点的标签
分类器:
def classify0(intX,dataSet,labels,k):
#inX 为待分类的数据,k为选取前K个元素
dataSetSize = dataSet.shape[0]
#dataSetSize = 4
new_dataset = tile(intX,(dataSetSize,1))
#假设intX=[2.0,1.0]
#tile(intX,(dataSetSize,1))为:
# [[2.0 1.0]
# [2.0 1.0]
# [2.0 1.0]
# [2.0 1.0] ]
diffMat = newdataset - dataSet
#将新的点扩成与现有数据集大小相同的数据集后,相减,得到新点与各点坐标差的数据集
sqDiffMat = diffMat**2 #计算平方
sqDistances = sqDiffMat.sum(axis=1)
#上面两步就是计算 (x1-x2)**2+(y1-y2)**2
distances = sqDistances**0.5 #开平方
sortedDistIndicies = distances.argsort()
#将得到的距离由小到大进行排列,返回的是各元素的下角标
classCount = {}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
#dict.get(key,default):如果这个字典中没有这个key,就返回default,这一步是在计算前K个点,每个标签出现的次数。
sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
#关于dict.iteritems()和dict.items(),可以参看
#http://www.iplaypy.com/jinjie/items-iteritems.html
return sortedClassCount[0][0]