给定一个数据集,对新的输入样本,在数据集中找到与新的输入样本距离最近的k个样本,将这k个样本中最多数属于某个类的那个类别当作新的输入样本的类别。
距离度量
- 欧式距离: D = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 D=\sqrt{(x_2-x_1)^2+(y_2-y_1)^2} D=(x2−x1)2+(y2−y1)2
- 曼哈顿距离: D = ∣ x 2 − x 1 ∣ + ∣ y 2 − y 1 ∣ D=|x_2-x_1|+|y_2-y_1| D=∣x2−x1∣+∣y2−y1∣
- 余弦值
实现
K近邻最简单的实现就是直接遍历整个数据集,叫线性扫描(linear scan),但是这样的话,需要将输入的样本和数据集中每个样本进行度量距离,如果数据集很大的话,计算是非常耗时的。所以比较常见的是KD树。
代码
from numpy import tile
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 #根号
sortedDistIndicies = distances.argsort() #排序
classCount={}
#选择距离最小的k个点
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
#排序,将classCount字典分解为元祖列表,导入itemgeeter方法,按照第二个元素的次序对元祖进行排序
#此处排序为逆序,即从大到小排序,最后返回发生频率最高的元素标签。
sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]
# 为预测数据所在分类:kNN.classify0([0,0], group, labels, 3)