KNN算法的sklearn实践

一、KNN算法概述  
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。Cover和Hart在1968年提出了最初的邻近算法。KNN是一种分类(classification)算法,它输入基于实例的学习(instance-based learning),属于懒惰学习(lazy learning)即KNN没有显式的学习过程,也就是说没有训练阶段,数据集事先已有了分类和特征值,待收到新样本后直接进行处理。与急切学习(eager learning)相对应。
KNN是通过测量不同特征值之间的距离进行分类。  
思路是:如果一个样本在特征空间中的k个最邻近的样本中的大多数属于某一个类别,则该样本也划分为这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。  
提到KNN,网上最常见的就是下面这个图可以帮助我们理解。  
我们要确定绿点属于哪个颜色(红色或者蓝色),要做的就是选出距离目标点距离最近的k个点,看这k个点的大多数颜色是什么颜色。当k取3的时候,我们可以看出距离最近的三个,分别是红色、红色、蓝色,因此得到目标点为红色!
KNN算法的sklearn实践_第1张图片
算法的描述:
  1)计算测试数据与各个训练数据之间的距离;  
  2)按照距离的递增关系进行排序; 
  3)选取距离最小的K个点;  
  4)确定前K个点所在类别的出现频率;
  5)返回前K个点中出现频率最高的类别作为测试数据的预测分类
  
  
二、关于K的取值
 K:临近数,即在预测目标点时取几个临近的点来预测。
 K值得选取非常重要,因为:  
 1)如果当K的取值过小时,一旦有噪声得成分存在们将会对预测产生比较大影响,例如取K值为1时,一旦最近的一个点是噪声,那么就会出现偏差,K值的减小就意味着整体模型变得复杂,容易发生过拟合; 
  2)如果K的值取的过大时,就相当于用较大邻域中的训练实例进行预测,学习的近似误差会增大。这时与输入目标点较远实例也会对预测起作用,使预测发生错误。K值的增大就意味着整体的模型变得简单;
  3)如果K==N的时候,那么就是取全部的实例,即为取实例中某分类下最多的点,就对预测没有什么实际的意义了;
  4)K的取值尽量要取奇数,以保证在计算结果最后会产生一个较多的类别,如果取偶数可能会产生相等的情况,不利于预测。

K的取法:
  常用的方法是从k=1开始,使用检验集估计分类器的误差率。重复该过程,每次K增值1,允许增加一个近邻。选取产生最小误差率的K。一般k的取值不超过20,上限是n的开方,随着数据集的增大,K的值也要增大。
  
  
三、关于距离的选取
距离就是平面上两个点的直线距离  
关于距离的度量方法,常用的有:欧几里得距离、余弦值(cos), 相关度 (correlation), 曼哈顿距离 (Manhattan distance)或其他。 
欧氏距离(Euclidean Distance) 定义: 两个点或元组P1=(x1,y1)和P2=(x2,y2)的欧几里得距离是
KNN算法的sklearn实践_第2张图片
  距离公式为:(多个维度的时候是多个维度各自求差)
  在这里插入图片描述
四、总结
 KNN算法是最简单有效的分类算法,简单且容易实现。
 当训练数据集很大时,需要大量的存储空间,而且需要计算待测样本和训练数据集中所有样本的距离,所以非常耗时  
 KNN对于随机分布的数据集分类效果较差,对于类内间距小,类间间距大的数据集分类效果好,而且对于边界不规则的数据效果好于线性分类器。 
 KNN对于样本不均衡的数据效果不好,需要进行改进。改进的方法时对k个近邻数据赋予权重,比如距离测试样本越近,权重越大。 
 KNN很耗时,时间复杂度为O(n),一般适用于样本数较少的数据集,当数据量大时,可以将数据以树的形式呈现,能提高速度,常用的有kd-tree和ball-tree。
 
 六、sklearn库的应用
   我利用sklearn库来进行了kNN的应用(这个库是真的很方便了,可以借助这个库好好学习一下,我是用KNN算法进行预测,这里用一个鸢尾花的实例,因为这篇主要是关于KNN的知识,所以不对sklearn的过多的分析,而且我用的还不深入),sklearn库内的算法与自己手搓的相比功能更强大、拓展性更优异、易用性也更强。还是很受欢迎的。(确实好用,简单)代码如下:

随机生成1000个点,6个类别的分类数据

from sklearn.datasets import make_blobs
data=make_blobs(n_features=2,n_samples=1000,random_state=8,centers=6)

import seaborn as sns #对其进行可视化
import matplotlib.pyplot as plt
X,y = data
plt.scatter(X[:,0],X[:,1],c=y,cmap=plt.cm.spring,edgecolors = ‘k’)
KNN算法的sklearn实践_第3张图片

from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier() # KNN分类器实例化
clf.fit(X,y)

训练结果可视化

import numpy as np
x_min ,x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min ,y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx , yy = np.meshgrid(np.arange(x_min,x_max, .02),
np.arange(y_min,y_max, .02))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.pcolormesh(xx,yy,Z,cmap=plt.cm.Pastel1)
plt.scatter(X[:, 0],X[:, 1],c=y,cmap=plt.cm.spring,edgecolor=‘k’)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title(“Classifier:KNN”)
KNN算法的sklearn实践_第4张图片

对数据点(8.88, 6.66)的类别进行预测

import numpy as np
x_min ,x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min ,y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx , yy = np.meshgrid(np.arange(x_min,x_max, .02),
np.arange(y_min,y_max, .02))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.pcolormesh(xx,yy,Z,cmap=plt.cm.Pastel1)
plt.scatter(X[:, 0],X[:, 1],c=y,cmap=plt.cm.spring,edgecolor=‘k’)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title(“Classifier:KNN”)
plt.scatter(8.88,6.66,marker=’*’,c=‘red’,s=1000)
KNN算法的sklearn实践_第5张图片

评估模型的准确率

print(‘模型正确率:{:.2f}’.format(clf.score(X,y)))
print(‘新数据点的分类是:’, clf.predict([[8.88,6.66]]))
KNN算法的sklearn实践_第6张图片

你可能感兴趣的:(KNN算法的sklearn实践)