《机器学习实战》K近邻算法原理及实现

一、问题描述

鸢尾花(IRIS)有很多种,但又因为特征很是相近,不好区分,通过大量数据归纳的特征,我们通过花萼长度(Sepal.Length),花萼宽度(Sepal.Width),花瓣长度(Petal.Length),花瓣宽度(Petal.Width),4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类,从而更加有效地进行区分。

二、算法原理

原理:已知晓部分样本的类别。然后利用欧式距离,计算所有点的距离,对所有数据做一个排序,确定最小元素前K个元素所在的分类,计算需要判别的样本与已知样本不同特征值之间的距离。最后,将需判别的样本划分入在其临近的k个样本中出现次数最多的类别之中。

三、数据可视化

iris,txt(Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。数据集包含150个数据集,分为3类,每类50个数据,每个数据包含4个属性(花萼长度,花萼宽度,花瓣长度,花瓣宽度) 。

《机器学习实战》K近邻算法原理及实现

横坐标:花萼长度(Sepal.Length)

纵坐标:花萼宽度(Sepal.Width)

《机器学习实战》K近邻算法原理及实现

横坐标:花瓣长度(Petal.Length)

纵坐标:花瓣宽度(Petal.Width)

四、主要程序函数

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 = {}  
    for i in range(k):  
        voteIlabel = labels[sortedDistIndicies[i]]  
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1  
    sortedClassCount = sorted(classCount.items(),  
                              key=operator.itemgetter(1),reverse=True)  
    return sortedClassCount[0][0]  

五、测试结果

取K=3,选取50%、60%、70%、80%的数据做测试集,绘制正确率折线图

         K=4,、5、6、7、8、9、10  取50%的数据做测试数据,绘制正确率折线图

K值        测试数据比例(数据量)                错误率

K=3       50%(75)                                   0.053333

              60%(90)                                    0.044444

               63%(93)                                      0.043011

              65%(97)                                      0.041237

              66%(99)                                      0.535354

              70%(105)                                     0.533333

              80%(120)                                     0.566667

              90%(135)                                     0.740741

《机器学习实战》K近邻算法原理及实现

分析:在测试数据量到65%之前算法分类出错的概率都非常低,65%之后错误率有明显提高。

K值           测试数据比例(数据量)                错误率

K=3           50%(75)                                    0.053333

K=4           50%(75)                                    0.040000

K=5           50%(75)                                      0.040000

K=6           50%(75)                                      0.053333

K=7           50%(75)                                      0.053333

K=8           50%(75)                                      0.040000

K=9           50%(75)                                      0.040000

K=10        50%(75)                                      0.040000

K=15        50%(75)                                      0.053333

K=20        50%(75)                                      0.053333

K=25        50%(75)                                      0.053333

K=30        50%(75)                                      0.120000

《机器学习实战》K近邻算法原理及实现

分析:在K值小于25时,分类算法出错的概率很小,K值影响不大,但25之后错误率开始上升。

六、总结与体会

优点:

1)简单、有效。

2)重新训练的代价较低(类别体系的变化和训练集的变化,在Web环境和电子商务应用中是很常见的)。

3)计算时间和空间线性于训练集的规模(在一些场合不算太大)。

4)由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

5)该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。

缺点:

1)KNN算法是懒散学习方法(lazy learning,基本上不学习),一些积极学习的算法要快很多。

2)类别评分不是规格化的(不像概率评分)。

3)输出的可解释性不强,例如决策树的可解释性较强。

4)该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。

5)计算量较大。目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本

七、参考文献

【1】Peter Harrington。《机器学习实战》

【2】python使用matplotlib绘制柱状图教程

http://www.jb51.net/article/104924.htm

【3】机器学习实战之kNN算法

https://www.cnblogs.com/zy230530/p/6780836.html

非常感谢阅读!如有不足之处,请留下您的评价和问题