KNN 算法的思想
KNN(K Neareast Neighbours) 又称 K 邻近算法,是一种直观明了的算法,可以理解为“近朱者赤近墨者黑”。
你也许听过一句话“一个人的收入是身边交往最多的五个人的收入的平均值”,这就是“密友五次理论”,这个理论恰好就体现了 KNN 算法的思想。
![](https://img.haomeiwen.com/i811131/4e7acf275ce76bfc.jpg)
以上图为例,假设有两种数据,红色五角星和蓝色三角形,现在我们不知道绿色方块是属于哪一类,我们该怎么判断呢?
如果我们用 KNN 算法的思想来判断,找到绿色方块最近的几个邻居,根据最近几个邻居的来推测绿色方块是属于哪一类。
假设 K = 5,距离绿色方块最近的 5 个邻居是 3 蓝 + 2 红;
假设 K = 10,距离绿色方块最近的 10 个邻居是 6 红 + 4蓝
由上面的步骤中还有 2 个问题需要确定:
1. 怎么计算距离
两个样本间的距离代表了样本之间的相似度,距离越大差异性越大;距离越小相似性越高。 KNN 中常用的距离计算方式有
-
欧氏距离
欧氏距离是我们最常用的距离公式,在 n 维空间中的欧式距离可以表示为:
-
曼哈顿距离
曼哈顿距离等于两个点在坐标系上绝对轴距总和:
2. 怎么判定类别
- 少数服从多数,取 K 个样本中类别最多的为预测类别
- 加权法,依据离预测样本的距离远近设定权值,越近的权重越大
解决了这两个问题后我们来梳理一下 KNN 算法的流程,KNN 模型的建立过程大概有这几部:
- 给定测试样本,计算它与训练集中每一个样本的距离
- 找出距离最近的 K 个样本,作为测试样本的邻近
- 依据这 K 个邻近样本的类别来预测样本的类别
K 值的选择
那么问题来了,怎么选择 K 值呢? K 值的大小直接影响了 KNN 的预测结果。 如果 K 值过小,如果邻近点是噪声点,那这个噪声的影响会过大,这样会产生过拟合; 如果 K 值过大,那么距离较远的样本也会对预测结果造成影响,虽然这样能减小误差,但是也会让整个模型变得简单,产生欠拟合的情况。 在实际应用中,一般采用交叉验证的方式选择 K 值,选择在较小的范围,同时在验证集上准确率最高的最终确定为 K 值。
动手练习
用 KNN 算法来进行手写数字分类,使用的是sklearn
中自带的数据集。
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_digits
from sklearn.metrics import accuracy_score
from sklearn import preprocessing
import matplotlib.pyplot as plt
# 加载数据
digits = load_digits()
data = digits.data
print(data.shape)
# 查看第一个数字图像
print(digits.target[0])
plt.gray()
plt.imshow(digits.images[0])
plt.show()
![](https://img.haomeiwen.com/i811131/aa8c3bd0f4c8f510.png)
分割数据为训练集和测试集,由于要进行距离计算,而且我们只关心数字的形状,所以先将图像数据进行Z-Score规范化会更好:
train_x, test_x, train_y, test_y = train_test_split(data, digits.target, test_size = 0.2, random_state = 2020)
# Z-Score
scaler = preprocessing.StandardScaler()
train_scaled_x = scaler.fit_transform(train_x)
test_scaled_x = scaler.transform(test_x)
用 KNN 模型进行训练和预测:
knn = KNeighborsClassifier()
knn.fit(train_scaled_x, train_y)
pred_y = knn.predict(test_scaled_x)
print("knn accuracy: %.4f" % accuracy_score(test_y, pred_y))
最后预测准确度为 0.9861 KNN 模型虽然简单,但有时效果还是不错的~~
总结一下 KNN 算法的优缺点:
-
优点:
- 模型简单,易于理解、易于实现、无需估计参数
- 适合对稀有事件进行分类
- 特别适合多分类问题
-
缺点:
- 对测试样本分类时的计算量大,内存开销大,评分慢
- 可解释性差,无法给出决策树那样的规则
- 当样本不平衡时,在选取 K 个邻居时容易造成大容量样本占多数的情况,影响分类结果
- 没有提前训练过程,直到要分类预测时才对进行,这是一种消极学习法
END
网友评论