一、算法概述
KNN算法思想
- K-近邻算法(K Nearest Neighbor):根据"邻居"的类别推断样本类别
- 核心思想:如果一个样本在特征空间中的k个最相似样本中,大多数属于某一类别,则该样本也属于这个类别
- 相似性度量:样本距离越近则越相似
K值选择
- K值过小:容易受噪声影响,过拟合
- K值过大:距离较远的样本也会影响结果,欠拟合
- 经验选择:一般选择较小的K值,通过交叉验证确定最优K
二、距离度量方法
知道有这几种距离就行了,咋算的不用纠结
1. 欧氏距离(直线距离)
- 二维空间:d(P,Q)=(x1−x2)2+(y1−y2)2d(P, Q) = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}d(P,Q)=(x1−x2)2+(y1−y2)2
- N维空间:d(p,q)=∑i=1n(pi−qi)2d(\mathbf{p}, \mathbf{q}) = \sqrt{\sum_{i=1}^{n} (p_i - q_i)^2}d(p,q)=i=1∑n(pi−qi)2
2. 曼哈顿距离(网格路径)
- 二维空间:d1(P,Q)=∣x1−x2∣+∣y1−y2∣d_1(P, Q) = |x_1 - x_2| + |y_1 - y_2|d1(P,Q)=∣x1−x2∣+∣y1−y2∣
- n维空间:d1(p,q)=∑i=1n∣pi−qi∣d_1(\mathbf{p}, \mathbf{q}) = \sum_{i=1}^{n} |p_i - q_i|d1(p,q)=i=1∑n∣pi−qi∣
- 特点:横平竖直的路径距离
3. 切比雪夫距离(棋盘路径)
- 二维空间:d∞(P,Q)=max(∣x1−x2∣,∣y1−y2∣)d_\infty(P, Q) = \max(|x_1 - x_2|, |y_1 - y_2|)d∞(P,Q)=max(∣x1−x2∣,∣y1−y2∣)
- n维空间:d∞(p,q)=maxi=1,2,…,n∣pi−qi∣d_\infty(\mathbf{p}, \mathbf{q}) = \max_{i = 1, 2, \dots, n} |p_i - q_i|d∞(p,q)=i=1,2,…,nmax∣pi−qi∣
- 特点:可以走斜线,取坐标差的最大值
4. 闵可夫斯基距离(通用公式)
d(x,y)=∑i=1n∣Xi−Yi∣pp d(x,y) = \sqrt[p]{\sum_{i=1}^{n}\left |{X_i-Y_i}\right |^p } d(x,y)=pi=1∑n∣Xi−Yi∣p
- 特点:对欧氏距离(p=2)、曼哈顿距离(p=1)、切比雪夫距离(p=∞)的概括
三、特征预处理
为什么需要预处理?
- 特征单位或大小差异较大时,会影响模型结果
- 某些特征方差过大容易支配目标结果
归一化(Normalization)
- 公式:x′=(x−min)/(max−min)x' = (x - min)/(max - min)x′=(x−min)/(max−min)
- 范围:[0, 1]
- 适用场景:数据量较少,减少最大最小值差异
- 缺点:受异常值影响大,鲁棒性差
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0,1))
x_normalized = scaler.fit_transform(x)
标准化(Standardization)
- 公式:(x−mean)/std(x - mean) / std(x−mean)/std
- 特点:转换为均值为0,标准差为1的正态分布
- 适用场景:数据量较大
- 优点:对异常值不敏感
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x_standardized = scaler.fit_transform(x)
四、KNN算法应用
分类问题流程
- 计算未知样本到每个训练样本的距离
- 按距离升序排列训练样本
- 取距离最近的K个样本
- 进行多数表决,统计K个样本中最多的类别
- 将未知样本归为此类别
回归问题流程
- 计算未知样本到每个训练样本的距离
- 按距离升序排列训练样本
- 取距离最近的K个样本
- 计算K个样本目标值的平均值
- 作为未知样本的预测值
五、API使用
分类API
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier(n_neighbors=5)
model.fit(x_train, y_train)
predictions = model.predict(x_test)
回归API
from sklearn.neighbors import KNeighborsRegressor
model = KNeighborsRegressor(n_neighbors=5)
model.fit(x_train, y_train)
predictions = model.predict(x_test)
六、超参数优化
交叉验证(Cross Validation)
- 原理:将训练集划分为n份,轮流用其中1份作为验证集,其余n-1份作为训练集
- 优点:充分利用数据,减少过拟合
- 流程:多次训练评估,取平均值作为模型得分
网格搜索(Grid Search)
- 原理:遍历所有可能的参数组合,找到最优超参数
- 结合交叉验证:对每个参数组合进行交叉验证
from sklearn.model_selection import GridSearchCV
param_grid = {"n_neighbors": range(1, 10)}
estimator = KNeighborsClassifier()
grid_search = GridSearchCV(estimator, param_grid, cv=5)
grid_search.fit(x_train, y_train)
print("最优参数:", grid_search.best_params_)
print("最优得分:", grid_search.best_score_)
七、实战案例
鸢尾花分类
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
# 加载数据
iris = load_iris()
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2)
# 数据标准化
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)
# 模型训练预测
model = KNeighborsClassifier(n_neighbors=5)
model.fit(x_train, y_train)
accuracy = model.score(x_test, y_test)
手写数字识别
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import joblib
# 数据加载和预处理
data = pd.read_csv('手写数字识别.csv')
x = data.iloc[:, 1:] / 255 # 归一化
y = data.iloc[:, 0]
# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y)
# 模型训练
model = KNeighborsClassifier(n_neighbors=3)
model.fit(x_train, y_train)
# 模型保存
joblib.dump(model, 'knn_model.pth')
八、总结
KNN算法特点
- 优点:简单易懂,无需训练过程,对异常值不敏感
- 缺点:计算复杂度高,需要存储所有训练数据,对不平衡数据敏感
关键要点
- K值选择:通过交叉验证确定最优K值
- 距离度量:根据数据特点选择合适的距离公式
- 特征预处理:归一化或标准化消除量纲影响
- 参数优化:使用网格搜索结合交叉验证调优
应用场景
- 分类问题:文本分类、图像识别
- 回归问题:房价预测、销量预测
- 推荐系统:基于用户的协同过滤
555

被折叠的 条评论
为什么被折叠?



