机器学习KNN算法
一、KNN 是什么?—— 机器学习里的 “少数服从多数”
KNN(K-Nearest Neighbors,K 近邻算法)是机器学习中最经典的监督学习算法之一,核心逻辑堪称 “朴素又直白”:
“要判断一个样本属于什么类别,就看看它周围最近的 K 个样本里,哪种类别占多数。”
打个生活比方:如果你新搬到一个小区,想知道邻居们喜欢吃甜口还是咸口,不用挨个调研 —— 只要问最近的 3 户(K=3)邻居,若 2 户爱吃甜口,就可以推测这个区域更偏爱甜口。KNN 的 “判断逻辑” 和这完全一致,只不过把 “距离” 换成了数据维度的计算,把 “口味偏好” 换成了数据标签。
二、KNN 的核心原理:3 个关键问题
1. 如何衡量 “距离”?
KNN 靠 “距离” 判断样本相似度,常用 3 种距离公式:
- 欧氏距离(最常用):适用于连续型特征,类似平面上两点间的直线距离,公式为:
\(d(x,y) = \sqrt{\sum_{i=1}^{n}(x_i - y_i)^2}\)
例:用 “年龄(25 vs 30)”“收入(8k vs 10k)” 判断用户相似度,直接算两点间距离。
- 曼哈顿距离:适用于高维稀疏数据(如文本特征),公式为:
\(d(x,y) = \sum_{i=1}^{n}|x_i - y_i|\)
- 余弦相似度:衡量向量方向的相似度,适用于文本、图像等特征向量(值越大越相似)。
2. K 值怎么选?—— 决定算法效果的关键
K 值是 KNN 的 “灵魂参数”,选大或选小都会出问题:
- K 值太小(如 K=1):容易受 “异常值” 影响。比如判断一个用户是否流失时,恰好最近的 1 个样本是异常离网用户,就会误判。
- K 值太大(如 K=100):会忽略局部特征,被 “多数类” 带偏。比如样本中 90% 是 “未流失用户”,K=100 时几乎全判为未流失,漏掉真实离网用户。
实用技巧:K 值通常选奇数(避免平局),通过 “交叉验证” 筛选(比如从 3、5、7 中选效果最好的)。
3. 特征需要 “特殊对待” 吗?
必须!KNN 对特征尺度非常敏感:
比如用 “年龄(0-100)” 和 “收入(0-10000)” 做特征,收入的数值范围远大于年龄,计算距离时会被收入 “主导”,导致年龄特征失效。
解决方法:先做 “特征标准化”,把所有特征缩放到同一尺度:
- 标准化(Z-score):\(x' = \frac{x - \mu}{\sigma}\)(均值为 0,标准差为 1)
- 归一化(Min-Max):\(x' = \frac{x - min}{max - min}\)(缩到 0-1 区间)
三、实战:用 KNN 做 “客户离网预测”
以电信客户数据为例,用 KNN 判断用户是否会离网,代码简洁到新手也能看懂:
1. 准备工作(安装库)
pip install pandas scikit-learn
2. 核心代码
# 1. 加载数据(包含19个特征,标签为Churn?:0=未离网,1=离网)
import pandas as pd
data = pd.read_csv("telecom_churn.csv")
# 2. 提取特征和标签
X = data.iloc[:, 1:-1] # 前19列特征
y = data.iloc[:, -1] # 最后一列标签
# 3. 特征标准化(关键步骤!)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 4. 划分训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.3, random_state=0
)
# 5. 训练KNN模型(K=5)
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=5) # 设K=5
knn.fit(X_train, y_train)
# 6. 评估效果
from sklearn.metrics import classification_report
y_pred = knn.predict(X_test)
print(classification_report(y_test, y_pred, target_names=['未离网', '离网']))
3. 输出结果(示例)
precision recall f1-score support
未离网 0.93 0.95 0.94 862
离网 0.72 0.65 0.68 138
accuracy 0.91 1000
macro avg 0.82 0.80 0.81 1000
weighted avg 0.90 0.91 0.90 1000
可以看到,KNN 对 “未离网” 用户的识别精度(93%)较高,对 “离网” 这类少数类也有不错的召回率(65%)。
四、KNN 的 “生存法则”:适合与不适合的场景
✅ 适合用 KNN 的情况
- 小数据集:无需训练 “模型”,直接用原始数据判断,大数据会变慢;
- 可解释性要求高:能明确说出 “根据哪几个样本判断的”,比神经网络更透明;
- 特征维度不高:高维数据(如图片)计算距离耗时,且容易 “维度灾难”;
- 实时更新需求:新增样本直接加入数据集,不用重新训练模型(如实时推荐)。
❌ 不适合用 KNN 的情况
- 大数据集:每次预测都要计算与所有样本的距离,速度极慢;
- 高维数据:比如 1000 维的文本特征,距离计算会失效(“维度灾难”);
- 特征不均衡:比如 “收入” 占比远大于 “年龄”,不标准化就会出错;
- 实时性要求极高:比如自动驾驶的决策,KNN 的计算速度跟不上。
五、新手必懂:KNN 调优 3 个技巧
- 选对 K 值:用 “网格搜索” 找最优 K,比如GridSearchCV(knn, param_grid={'n_neighbors': [3,5,7]});
- 加权 KNN:让距离近的样本 “话语权更大”,设置weights='distance'(默认是uniform平等权重);
- 降维预处理:高维数据先做 PCA 降维,再用 KNN,既快又准。
六、总结:KNN 的 “朴素哲学”
KNN 没有复杂的数学推导,也不用迭代训练,却能解决很多实际问题 —— 它的核心是 “相信相似性”:相似的样本大概率属于同一类。
作为机器学习入门算法,KNN 能帮你快速理解 “特征、距离、标签” 的关系;而在实际工作中,它更适合做 “基线模型”—— 先用 KNN 跑出基础效果,再用随机森林、XGBoost 等算法优化,效率更高。
下次遇到 “分类” 问题,不妨先试试 KNN,说不定简单的方法就是最好的方法~
更多推荐


所有评论(0)