文章目录
一、KNN算法简介
K-最近邻算法(K-Nearest Neighbors,简称KNN)是一种简单而有效的监督学习算法,主要用于分类和回归问题。在分类问题中,KNN算法通过计算测试样本与训练样本之间的距离,找到距离测试样本最近的 k 个训练样本,然后通过这 k 个样本的类别进行投票决定测试样本的类别。在回归问题中,KNN则是通过这些最近邻的平均值来预测输出。
KNN是一种基于实例的学习算法,它没有显式的模型训练过程,而是直接利用所有训练数据进行预测。正因为其简单和直观的特点,KNN广泛用于各种应用中,包括图像分类、文本分类和推荐系统等。
二、KNN算法的工作原理
KNN的工作原理主要包含以下几个步骤:
计算距离:计算测试样本与训练样本之间的距离,通常使用欧氏距离(Euclidean Distance),也可以使用曼哈顿距离(Manhattan Distance)或余弦相似度(Cosine Similarity)等。
选择最近的K个邻居:根据距离大小,选择与测试样本距离最近的 k 个训练样本。
投票决定类别:对于分类问题,KNN通过这 k 个邻居的类别进行投票,将类别最多的作为预测结果。对于回归问题,则通过最近 k 个点的平均值来得到预测值。
2.1 欧氏距离
欧氏距离是最常用的距离度量方法之一,用于度量两个样本点之间的直线距离。对于两个点 A 和 B,其坐标分别为 (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)=(x2−x1)2+(y2−y1)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=1∑n(xiA−xiB)2
其中,n 是样本特征的维数。
三、K值的选择
K值的选择对于KNN算法的效果非常重要。如果 K 值太小,模型容易受到噪声数据的影响,导致过拟合(overfitting);如果 K 值太大,模型则会变得过于平滑,导致欠拟合(underfitting)。因此,我们需要通过交叉验证等方法来选择最合适的 K 值。
通常,K值取奇数,特别是在二分类问题中,以避免投票结果出现平局的情况。
四、KNN算法的优缺点
4.1 优点
- 简单易懂:KNN算法的原理非常简单,容易理解和实现。
- 无训练过程:KNN不需要显式的模型训练,可以直接用于预测,适用于小规模数据集。
- 适用性广:KNN可以处理多分类问题和回归问题,并且适用于多种距离度量方法。
4.2 缺点
- 计算复杂度高:对于每一个测试样本,KNN都需要计算与所有训练样本的距离,当数据集很大时,计算开销非常大。
- 内存消耗大:KNN需要存储所有的训练数据,因此对内存的要求较高。
- 对特征尺度敏感: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 学习要点
- KNN原理:通过距离度量,找到测试样本的最近邻并投票决定其类别。
- 距离度量方法:欧氏距离是最常用的距离度量方法。
- K值选择:K值太小容易过拟合,K值太大容易欠拟合,可以通过交叉验证选出最优的K值。
- Python实现:可以使用 scikit-learn 库中的 KNeighborsClassifier 轻松实现KNN分类。
6.2 练习题
- 使用KNN算法对 Iris 数据集进行回归,尝试使用不同的K值,观察模型表现的变化。
- 尝试使用曼哈顿距离或余弦相似度作为KNN中的距离度量方法,比较其与欧氏距离的性能差异。
- 使用 sklearn.datasets 模块中的 load_wine 数据集,构建一个KNN分类模型,预测葡萄酒的类别。
如果您觉得本文有帮助,欢迎继续学习本专栏的其他内容,下一篇文章将为您介绍逻辑回归及其Python实现。