K最近邻算法(K-Nearest Neighbors,KNN)是一种直观且易于实现的机器学习算法。初学者即使在机器学习的早期阶段也能掌握这个算法。本文旨在帮助读者理解KNN算法的表示和预测方法,如何选择K值和距离度量,数据准备的必要性,以及KNN算法的优缺点。此外,还将提供伪代码和Python实现。
K最近邻算法属于监督学习范畴,主要用于分类(最常见的)和回归。它是一种多用途算法,也用于填补缺失值和重采样数据集。正如其名(K最近邻)所暗示的,它考虑K个最近邻(数据点)来预测新数据点的类别或连续值。
该算法的学习特点包括:
原则:考虑以下图形。假设已经在二维特征空间中绘制了来自训练集的数据点。如图所示,总共有6个数据点(3个红色和3个蓝色)。红色数据点属于‘类别1’,蓝色数据点属于‘类别2’。黄色数据点代表特征空间中的新点,需要预测其类别。显然,说它属于‘类别1’(红色点)。
为什么?因为它的最近邻属于那个类别!是的,这就是K最近邻背后的原则。在这里,最近邻是那些在特征空间中与新数据点距离最小的数据点。而K是在算法实现中考虑的这样的数据点的数量。因此,距离度量和K值是使用KNN算法时两个重要的考虑因素。欧几里得距离是最流行的距离度量。也可以根据需要使用汉明距离、曼哈顿距离、闵可夫斯基距离。对于预测新数据点的类别/连续值,它考虑了训练数据集中的所有数据点。找到新数据点的‘K’最近邻(数据点)及其类别标签或连续值。
然后:
在这里,不学习权重并存储它们,而是将整个训练数据集存储在内存中。因此,KNN的模型表示是整个训练数据集。
K是KNN算法中的关键参数。选择K值的一些建议包括:
1. 数据缩放:为了在多维特征空间中定位数据点,如果所有特征都在同一尺度上,将会有所帮助。因此,数据的归一化或标准化将会有所帮助。
2. 降维:如果特征太多,KNN可能无法很好地工作。因此,可以实施特征选择、主成分分析等降维技术。
3. 缺失值处理:如果在训练集中某个示例的M个特征中有一个特征的数据缺失,那么无法定位或计算与该点的距离。因此,需要删除该行或进行插补。
使用Python的scikit-learn库实现K最近邻算法:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics
# 创建数据
X,Y=make_classification(n_samples= 200,n_features=8,n_informative=8,n_redundant=0,n_repeated=0,n_classes=2,random_state=14)
# 数据分割
X_train, X_test, y_train, y_test= train_test_split(X, Y, test_size= 0.2,random_state=32)
# 数据标准化
sc= StandardScaler()
sc.fit(X_train)
X_train= sc.transform(X_train)
sc.fit(X_test)
X_test= sc.transform(X_test)
print(X.shape)
(200, 8)
error1= []
error2= []
for k in range(1,15):
knn= KNeighborsClassifier(n_neighbors=k)
knn.fit(X_train,y_train)
y_pred1= knn.predict(X_train)
error1.append(np.mean(y_train!= y_pred1))
y_pred2= knn.predict(X_test)
error2.append(np.mean(y_test!= y_pred2))
# 绘制误差曲线
plt.plot(range(1,15),error1,label="train")
plt.plot(range(1,15),error2,label="test")
plt.xlabel('k Value')
plt.ylabel('Error')
plt.legend()
knn= KNeighborsClassifier(n_neighbors=7)
knn.fit(X_train,y_train)
y_pred= knn.predict(X_test)
metrics.accuracy_score(y_test,y_pred)
0.9