K最近邻算法详解

K最近邻算法(K-Nearest Neighbors,KNN)是一种直观且易于实现的机器学习算法。初学者即使在机器学习的早期阶段也能掌握这个算法。本文旨在帮助读者理解KNN算法的表示和预测方法,如何选择K值和距离度量,数据准备的必要性,以及KNN算法的优缺点。此外,还将提供伪代码和Python实现

KNN算法简介

K最近邻算法属于监督学习范畴,主要用于分类(最常见的)和回归。它是一种多用途算法,也用于填补缺失值和重采样数据集。正如其名(K最近邻)所暗示的,它考虑K个最近邻(数据点)来预测新数据点的类别或连续值。

该算法的学习特点包括:

  • 基于实例的学习:不从训练数据中学习权重来预测输出(如基于模型的算法),而是使用整个训练实例来预测未见数据的输出。
  • 懒惰学习:模型不是使用训练数据事先学习,而是将学习过程推迟到需要对新实例进行预测时。
  • 非参数:在KNN中,没有预定义的映射函数形式。

KNN工作原理

原则:考虑以下图形。假设已经在二维特征空间中绘制了来自训练集的数据点。如图所示,总共有6个数据点(3个红色和3个蓝色)。红色数据点属于‘类别1’,蓝色数据点属于‘类别2’。黄色数据点代表特征空间中的新点,需要预测其类别。显然,说它属于‘类别1’(红色点)。

为什么?因为它的最近邻属于那个类别!是的,这就是K最近邻背后的原则。在这里,最近邻是那些在特征空间中与新数据点距离最小的数据点。而K是在算法实现中考虑的这样的数据点的数量。因此,距离度量和K值是使用KNN算法时两个重要的考虑因素。欧几里得距离是最流行的距离度量。也可以根据需要使用汉明距离、曼哈顿距离、闵可夫斯基距离。对于预测新数据点的类别/连续值,它考虑了训练数据集中的所有数据点。找到新数据点的‘K’最近邻(数据点)及其类别标签或连续值。

然后:

  • 对于分类:从训练数据集中的K个最近邻中分配给大多数的类别标签被认为是新数据点的预测类别。
  • 对于回归:从训练数据集中的K个最近邻分配的连续值的平均值或中位数是新数据点的预测连续值。

模型表示

在这里,不学习权重并存储它们,而是将整个训练数据集存储在内存中。因此,KNN的模型表示是整个训练数据集。

如何选择K值

K是KNN算法中的关键参数。选择K值的一些建议包括:

  1. 使用误差曲线:下图显示了训练和测试数据的不同K值的误差曲线。
  2. 领域知识在选择K值时非常有用。
  3. 在考虑二元(两个类别)分类时,K值应该是奇数。

所需的数据准备

1. 数据缩放:为了在多维特征空间中定位数据点,如果所有特征都在同一尺度上,将会有所帮助。因此,数据的归一化或标准化将会有所帮助。

2. 降维:如果特征太多,KNN可能无法很好地工作。因此,可以实施特征选择、主成分分析等降维技术。

3. 缺失值处理:如果在训练集中某个示例的M个特征中有一个特征的数据缺失,那么无法定位或计算与该点的距离。因此,需要删除该行或进行插补。

使用Python的scikit-learn库实现K最近邻算法:

  1. 获取并准备数据
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)
  1. 找到K值
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()
  1. 预测
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
  1. 加载训练数据。
  2. 根据需要准备数据,包括缩放、处理缺失值和降维。
  3. 找到K的最优值:
  4. 预测新数据的类别值:
  5. 计算距离(X, Xi),其中i=1,2,3,…,n。
  6. X=新数据点,Xi=训练数据,距离根据所选的距离度量计算。
  7. 将这些距离按升序排序,并对应训练数据。
  8. 从这个排序的列表中,选择前‘K’行。
  9. 从这些选定的‘K’行中找到最频繁的类别。这将是预测类别。
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485