机器学习 - K-最近邻算法(KNN)
KNN
KNN 是一种简单、有监督的机器学习(ML)算法,可用于分类或回归任务——并且也常用于缺失值插补。它基于这样一个思想:给定数据点最近的观测值是在数据集中最“相似”的观测值,因此我们可以根据最近现有点的值对不可预见的点进行分类。通过选择 K,用户可以选择在算法中使用的附近观测值的数量。
在这里,我们将向您展示如何实现用于分类的 KNN 算法,并展示不同的 K 值如何影响结果。
它是如何工作的?
K 是要使用的最近邻居的数量。对于分类,通过多数投票来确定新观测值应归入哪个类别。较大的 K 值通常对异常值更稳健,并产生比非常小的值更稳定的决策边界(K=3 比 K=1 更好,后者可能会产生不理想的结果)。
实例
首先,可视化一些数据点:
import matplotlib.pyplot as plt x = [4, 5, 10, 4, 3, 11, 14 , 8, 10, 12] y = [21, 19, 24, 17, 16, 25, 24, 22, 21, 21] classes = [0, 0, 1, 0, 0, 1, 1, 0, 1, 1] plt.scatter(x, y, c=classes) plt.show()
结果:

现在我们使用 K=1 来拟合 KNN 算法:
from sklearn.neighbors import KNeighborsClassifier data = list(zip(x, y)) knn = KNeighborsClassifier(n_neighbors=1) knn.fit(data, classes)
并使用它来分类一个新的数据点:
实例
new_x = 8 new_y = 21 new_point = [(new_x, new_y)] prediction = knn.predict(new_point) plt.scatter(x + [new_x], y + [new_y], c=classes + [prediction[0]]) plt.text(x=new_x-1.7, y=new_y-0.7, s=f"new point, class: {prediction[0]}") plt.show()
结果:

现在我们做同样的事情,但使用更高的 K 值来改变预测:
实例
knn = KNeighborsClassifier(n_neighbors=5) knn.fit(data, classes) prediction = knn.predict(new_point) plt.scatter(x + [new_x], y + [new_y], c=classes + [prediction[0]]) plt.text(x=new_x-1.7, y=new_y-0.7, s=f"new point, class: {prediction[0]}") plt.show()
结果:

例子解释
导入您需要的模块。
您可以在我们的 Matplotlib 教程 中学习 Matplotlib 模块。
scikit-learn 是 Python 中一个流行的机器学习库。
import matplotlib.pyplot as plt from sklearn.neighbors import KNeighborsClassifier
创建类似于数据集中变量的数组。我们有两个输入特征(x 和 y),然后是一个目标类别(class)。预先用目标类别标记的输入特征将用于预测新数据的类别。请注意,虽然我们这里只使用两个输入特征,但这种方法适用于任何数量的变量:
x = [4, 5, 10, 4, 3, 11, 14 , 8, 10, 12] y = [21, 19, 24, 17, 16, 25, 24, 22, 21, 21] classes = [0, 0, 1, 0, 0, 1, 1, 0, 1, 1]
将输入特征转换为一系列点:
data = list(zip(x, y)) print(data)
结果:
[(4, 21), (5, 19), (10, 24), (4, 17), (3, 16), (11, 25), (14, 24), (8, 22), (10, 21), (12, 21)]
使用输入特征和目标类别,我们在模型上拟合一个使用 1 个最近邻居的 KNN 模型:
knn = KNeighborsClassifier(n_neighbors=1) knn.fit(data, classes)
然后,我们可以使用相同的 KNN 对象来预测新的、不可预见的数据点的类别。首先,我们创建新的 x 和 y 特征,然后对新的数据点调用 knn.predict() 以获得类别 0 或 1:
new_x = 8 new_y = 21 new_point = [(new_x, new_y)] prediction = knn.predict(new_point) print(prediction)
结果:
[0]
当我们绘制所有数据以及新点和类别时,我们可以看到它被标记为蓝色,类别为 1。文本注释只是为了突出新点的位置:
plt.scatter(x + [new_x], y + [new_y], c=classes + [prediction[0]]) plt.text(x=new_x-1.7, y=new_y-0.7, s=f"new point, class: {prediction[0]}") plt.show()
结果:

但是,当我们将邻居数量更改为 5 时,用于分类新点的点数就会改变。因此,新点的分类也会改变:
knn = KNeighborsClassifier(n_neighbors=5) knn.fit(data, classes) prediction = knn.predict(new_point) print(prediction)
结果:
[1]
当我们绘制新点的类别以及旧点时,我们注意到颜色已根据关联的类别标签更改:
plt.scatter(x + [new_x], y + [new_y], c=classes + [prediction[0]]) plt.text(x=new_x-1.7, y=new_y-0.7, s=f"new point, class: {prediction[0]}") plt.show()
结果:
