【机器学习】KNN算法(K-近邻算法)
day01 KNN算法(K-近邻算法)
文章目录
前言
K-近邻算法(K-Nearest Neighbors, KNN)是机器学习入门最经典的算法之一。
本文从零开始,系统性地介绍KNN算法的核心原理、关键参数(K值)的选择策略、两种核心距离度量公式(欧式距离与曼哈顿距离),并使用Python的Scikit-Learn库完成两个完整的实战项目:AI智能寝室分配系统与鸢尾花分类。
通过本文,你将不仅理解KNN的理论基础,更能掌握其在实际数据科学项目中的应用流程,为后续学习更复杂的机器学习模型打下坚实基础。
一、什么是KNN算法?
1.定义
全称是K-Nearest neighbors ,通过寻找k个距离最近的数据,来确定当前数据值的大小或者类别。是机器学习中最为简单和经典的一个算法。
目标检测:回归+分类
2. KNN算法的使用步骤
结合文章中的实战代码,KNN算法的完整使用流程可以分为以下5个步骤:
步骤1:导入所需库
首先需要导入KNN分类器以及数据处理相关的库:
import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
步骤2:加载并准备数据
将数据分为**特征变量(X)和标签(y)**两部分。特征变量是用于判断的依据,标签是已知的分类结果:
# 以AI智能寝室分配系统为例
data = np.loadtxt('datingTestSet2.txt')
X = data[:, :-1] # 特征:学生的各项性格指标
y = data[:, -1] # 标签:学生的性格类别(1/2/3)
步骤3:创建KNN模型并训练
创建KNN分类器对象,设置邻居数量K值,然后使用 fit() 方法进行训练:
knn = KNeighborsClassifier(n_neighbors=3) # 设置K=3
knn.fit(X, y) # 模型学习特征与标签之间的对应关系
步骤4:使用模型进行预测
训练完成后,使用 predict() 方法对新样本进行分类预测:
# 单次预测
print(knn.predict([[42666, 13.276368, 0.543880]]))
# 批量预测
predict_data = [[5569, 4.875435, 0.728658], [65230, 9.972470, 0.881877]]
print(knn.predict(predict_data))
步骤5:评估模型性能
使用 score() 方法计算模型在测试集上的准确率,评估模型的泛化能力:
score = knn.score(data_test, test_y) # 计算准确率
print(score)
以上5个步骤是KNN算法在sklearn中的标准使用流程,后面的「实战案例」部分将基于此流程展开两个完整的项目实践。
3. 如何选择K值?
K值的选择是KNN算法中最重要的参数调优环节,它直接影响模型的预测性能。
K值对模型的影响
- K值过小(如K=1):模型只参考最近的一个邻居,容易受到噪声和异常值的干扰,导致过拟合——训练集上表现很好,但测试集上泛化能力差。
- K值过大(如K=50):模型会参考大量远距离的样本,导致决策边界过于平滑,可能忽略数据的局部模式,造成欠拟合——模型过于简单,无法捕捉数据的真实分布。
- K值适中:模型在偏差和方差之间取得平衡,既能利用局部信息,又对噪声有一定容忍度。
经验法则:通常K取训练样本数的平方根附近的值,且一般选择奇数(避免二分类时出现平票情况)。
二、KNN算法—距离公式
1.欧式距离(Euclidean Distance)
欧式距离是最常用的距离度量方法,用于计算多维空间中两点之间的直线距离。
对于 n 维空间中的两个点 P 和 Q,其坐标分别为:
- P = (p₁, p₂, …, pₙ)
- Q = (q₁, q₂, …, qₙ)
它们之间的欧式距离公式为:
d ( P , Q ) = ∑ i = 1 n ( p i − q i ) 2 d(P, Q) = \sqrt{\sum_{i=1}^{n} (p_i - q_i)^2} d(P,Q)=i=1∑n(pi−qi)2
在二维空间中(即平面直角坐标系),公式简化为:
d = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} d=(x2−x1)2+(y2−y1)2
在三维空间中,公式为:
d = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 + ( z 2 − z 1 ) 2 d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2 + (z_2 - z_1)^2} d=(x2−x1)2+(y2−y1)2+(z2−z1)2
在 KNN 算法中,通常使用欧式距离来计算样本点之间的距离,以找出最近的 K 个邻居。
2.曼哈顿距离(Manhattan Distance)
曼哈顿距离(Manhattan Distance)又称城市街区距离(City Block Distance),用于计算多维空间中两点在各坐标轴上的绝对轴距之和。
对于 n 维空间中的两个点 P 和 Q,其坐标分别为:
- P = (p₁, p₂, …, pₙ)
- Q = (q₁, q₂, …, qₙ)
它们之间的曼哈顿距离公式为:
d ( P , Q ) = ∑ i = 1 n ∣ p i − q i ∣ d(P, Q) = \sum_{i=1}^{n} |p_i - q_i| d(P,Q)=i=1∑n∣pi−qi∣
在二维空间中(即平面直角坐标系),公式简化为:
d = ∣ x 2 − x 1 ∣ + ∣ y 2 − y 1 ∣ d = |x_2 - x_1| + |y_2 - y_1| d=∣x2−x1∣+∣y2−y1∣
在三维空间中,公式为:
d = ∣ x 2 − x 1 ∣ + ∣ y 2 − y 1 ∣ + ∣ z 2 − z 1 ∣ d = |x_2 - x_1| + |y_2 - y_1| + |z_2 - z_1| d=∣x2−x1∣+∣y2−y1∣+∣z2−z1∣
在 KNN 算法中,曼哈顿距离常用于高维稀疏数据或特征尺度差异较大的场景,相比欧式距离对异常值更鲁棒。
💡 什么是「鲁棒」?
「鲁棒」是英文 Robust 的音译,意为稳健的、健壮的。在机器学习中,说一个算法「更鲁棒」,指它对异常值、噪声或数据波动不敏感,即使输入数据存在偏差或离群点,算法的表现依然稳定可靠。例如曼哈顿距离使用绝对值求和,相比欧式距离的平方求和,受单个异常值的影响更小,因此对异常值更鲁棒。
三、KNN算法–sklearn
1.Sklearn是什么?
Sklearn(Scikit-Learn)是基于Python语言的第三方机器学习库。它建立在Numpy,Scipy,Pandas和Matplotlib库之上,里面的API的设计非常好,所有对象的接口简单,适合新手。
2.Sklearn安装
在命令提示符中输入:
pip install scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple
3.Sklearn的使用
使用sklearn官网API:https://scikit-learn.org/
knn算法的介绍 搜索k-nearest neighbors
四、实战案例
1. AI智能寝室分配系统
任务目标:将性格相似的学生分配在同一个寝室
1. 导入所需库
import numpy as np # numpy是专门用于处理矩阵数据的库
from sklearn.neighbors import KNeighborsClassifier # 从sklearn中导入KNN分类器
2. 加载并准备数据
# 使用numpy读取datingTestSet2.txt文件中的数据
# 该文件包含学生特征数据,最后一列为性格类别标签(1/2/3)
data = np.loadtxt('datingTestSet2.txt')
# 提取特征数据:取所有行的所有列,但不包含最后一列
# X 是特征矩阵,包含每个学生的各项性格指标
X = data[:, :-1]
# 提取标签数据:取所有行的最后一列
# y 是标签向量,表示每个学生的性格类别(1、2、3)
y = data[:, -1]
3. 创建并训练KNN模型
# 创建KNN分类器对象,设置邻居数量k=3
# n_neighbors=3 表示取距离最近的3个邻居,根据它们的类别进行投票(多数表决)
neight = KNeighborsClassifier(n_neighbors=3)
# 使用特征数据X和标签y对模型进行训练
# fit()方法会计算并存储所有训练样本的特征和标签
neight.fit(X, y)
4. 单次预测——测试模型效果
# predict()方法用于预测新样本的类别
# 传入的参数是一个二维数组,每个子数组代表一个新学生的特征数据
print(neight.predict([[42666, 13.276368, 0.543880]])) # 预测结果:3
print(neight.predict([[44372, 4.391522, 0.807100]])) # 预测结果:1
print(neight.predict([[14673, 0.460768, 0.689586]])) # 预测结果:2
5. 批量预测——同时预测多个学生
# 准备一组待预测的学生数据,每个子列表包含3个特征值
predict_data = [
[5569, 4.875435, 0.728658], # 预期类别:2
[65230, 9.972470, 0.881877], # 预期类别:1
[36788, 12.458258, 0.649517], # 预期类别:3
[7917, 3.007578, 0.297302], # 预期类别:2
[22329, 2.262014, 1.022169], # 预期类别:1
[38768, 5.308408, 0.030683], # 预期类别:3
[10933, 0.000000, 0.107476] # 预期类别:2
]
print("再次多人同时预测")
print(neight.predict(predict_data))
2. 鸢尾花分类
1. 导入所需库并读取数据
import pandas as pd # numpy可以读二维数据,pandas可以处理表格类型的数据
# 读取数据
# train_data:训练集
# test_data:测试集
# numpy:数组形式读取数据;pandas:以表格形式读取数据
train_data = pd.read_excel("鸢尾花训练数据.xlsx")
test_data = pd.read_excel("鸢尾花测试数据.xlsx")
2. 处理训练集数据——变量与标签分离
# 将特征变量与标签分离
train_X = train_data[['萼片长(cm)', '萼片宽(cm)', '花瓣长(cm)', '花瓣宽(cm)']]
train_y = train_data[['类型_num']]
3. 对训练数据进行标准化处理
"""
标准化方法说明:
1. 归一化:将数据缩放到 0~1 范围,对每个列(特征)分别进行
2. Z-Score标准化:将数据减去均值并除以标准差,结果通常在 -5~5 范围
"""
from sklearn.preprocessing import scale # 对输入数据进行去均值并除以标准差的操作
data = pd.DataFrame()
data['萼片长标准化'] = scale(train_X['萼片长(cm)'])
data['萼片宽标准化'] = scale(train_X['萼片宽(cm)'])
data['花瓣长标准化'] = scale(train_X['花瓣长(cm)'])
data['花瓣宽标准化'] = scale(train_X['花瓣宽(cm)'])
# 数据预处理的目标是让每个特征的数据都在差不多大小的范围内
4. 创建并训练KNN模型
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=2) # 设置邻居数量k=2
knn.fit(data, train_y) # 使用标准化后的训练数据训练模型
5. 使用训练数据进行自测评估
train_predicted = knn.predict(data) # 用训练数据自测预测
score = knn.score(data, train_y) # 计算模型得分:将data传入模型预测,将预测结果与train_y比较
print(score)
6. 准备测试集数据并标准化
# 提取测试集的特征和标签
test_X = test_data[['萼片长(cm)', '萼片宽(cm)', '花瓣长(cm)', '花瓣宽(cm)']]
test_y = test_data[['类型_num']]
# 对测试集进行Z-Score标准化
from sklearn.preprocessing import scale
data_test = pd.DataFrame() # 传入全新的测试数据,从未传入过模型
data_test['萼片长标准化'] = scale(test_X['萼片长(cm)'])
data_test['萼片宽标准化'] = scale(test_X['萼片宽(cm)'])
data_test['花瓣长标准化'] = scale(test_X['花瓣长(cm)'])
data_test['花瓣宽标准化'] = scale(test_X['花瓣宽(cm)'])
7. 使用测试集进行预测并评估
# 预测测试集结果
test_predicted = knn.predict(data_test)
score = knn.score(data_test, test_y) # 计算模型在测试集上的得分
print(score)
# # 预测概率(可选)
# test_predicted_pr = knn.predict_proba(data_test)
# print(test_predicted_pr)
总结
本文系统学习了KNN算法的三大核心板块:
- 算法原理:KNN通过寻找K个最近邻居进行投票分类,K值的选择直接影响模型性能——K过小易过拟合,K过大易欠拟合。
- 距离度量:欧式距离(直线距离)和曼哈顿距离(轴距之和)是KNN最常用的两种距离计算方式,后者对异常值更鲁棒。
- sklearn实战:完成了智能寝室分配和鸢尾花分类两个项目,掌握了从数据准备、模型训练到预测评估的完整流程。
更多推荐
所有评论(0)