ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

KNN 算法入门指南:从近邻思想到模型调优与评估

KNN 算法入门指南:从近邻思想到模型调优与评估 在机器学习的算法家族中KNNK-Nearest NeighborsK近邻是最直觉、最容易理解的算法之一。它没有复杂的数学推导不需要训练过程核心思想用一句话就能说清看看你周围的人是谁你就是谁。但简单不等于简陋。KNN 涉及的距离度量、K值选择、特征预处理、交叉验证、混淆矩阵等概念都是机器学习中反复出现的通用知识。掌握 KNN不仅是学一个算法更是理解整个机器学习工作流的重要一步。今天这篇文章我们就来系统梳理 KNN 的完整知识脉络。一、KNN 的核心思想KNN 的定义非常直白判断一个未知样本属于哪一类参考距离它最近的 K 个样本的类别占比其中最多的类别就是预测结果。打个比方你刚搬到一个新小区想知道自己属于上班族还是退休老人哪个群体。KNN 的做法是——看看你住的那栋楼里离你最近的 K 户人家如果大多数人都是上班族那就把你也归为上班族。这就是近朱者赤近墨者黑的算法版本。KNN 的核心假设是**物以类聚**特征空间中距离越近的样本越可能属于同一类别。这个假设在大多数实际场景中都成立这也是 KNN 有效的基本前提。二、算法原理四步走KNN 的执行过程可以分为四步第一步计算欧氏距离。对于待预测样本计算它与训练集中每一个样本之间的距离。最常用的是欧氏距离——两点之间的直线距离。对于二维空间中的两个点 (x₁, y₁) 和 (x₂, y₂)欧氏距离就是d √((x₁-x₂)² (y₁-y₂)²)扩展到多维特征空间也同理——各维度差值的平方和开根号。比如两个样本分别有 4 个特征就计算 4 个维度差值的平方和再开根号。除了欧氏距离还有曼哈顿距离各维度差值的绝对值之和像在城市街道上走路一样只能沿坐标轴方向走、余弦距离衡量方向差异而非绝对距离常用于文本分析等但欧氏距离是 KNN 的默认选择适用于大多数连续数值特征的场景。值得一提的是KNN 中的距离不限于空间距离本质上是一种相似度度量——距离越小相似度越高。选择不同的距离度量方式会影响近邻的定义进而影响模型效果。在实际项目中欧氏距离是首选但如果效果不理想可以尝试切换其他距离度量。第二步按距离升序排序。把所有训练样本按与待预测样本的距离从小到大排列距离越小说明越近邻。第三步选择前 K 个样本。从排序结果中取出距离最小的 K 个样本它们就是待预测样本的K 个最近邻居。第四步投票决定结果。如果是分类问题让这 K 个邻居投票哪个类别得票最多预测结果就是哪个类别如果是回归问题取这 K 个邻居目标值的平均值作为预测结果整个过程不需要训练——KNN 是一种懒惰学习Lazy Learning算法训练阶段只是把数据存下来真正的计算发生在预测时。这也意味着预测速度可能较慢因为每次预测都要与所有训练样本计算距离。当训练集有 10 万条样本、每条样本有 100 个特征时每一次预测都要做 10 万次 100 维的距离计算计算量非常可观。与此相对线性回归是急切学习Eager Learning——训练阶段花费时间学习参数预测时只需一次矩阵乘法速度极快。两者的权衡是KNN 训练快、预测慢线性回归训练慢、预测快。在实时性要求高的场景中KNN 可能不是好选择。三、K 值的选择简单参数背后的深刻影响KNN 中最重要的参数就是 K——取多少个邻居来投票。这个看似简单的数字直接决定了模型的表现。K 值太小比如 K1只看最近的一个邻居。模型过于敏感容易受噪声和异常值影响。如果恰好最近的那个邻居是个标注错误的噪声点预测就会出错。这会导致过拟合——训练集上表现完美测试集上表现差。K 值太大比如 K 等于全部训练样本数。所有样本都参与投票预测结果永远是样本最多的那个类别完全忽略了待预测样本的特征。这会导致欠拟合——模型太简单什么都预测成同一个结果。K 值的选择本质上是在过拟合和欠拟合之间找平衡。K 太小模型太复杂K 太大模型太简单。那怎么找到最优的 K 值答案是参数调优交叉验证 网格搜索。这部分后面会详细讲。实际经验上K 通常取一个较小的奇数3、5、7 等取奇数是为了避免投票时出现平局。四、API 调用在 scikit-learn 中KNN 对应两个 APIKNeighborsClassifier用于分类任务输出离散类别KNeighborsRegressor用于回归任务输出连续数值from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor # 分类任务 clf KNeighborsClassifier(n_neighbors5) clf.fit(X_train, y_train) y_pred clf.predict(X_test) # 回归任务 reg KNeighborsRegressor(n_neighbors5) reg.fit(X_train, y_train) y_pred reg.predict(X_test)调用方式和其他 sklearn 模型一样遵循实例化 → fit → predict三步走。n_neighbors参数就是 K 值默认为 5。五、特征预处理KNN 的必修课KNN 基于距离计算这就带来一个关键问题如果特征的量纲不一致距离计算会被大量纲特征主导。比如预测一个人是否适合某项运动特征包括身高cm范围 150-200和 BMI范围 15-35。身高的数值远大于 BMI欧氏距离计算时身高的影响会压倒 BMI导致模型实际上只看了身高这一个特征。因此特征预处理是 KNN 的必修课。归一化将数据映射到 [0, 1] 区间x (x - min) / (max - min)反向操作x x × (max - min) min归一化的优点是简单直观结果一定在 [0, 1] 范围内。缺点是容易受异常值影响——一个极端值会拉大 max 或缩小 min把其他正常值压缩到很窄的范围内。标准化将数据转化为均值为 0、标准差为 1 的分布x (x - μ) / σ其中 μ 是均值σ 是标准差。标准差是方差的平方根方差 Σ(x - μ)² / n 标准差 √方差标准化不限定范围但对异常值的敏感度低于归一化。在大多数场景中标准化是更常用的选择。正态分布标准化和归一化都是线性变换还有一个更深层的目标——让数据呈现正态分布钟型分布。正态分布由两个参数决定μ均值决定钟形曲线中心最高峰的位置左右移动σ标准差决定钟形曲线的宽窄形状σ 越大曲线越扁平σ 越小曲线越陡峭正态分布有一个重要的3σ 原则±1σ 范围内包含约 68.3% 的数据±2σ 范围内包含约 95.4% 的数据±3σ 范围内包含约 99.7% 的数据3σ 原则在实践中很有用——如果一个数据点落在 3σ 之外它很可能是异常值可以考虑剔除。这也是数据预处理中异常值检测的常用方法之一。理解正态分布对机器学习意义重大因为很多算法包括线性回归都假设数据服从正态分布如果数据严重偏离正态分布模型效果可能会打折扣。六、实战案例鸢尾花分类鸢尾花数据集是机器学习最经典的入门数据集包含 150 条样本4 个特征花萼长度、花萼宽度、花瓣长度、花瓣宽度3 个类别山鸢尾、变色鸢尾、维吉尼亚鸢尾。from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.datasets import load_iris from sklearn.metrics import accuracy_score # 1. 加载数据并查看 iris load_iris() X iris.data y iris.target # 2. 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) # 3. 特征标准化KNN必须做 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 4. KNN 分类 knn KNeighborsClassifier(n_neighbors5) knn.fit(X_train_scaled, y_train) y_pred knn.predict(X_test_scaled) print(f准确率: {accuracy_score(y_test, y_pred):.4f})一个完整的 KNN 流程就是这样加载数据 → 划分数据集 → 特征标准化 → 模型训练 → 预测评估。注意fit_transform只在训练集上调用测试集用transform——测试集必须用训练集的均值和标准差来标准化不能用自己的。七、交叉验证 网格搜索自动寻找最优 K前面说到 K 值的选择是个难题手动尝试效率太低。交叉验证 网格搜索就是自动化解决这个问题的标准方案。交叉验证交叉验证的核心思想是将训练集数据根据折数平均切分其中一份作为验证集其余作为训练集继续训练。训练轮数为 cv 数每次训练得到一个分数取平均值作为最终评估。以 5 折交叉验证为例把训练集平均分成 5 份每次取其中 4 份训练、1 份验证轮换 5 次得到 5 个分数取平均。这样每份数据都当过验证集评估结果更可靠不会因为一次划分不巧而误判模型能力。网格搜索网格搜索是指指定参数的调试范围让程序自动遍历所有可能的参数组合。比如指定 K 的范围为 [1, 3, 5, 7, 9, 11]网格搜索会逐个尝试。两者结合交叉验证 网格搜索的完整流程将训练集数据根据折数平均切分其中一份作为验证集其余作为训练集训练轮数为 cv 数每次训练得到一个分数取平均值对于指定参数范围内的每一个参数值都进行一遍交叉验证得到一个平均分数取分数最高的那个参数作为最优参数本质上就是穷举所有候选参数每个参数做交叉验证选最好的那个。from sklearn.model_selection import GridSearchCV # 定义参数搜索范围 param_grid {n_neighbors: [1, 3, 5, 7, 9, 11]} # 网格搜索 交叉验证 grid GridSearchCV(KNeighborsClassifier(), param_grid, cv5) grid.fit(X_train_scaled, y_train) print(f最优K值: {grid.best_params_}) print(f最优分数: {grid.best_score_:.4f})GridSearchCV把交叉验证和网格搜索封装在一起一行代码就能自动找到最优参数。cv5 表示 5 折交叉验证它会尝试 K1、3、5、7、9、11 各做 5 折交叉验证最终返回分数最高的 K 值。八、评估方式混淆矩阵与四大指标模型训练完了怎么评估效果对于分类问题仅看准确率是不够的。混淆矩阵提供了更细致的评估视角。混淆矩阵混淆矩阵以矩阵形式呈现预测结果和真实结果中正例和反例的占比情况包含四个基本概念TP真正例真实值是正例预测值也是正例——预测对了FN伪反例真实值是正例预测值是反例——漏报了FP伪正例真实值是反例预测值是正例——误报了TN真反例真实值是反例预测值也是反例——预测对了用表格表示预测为正例预测为反例真实为正例TPFN真实为反例FPTN这四个值是所有分类评估指标的基础。四大评估指标准确率Accuracy预测正确的个数占总样本数的比例。Accuracy (TP TN) / (TP FN FP TN)准确率直观易懂但在数据不平衡时会有误导性。比如 99% 的样本都是反例模型全预测为反例准确率也有 99%但这个模型毫无用处。精确率Precision预测为正例的结果中真正例的占比。Precision TP / (TP FP)精确率关注的是我说它是正例的有多少真的是。在垃圾邮件检测中很重要——你希望被标记为垃圾邮件的确实都是垃圾邮件不要误杀正常邮件。召回率Recall真实值为正例的结果中预测为真正例的占比。Recall TP / (TP FN)召回率关注的是真正的正例我找出了多少。在医疗诊断中很重要——你希望真正患病的人都被检测出来不要漏掉任何一个病人。F1-Score精确率和召回率的调和平均值。F1 2 × Precision × Recall / (Precision Recall)F1-Score 综合考虑了精确率和召回率是一个平衡指标。当精确率和召回率都高时F1 才高一个高一个低时F1 会被拉低。在需要同时兼顾精确率和召回率的场景中F1-Score 是最常用的评估指标。举个实际例子来区分这三个指标假设有 100 封邮件其中 10 封是垃圾邮件正例90 封是正常邮件反例。模型预测了 8 封为垃圾邮件其中 6 封确实是垃圾邮件2 封是正常邮件被误判。那么精确率 6/8 75%预测的 8 封垃圾邮件中6 封是对的召回率 6/10 60%真正的 10 封垃圾邮件中只找到了 6 封准确率 (688)/100 94%100 封中总共对了 94 封。可以看到准确率 94% 看起来很高但召回率只有 60%——还有 4 封垃圾邮件漏掉了。如果这是邮件过滤系统漏掉垃圾邮件还可以接受但如果是疾病筛查漏掉一个病人代价就大了。所以选什么指标要看业务场景。指标公式关注点适用场景准确率(TPTN)/总数整体正确率数据平衡精确率TP/(TPFP)预测正例的纯度垃圾邮件检测召回率TP/(TPFN)真实正例的覆盖率医疗诊断F1-Score调和平均精确率与召回率的平衡综合评估九、学习心得与建议第一KNN 的简单是表象背后的知识体系是通用的。距离度量、特征预处理、交叉验证、网格搜索、混淆矩阵——这些概念在 KNN 中学到在逻辑回归、决策树、神经网络中照样用得到。学一个算法掌握一套通用工具这是学习机器学习的正确姿势。第二KNN 对特征预处理极其敏感。线性回归对量纲不敏感梯度下降法除外但 KNN 完全依赖距离计算不做标准化几乎一定会出问题。养成习惯用 KNN先标准化。第三K 值是 KNN 的灵魂。不要随便填一个数用 GridSearchCV 自动搜索。但也要注意——K 的范围别太大搜索范围越大计算量越大尤其是 KNN 本身预测就慢网格搜索会放大这个问题。第四KNN 的优缺点要清楚。优点原理简单、无需训练、天然支持多分类。缺点预测速度慢每次要与所有训练样本计算距离、内存占用大要存所有训练数据、对特征冗余敏感无关特征会干扰距离计算。数据量大、特征多时KNN 不是好选择。最后KNN 是机器学习中最亲民的算法——没有复杂的数学公式没有训练过程核心思想就是看邻居投票。但正因为它简单反而适合作为理解机器学习全流程的载体从特征预处理到模型训练从参数调优到评估指标KNN 把整个工作流串了起来。从机器学习概述到线性回归再到今天的 KNN我们逐步深入了监督学习的核心算法。每种算法都有自己独特的视角——线性回归用最优拟合线建模KNN 用近邻投票决策。理解不同算法的思路差异才能在面对实际问题时做出正确的选型。算法没有最好只有最合适。知道了每种算法擅长什么、不擅长什么你才能在正确的场景使用正确的工具。如果这篇文章对你有帮助欢迎点赞收藏。下一篇我们将继续探索决策树等机器学习算法敬请关注。
返回列表