k近邻算法_K-近邻算法的Python实现

ed7d435353f6ca356dd6582e9c71bb0e.png

K-近邻法(K-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一种基本分类与回归方法。

KNN的算法过程

9b482599289bf2b40bd9dc37a3a7b3a2.png

KNN的算法过程

图中的数据集中的样本包含标签属性(红色三角、蓝色正方形),即我们知道样本集中每一个样本与所属分类的对应关系。一类是蓝色正方形,一类是红色三角形,那个绿色的圆形(无标签)是待分类的测试样本。

  • 当K= 3 时,与绿色圆形最近的3个样本中,三角形多,这个待分类样本为红色三角形。
  • 当K= 5 时,与绿色圆形最近的5个样本中,正方形多,这个待分类样本为蓝色正方形。

在训练样本集中,每个样本都存在标签(监督学习)。预测对新数据(无标签)的标签类型,将新数据的每个特征与每个训练集中的样本特征进行比较(计算),然后提取训练集中前K个最相似数据的分类标签,出现次数最多的那个分类标签,作为新数据的分类标签。

KNN本质是基于一种数据统计的方法,一种惰性学习方式。它没有明显的数据训练过程,而是把训练集加载到内存后(因此训练集大时,占用大量存储空间),直接使用未知的数据与已知的数据进行比较(计算复杂度高),就可以预测(计算)新数据的标签类型了。KNN是分类算法中最简单有效的方法,效果也不错,但需要对每个新数据进行计算,才可以进行标签类型预测,相当耗时。


K值选择

当K值较小时,相当于使用较小量的训练集训练模型,容易发生过拟合,使得泛化误差会增大,K值的较小意味着模型变得复杂。

当K值较大时,相当于使用较大的训练集进行模型训练,容易发生欠拟合,使得泛化误差会增大,K值的较大意味着整体模型变得复杂。

K 的取值范围一般为1~20 ,且为奇数,一般低于训练样本数的平方根,通常采取交叉验证法来选取最优的K值。


KNN算法的一般流程

  1. 数据采集:使用NumPy与pandas以及sklearn.datasets等方式获取或处理数据集
  2. 数据预处理:测试集、训练集构建,进行数据标准化处理。
  3. 模型训练:此步骤不适用于k-近邻算法,KNN本质是基于一种数据统计的方法。
  4. 模型测试:使用测试集,验证模型性能。
  5. 模型优化:使用交叉验证法优化K值取值。

KNN的Python实现

1. 数据采集

首先先简单介绍下数据集,数据描述如下:

  • 数据来源:from sklearn.datasets import load_iris
  • 实例数量:150(三个类各50个)
  • 属性数量:4个特征数值属性、一个预测属性,属性信息如下:1. 萼片长度(厘米);2. 萼片宽度(厘米);3.花瓣长度(厘米);4. 花瓣宽度(厘米);5. 类(Iris Setosa——山鸢尾,Iris Versicolour——杂色鸢尾,Iris Virginica——维吉尼亚鸢尾)
  • 缺少属性值:None
  • 类别分布:3个类别各占33.3%。

数据样例

5.1,3.5,1.4,0.2,Iris-setosa4.9,3.0,1.4,0.2,Iris-setosa4.7,3.2,1.3,0.2,Iris-setosa4.6,3.1,1.5,0.2,Iris-setosa5.0,3.6,1.4,0.2,Iris-setosa

使用from sklearn.datasets import load_iris获取数据集,Python实现如下::

22d3b9f40f0654fa138062eb7ba97d8b.png

2. 数据预处理:数据标准化

我们将整个数据集随机抽取80%作为训练集、剩余的20%作为测试集,并且进行数据标准化处理,且重复运行时,训练集与测试集不发生变化,Python实现如下:

b05d4db998bb77a2bd9a15ecf6478827.png

3. 模型训练及测试

KNN本质是基于一种数据统计的方法,没有明显的前期训练过程,而是程序开始运行时,把数据集加载到内存后,不需要进行训练,就可以开始分类了,Python实现如下:

ef1138d702e1e568fe24e22b9a7a6a5d.png

我们使用测试集测试KNN模型的准确性,结果如下,准确率为97%,Python实现如下:

dcb4eef43d6412f68dd5dbf499115adc.png

4 .K值选择优化

上述实现中,KNeighborsClassifier的K为默认值5,我们使用GridSearchCV实现K值优化,我们将K取值范围设置为1~11之间,计算选择哪个K值的测试效果最佳,当K=3时,准确率为100%,Python实现如下:

8b6950823e2b8f944ff9a21105793077.png

优化结果如下:

KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=1, n_neighbors=3, p=2, weights='uniform')best_param s: {'n_neighbors': 3}best_score : 0.95The Accuracy of K-Nearest Neighbor Classifier is : 1.0

需要注意的是,此处的结果时基于当前训练集与测试集划分的背景下的算法性能,因此这部分结果可能存在过拟合。对于KNN算法,我们一般选取一个较小的K值,通常采取交叉验证法来选取最优的K值。

交叉验证法选取最优的K值

使用StratifiedKFold分层采样交叉切分,我们将全部数据集划分为5份,确保训练集,测试集中各类别样本的比例与原始数据集中相同,Python实现如下:

aacd0fa99bffc66a32bc5269c54012e6.png

计算累计识别率,Python实现如下:

c369fc0efdd5461e13e9568e507b672f.png

StratifiedKFold方法生成5个训练集和测试集,计算这5个组合的平均识别率,Python实现如下:

418b0afe9c1585ab78e6ac7b953a2e07.png

计算结果如下,我们可以看到当K=6、7、10、11、12时,准确率最高。

ab5af71c78571f38714b13e7ac39e624.png

KNN的主要优缺点

KNN的主要优点

  • 精度高,对异常值不敏感、无数据输入假定,适用于样本容量比较大的分类,而样本容量较小时,这种算法比较容易产生误分。

KNN的主要缺点

  • 特征数非常多的大数据量背景下,内存开销大,计算复杂度高、空间复杂度高。

KNN的与K-Means区别

另外,大概介绍下KNN的与K-Means区别,如下:

099b98f97c53441a7707990190c2d5e3.png
后续会继续分享线性、决策树、SVM、随机森林、朴素贝叶斯等算法介绍及Python实现,若对你有所帮助,欢迎大家评论、留言、关注,感谢支持!
a6cac537af96d7c31eb99dddf3e8ccf7.png
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值