1.算法介绍
k近邻(k-Nearest Neighbour, 简称kNN) 学习是一种常用的监督学习方法。其工作机制是给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本,然后根据这k个“邻居”的信息来进行预测。
- 分类任务中可以使用“投票法”,即选择这k个样本中出现最多的类别标记作为预测结果。
- 回归任务中可以使用“平均法”,即将这k个样本的实值输出标记的平均值作为预测结果
注:可以基于距离远近进行加权平均或加权投票,距离越近的样本权重越大。
算法特点:1. lazy learning的代表,训练时间消耗为零。此类学习技术在训练阶段仅仅是把样本保存起来,待收到测试样本后再进行处理。2.该算法适用于样本数较少、典型性较好的样本集。3. 适用数据范围:数值型和标称型。
- k-NN算法优点:精度高、对异常值不敏感、无数据输入假定;
- k-NN算法缺点:计算复杂度高、空间复杂度高。
2.k值的选择
- 近似误差:可理解为训练误差,即与训练集的拟合程度。
- 估计误差:是对误差大小的估计。与函数集的大小成反比。即函数集大时,包含正解的概率越大,估计误差越小,反之。
因此:
- 较小的k值:近似误差小,估计误差大,模型复杂,容易发生过拟合。
- 较大的k值:近似误差增大,估计误差变小,模型变得简单。
注:应用中,一般会选择较小的k,通常采用交叉验证法来选取最优k值。
3.算法流程
(1)收集数据:可以使用任何方法。
(2)准备数据:计算所需要的数值。
(3)分析数据:可以使用任何方法。
(4)测试算法:计算准确率。
(5)使用算法:1. 输入样本数据和结构化的输出结果;2. 运行k-近邻算法判断输入数据分别属于哪个分类。
4.代码示范(python)
def classify0(inX, dataSet, labels, k):
#inX-输入向量,dataSet-训练样本集,
#labels-标签向量(元素数目和矩阵dataSet的行数相同),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={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
sortedClassCount = sorted(classCount.iteritems(),
#选择距离最小的k个点
key=operator.itemgetter(1), reverse=True)
#排序
return sortedClassCount[0][0]