kNN算法流程
一般情况下,kNN有如下流程:
(1)收集数据:确定训练样本集合测试数据;
(2)计算测试数据和训练样本集中每个样本数据的距离;
常用的距离计算公式:
欧式距离公式:d(x,y)=∑ni=1(xi−yi)2−−−−−−−−−−−−√d(x,y)=∑i=1n(xi−yi)2
曼哈顿距离公式:d(x,y)=∑ni=1|xi−yi|d(x,y)=∑i=1n|xi−yi|
(3)按照距离递增的顺序排序;
(4)选取距离最近的k个点;
(5)确定这k个点中分类信息的频率;
(6)返回前k个点中出现频率最高的分类,作为当前测试数据的分类。
主要代码:
from numpy import *
import operator
#定义KNN算法分类器函数
#函数参数包括:(测试数据,训练数据,分类,k值)
def classify(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() #排序并返回index
#选择距离最近的k个值
classCount={}
for i in range(k):
voteIlabel=labels[sortedDistIndicies[i]]
#D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
#排序,降序
sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]
注:
- 这里用到矩阵运算,计算测试样本和每个训练样本之间的L2距离
- KNN存在的不足是,每次对一个样本进行预测时,都要对整个训练样本做一次测距,耗时严重;
- 因此,对应的KD-Tree就能很好的解决这个问题,不用遍历所有样本,即可求得距离coor点最近的K个点的序号。详细过程可参考前面的文章 “KD-Tree的C++实现”
参考资料:https://blog.csdn.net/moxigandashu/article/details/71169991