一、KNN算法简介

K-最近邻算法(K-Nearest Neighbors,简称KNN)是一种简单而有效的监督学习算法,主要用于分类和回归问题。在分类问题中,KNN算法通过计算测试样本与训练样本之间的距离,找到距离测试样本最近的 k 个训练样本,然后通过这 k 个样本的类别进行投票决定测试样本的类别。在回归问题中,KNN则是通过这些最近邻的平均值来预测输出。

KNN是一种基于实例的学习算法,它没有显式的模型训练过程,而是直接利用所有训练数据进行预测。正因为其简单和直观的特点,KNN广泛用于各种应用中,包括图像分类、文本分类和推荐系统等。

二、KNN算法的工作原理

KNN的工作原理主要包含以下几个步骤:

  1. 计算距离:计算测试样本与训练样本之间的距离,通常使用欧氏距离(Euclidean Distance),也可以使用曼哈顿距离(Manhattan Distance)或余弦相似度(Cosine Similarity)等。

  2. 选择最近的K个邻居:根据距离大小,选择与测试样本距离最近的 k 个训练样本。

  3. 投票决定类别:对于分类问题,KNN通过这 k 个邻居的类别进行投票,将类别最多的作为预测结果。对于回归问题,则通过最近 k 个点的平均值来得到预测值。

2.1 欧氏距离

欧氏距离是最常用的距离度量方法之一,用于度量两个样本点之间的直线距离。对于两个点 AB,其坐标分别为 (x1, y1)(x2, y2),欧氏距离的计算公式为:

d ( A , B ) = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 d(A, B) = \sqrt{(x2 - x1)^2 + (y2 - y1)^2} d(A,B)=(x2x1)2+(y2y1)2

在多维空间中,同样可以使用欧氏距离,公式如下:

d ( A , B ) = ∑ i = 1 n ( x i A − x i B ) 2 d(A, B) = \sqrt{\sum_{i=1}^n (x_{i}^{A} - x_{i}^{B})^2} d(A,B)=i=1n(xiAxiB)2

其中,n 是样本特征的维数。

三、K值的选择

K值的选择对于KNN算法的效果非常重要。如果 K 值太小,模型容易受到噪声数据的影响,导致过拟合(overfitting);如果 K 值太大,模型则会变得过于平滑,导致欠拟合(underfitting)。因此,我们需要通过交叉验证等方法来选择最合适的 K 值。

通常,K值取奇数,特别是在二分类问题中,以避免投票结果出现平局的情况。

四、KNN算法的优缺点

4.1 优点

  1. 简单易懂:KNN算法的原理非常简单,容易理解和实现。
  2. 无训练过程:KNN不需要显式的模型训练,可以直接用于预测,适用于小规模数据集。
  3. 适用性广:KNN可以处理多分类问题和回归问题,并且适用于多种距离度量方法。

4.2 缺点

  1. 计算复杂度高:对于每一个测试样本,KNN都需要计算与所有训练样本的距离,当数据集很大时,计算开销非常大。
  2. 内存消耗大:KNN需要存储所有的训练数据,因此对内存的要求较高。
  3. 对特征尺度敏感:KNN对特征的尺度比较敏感,如果特征之间的尺度相差较大,可能会导致距离度量不准确,因此在使用KNN之前通常需要对数据进行归一化处理。

五、Python实现KNN分类

下面我们将通过Python实现一个简单的KNN分类模型,使用 scikit-learn 库来帮助我们完成这一任务。

5.1 导入必要的库

首先,我们需要导入一些必要的库:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, confusion_matrix
  • numpy:用于数值计算。
  • matplotlib:用于数据可视化。
  • sklearn.datasets:用于加载 Iris 数据集,这是一个经典的多分类数据集。
  • train_test_split:用于将数据集拆分为训练集和测试集。
  • StandardScaler:用于数据标准化。
  • KNeighborsClassifier:KNN分类器。
  • accuracy_score, confusion_matrix:用于评估模型的准确率和混淆矩阵。

5.2 加载数据集并进行预处理

我们使用 Iris 数据集,这是一个常用的多分类数据集,包含三类花(山鸢尾、变色鸢尾、维吉尼亚鸢尾),每类有50个样本。

# 加载Iris数据集
data = load_iris()
X = data.data
y = data.target

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 对特征进行标准化处理
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
  • load_iris():加载Iris数据集,X 是特征矩阵,y 是标签。
  • train_test_split:将数据集拆分为训练集和测试集,20%的数据用于测试。
  • StandardScaler:对数据进行标准化,使每个特征具有零均值和单位方差,减少特征间的尺度差异。

5.3 创建KNN分类器并进行训练

我们创建一个KNN分类器,设定 k=3,并用训练集进行模型训练。

# 创建KNN分类器
knn = KNeighborsClassifier(n_neighbors=3)

# 训练模型
knn.fit(X_train, y_train)
  • KNeighborsClassifier(n_neighbors=3):创建KNN分类器,并设置邻居数为3。
  • knn.fit(X_train, y_train):用训练数据拟合KNN模型。

5.4 模型预测与评估

使用测试集进行预测,并评估模型的性能。

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

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型的准确率: {accuracy * 100:.2f}%")

# 混淆矩阵
conf_matrix = confusion_matrix(y_test, y_pred)
print("混淆矩阵:\n", conf_matrix)
  • knn.predict(X_test):对测试集进行预测。
  • accuracy_score:计算预测的准确率。
  • confusion_matrix:计算混淆矩阵,用于评估分类器在每个类别上的表现。

5.5 可视化K值对模型性能的影响

为了选择合适的K值,我们可以绘制不同K值下模型准确率的变化图。

# 尝试不同的K值,计算模型的准确率
k_values = range(1, 26)
accuracies = []

for k in k_values:
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X_train, y_train)
    y_pred = knn.predict(X_test)
    accuracies.append(accuracy_score(y_test, y_pred))

# 绘制准确率变化图
plt.plot(k_values, accuracies, marker='o')
plt.xlabel('K值')
plt.ylabel('准确率')
plt.title('不同K值下的模型准确率')
plt.grid(True)
plt.show()

通过运行上述代码,我们可以看到不同 K 值对模型准确率的影响,从而选择最优的 K 值。

六、总结

KNN是一种简单直观的监督学习算法,适用于分类和回归问题。它通过计算测试样本与训练样本之间的距离,找到最近的K个邻居进行投票决定类别。在实现KNN时,我们需要注意特征的尺度和K值的选择。KNN的优点是简单、易于理解,但其计算复杂度较高,尤其在大规模数据集上。因此,KNN更适用于小规模数据集。

6.1 学习要点

  1. KNN原理:通过距离度量,找到测试样本的最近邻并投票决定其类别。
  2. 距离度量方法:欧氏距离是最常用的距离度量方法。
  3. K值选择:K值太小容易过拟合,K值太大容易欠拟合,可以通过交叉验证选出最优的K值。
  4. Python实现:可以使用 scikit-learn 库中的 KNeighborsClassifier 轻松实现KNN分类。

6.2 练习题

  1. 使用KNN算法对 Iris 数据集进行回归,尝试使用不同的K值,观察模型表现的变化。
  2. 尝试使用曼哈顿距离或余弦相似度作为KNN中的距离度量方法,比较其与欧氏距离的性能差异。
  3. 使用 sklearn.datasets 模块中的 load_wine 数据集,构建一个KNN分类模型,预测葡萄酒的类别。

如果您觉得本文有帮助,欢迎继续学习本专栏的其他内容,下一篇文章将为您介绍逻辑回归及其Python实现。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部