授课语音

K近邻算法(KNN)

K近邻算法(K-Nearest Neighbors,简称KNN)是一种基本的分类和回归算法,在机器学习中广泛应用。其基本思想是通过计算样本之间的距离,选择距离待分类样本最近的K个邻居,根据邻居的类别(分类问题)或均值(回归问题)来决定目标样本的类别或数值。


1. K近邻算法的工作原理

K近邻算法基于一个简单的假设:相似的样本具有相似的标签。在进行预测时,KNN算法会选择离待预测样本最近的K个训练样本,并根据这些邻居的信息进行预测。

1.1 分类问题中的KNN

在分类任务中,KNN算法通过以下步骤进行预测:

  1. 计算距离:对待预测的样本,计算其与训练集中所有样本的距离。常见的距离度量方法包括欧氏距离、曼哈顿距离等。
  2. 选择K个最近邻居:选取距离待预测样本最近的K个训练样本。
  3. 投票机制:根据这K个邻居的类别标签进行投票,选择出现次数最多的类别作为预测结果。

1.2 回归问题中的KNN

在回归任务中,KNN算法的工作原理与分类相似,但预测过程不同:

  1. 计算距离:计算待预测样本与训练集中所有样本的距离。
  2. 选择K个最近邻居:选取K个最近的邻居。
  3. 均值计算:根据K个邻居的数值标签计算均值,作为最终的预测值。

1.3 KNN的距离计算

KNN的核心操作之一是计算样本之间的距离,常用的距离度量方法包括:

  • 欧氏距离:适用于数值型数据。 d(x, y) = √(Σ(x_i - y_i)²)

  • 曼哈顿距离:适用于某些特定场景,特别是在网格状的空间中。 d(x, y) = Σ|x_i - y_i|

  • 余弦相似度:用于文本分类等领域,通过计算样本之间的角度差异来衡量相似度。


2. K近邻算法的优缺点

2.1 优点

  • 简单易懂:KNN算法非常直观,易于理解和实现。
  • 无模型假设:KNN是基于实例的学习方法,它不做任何假设,适用于各种数据分布情况。
  • 灵活性高:KNN既可以用于分类任务,也可以用于回归任务,具有较高的灵活性。
  • 训练时间短:由于KNN没有显式的训练过程,它的训练时间非常短。

2.2 缺点

  • 计算开销大:KNN算法需要计算每个测试样本与训练集中所有样本的距离,随着训练集的增大,计算复杂度急剧上升。
  • 对异常值敏感:KNN算法容易受噪声和异常值的影响,因为它仅依赖于邻居的标签来进行预测。
  • 维度灾难:在高维空间中,距离度量变得不再有效,KNN的性能会显著下降。这是因为高维空间中样本之间的距离趋于均匀,难以区分。
  • 存储需求大:KNN需要存储所有的训练数据,内存开销较大。

3. KNN算法的代码实现

以下是使用Python中的scikit-learn库实现K近邻算法(分类问题)的示例。

3.1 KNN分类的代码实现

# 导入必要的库
from sklearn.datasets import load_iris  # 加载鸢尾花数据集
from sklearn.model_selection import train_test_split  # 数据集划分
from sklearn.neighbors import KNeighborsClassifier  # K近邻分类器
from sklearn.metrics import accuracy_score  # 准确度评估

# 加载数据集
data = load_iris()
X = data.data  # 特征数据
y = data.target  # 标签数据

# 划分数据集(80%训练,20%测试)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建KNN分类器,选择K=3
knn = KNeighborsClassifier(n_neighbors=3)

# 训练模型
knn.fit(X_train, y_train)

# 预测测试集
y_pred = knn.predict(X_test)

# 输出准确度
accuracy = accuracy_score(y_test, y_pred)
print(f"KNN分类模型的准确度:{accuracy * 100:.2f}%")

代码说明:

  • load_iris():加载鸢尾花数据集,它是一个经典的多类分类数据集。
  • train_test_split():将数据集随机划分为训练集和测试集。
  • KNeighborsClassifier(n_neighbors=3):创建K近邻分类器,n_neighbors=3表示选择3个最近邻进行投票。
  • fit():训练KNN模型。
  • predict():对测试集进行预测。
  • accuracy_score():计算预测结果的准确率。

3.2 KNN回归的代码实现

# 导入必要的库
from sklearn.datasets import load_boston  # 加载波士顿房价数据集
from sklearn.model_selection import train_test_split  # 数据集划分
from sklearn.neighbors import KNeighborsRegressor  # K近邻回归器
from sklearn.metrics import mean_squared_error  # 均方误差评估

# 加载数据集
data = load_boston()
X = data.data  # 特征数据
y = data.target  # 标签数据

# 划分数据集(80%训练,20%测试)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建KNN回归器,选择K=5
knn_regressor = KNeighborsRegressor(n_neighbors=5)

# 训练模型
knn_regressor.fit(X_train, y_train)

# 预测测试集
y_pred = knn_regressor.predict(X_test)

# 输出均方误差
mse = mean_squared_error(y_test, y_pred)
print(f"KNN回归模型的均方误差:{mse:.2f}")

代码说明:

  • load_boston():加载波士顿房价数据集,适用于回归任务。
  • KNeighborsRegressor(n_neighbors=5):创建K近邻回归器,n_neighbors=5表示选择5个最近邻来进行预测。
  • mean_squared_error():计算均方误差(MSE),作为回归模型的评估指标。

4. 选择K值的技巧

选择合适的K值是KNN算法中一个关键的超参数。如果K值太小,模型可能会对噪声过于敏感,导致过拟合;如果K值太大,模型可能会过于简单,导致欠拟合。因此,一般使用交叉验证的方法来选择最佳的K值。

from sklearn.model_selection import cross_val_score

# 使用交叉验证选择K值
k_range = range(1, 21)
k_scores = []

for k in k_range:
    knn = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(knn, X, y, cv=5, scoring='accuracy')
    k_scores.append(scores.mean())

# 输出最佳K值
best_k = k_range[k_scores.index(max(k_scores))]
print(f"最佳K值:{best_k}")

代码说明:

  • cross_val_score():进行交叉验证,评估不同K值下模型的准确度。
  • cv=5:设置交叉验证折数为5。

5. 总结

  • K近邻算法(KNN)是一种基于实例的学习算法,简单且易于理解,适用于分类和回归任务。
  • 在分类任务中,KNN通过投票选出类别;在回归任务中,通过计算邻居的均值来预测数值。
  • KNN的优点包括简单易懂、无需假设数据分布,但也存在计算开销大、对异常值敏感、维度灾难等缺点。
  • 在使用KNN时,选择合适的K值至关重要,一般通过交叉验证来选择最佳K值。

KNN算法作为一个基础的机器学习方法,适合初学者入门,但在处理大规模数据或高维数据时,需要注意其计算效率和存储需求。

去1:1私密咨询

系列课程: