1.概念
K近邻(k-Nearest Neighbor,简称kNN)是一种常用的监督学习方法,是机器学习中入门的算法。
KNN即在给定的测试样本中,基于某种距离来确定训练集中与其最靠近的k个训练样本,然后根据这k个邻居的情况来对未知样本进行预测和分类。有点类似我们所说的“近朱者赤,近墨者黑”的意思,一般用于分类,比如常见的用来辨别红酒的品种、花瓣的种类、电影的分类、肿瘤是良性还是恶性等。
如下图所示,绿色圆点为未知颜色,蓝色和红色为已知分类,当k=3时,与未知绿色圆点最近的为两个红色点和一个蓝色点,根据“K近邻”算法原则,可判断未知绿色与红色三角形为同一类。
2.KNN算法流程
对未知类别属性的数据集中的每个点依次执行以下操作:
(1) 计算已知类别数据集中的点与当前点之间的距离;
距离就是两点之间的平面距离,对于二维数据P1(X1,Y1)和P2(X2,Y2)两点的距离,可以用欧几里得距离为:
即未知数据Xi与数据集中任意数据的距离为:
(2) 按照距离递增次序排序;
(3) 选取与当前点距离最小的k个点;
(4) 确定前k个点所在类别的出现频率;
(5) 返回前k个点出现频率最高的类别作为当前点的预测分类。
3.Python实现
import numpy as np
from math import sqrt
import operator as opt
def kNN(X_data, labels, testData, k):
disSqr = (X_data - testData) ** 2 # 计算差值的平方
disSqrSums = disSqr.sum(axis=1) # 求每一行的差值平方和
dis = disSqrSums ** 0.5 # 开根号,得出每个样本到测试点的距离
sortedIndices = dis.argsort() # 排序,得到排序后的下标
indices = sortedIndices[:k] # 取最小的k个
labelCount = {} # 存储每个label的出现次数
for i in indices:
label = labels[i]
labelCount[label] = labelCount.get(label, 0) + 1 # 次数加一
sortedCount = sorted(labelCount.items(), key=opt.itemgetter(1), reverse=True) # 对label出现的次数从大到小进行排序
return sortedCount[0][0] # 返回出现次数最大的label
dataSet = np.array([[2, 3], [6, 8]])
labels = ['a', 'b']
testData = np.array([7, 5.5])
result = kNN(dataSet, labels, testData, 1)
print(result)
输出结果
b