想象你搬进了一个陌生小区,叫“听风苑”。你想知道这片住户整体是“爱热闹的夜猫子”还是“爱安静的早睡党”。你没有业主名册,也没有大数据报告,最简单粗暴的办法是——站到楼下,找到离你家最近的三户邻居,观察他们的作息。如果三户里有两户每天都凌晨才熄灯,你大概可以判断:这一片是夜猫子聚集地。这就是 K 近邻算法(KNN)的全部直觉:物以类聚,人以群分。认识一个人,先看他身边最近的那圈朋友;判断一个数据点,先看它距离最近的 K 个“邻居”怎么说。整个过程不需要“训练”——你不需要事先总结小区规律,只是现查现问;但每来一个陌生人要判断,你都得重新跑遍整栋楼,把每户打量一遍。这份“省事但费脚力”的智慧,就是 KNN 算法。

岗位关联

KNN 是机器学习入门的第一块敲门砖——它没有花哨的训练过程,却把“距离度量”“K 值选择”“多数投票”这些贯穿所有监督学习的基础概念一次性讲透。掌握它,你就拿到了读懂后续一切算法的钥匙。

目录
  1. 可视化演示
  2. 核心思想:物以类聚,向邻居投票
  3. 距离度量:亲疏远近,各有算法
  4. K值选择:问几个邻居才靠谱
  5. 分类与回归:举手表决与报价平均
  6. 惰性学习:不备课的现问现答
  7. 优缺点分析:简单直观与维度隐忧
  8. 实践要点:让邻居靠谱的工程秘笈
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示K近邻分类的投票决策过程、欧几里得与曼哈顿距离度量对比,以及不同K值对决策边界的影响。

本节配有交互动效(进入视口后自动加载,约 3KB)。

K近邻分类决策 找到测试点(橙)最近的K个邻居,多数投票决定类别 连线表示K个最近邻,距离越近影响力越大 y = mode(K nearest neighbors) KNN惰性学习无需训练,推理时计算所有距离

核心思想:物以类聚,向邻居投票

小明初到“听风苑”小区,分不清这一片是文艺青年的沙龙还是程序员的工位群。他没有门禁卡、没有业主名单,只做了一件事——站到楼下,观察离自己单元最近的三户人家:一户深夜还在敲键盘、一户桌上摆着三台显示器、一户运动鞋堆满玄关。三户里有两户明显是程序员,他于是推断:这个单元程序员浓度偏高。

机器学习里,“住户”叫训练样本,“作息类型”叫标签。来了一个没有标签的新样本(新住户),我们不做任何假设,只在存量数据中找到距离它最近的 K 个样本,让这 K 个“邻居”举手表决:分类任务中,得票最多的类别就是预测结果。这就是 KNN 的全部工作流程。

用数学语言说:对测试样本 $\mathbf{x}$,先找出它的最近邻集合 $N_k(\mathbf{x})$,再让这些邻居为每个候选类别投票:

整个过程没有“总结规律”这一步,只看身边人的声音——这就是“近朱者赤、物以类聚”的朴素智慧。判断一个数据点的身份,先看它身边最近的那圈朋友;朋友怎么说,它就怎么答。

y^=arg⁡max⁡c∑i∈Nk(x)I(yi=c)\displaystyle \hat{y} = \arg\max_{c} \sum_{i \in N_k(\mathbf{x})} \mathbb{I}(y_i = c)
这个公式是在说:统计 K 个最近邻居各自的类别,哪个类别被举手的次数最多,就把它作为新样本的预测答案。
  1. 邻居集合距离测试样本最近的 K 个训练样本组成一个“小圈子”,圈内人才有投票资格。
    Nk(x)N_k(\mathbf{x})
  2. 指示函数判断第 i 个邻居的标签是否等于候选类别 c,是则记 1 票,否则记 0 票。
    I(yi=c)\mathbb{I}(y_i = c)
  3. 求和把 K 个邻居中投给类别 c 的票数全部累加起来。
    ∑i∈Nk(x)\sum_{i \in N_k(\mathbf{x})}
  4. 取最大者比较所有类别的得票总数,返回票数最多的那个类别作为最终预测。
    y^=arg⁡max⁡c\hat{y} = \arg\max_{c}

距离度量:亲疏远近,各有算法

小明想定义“最近”。拎着菜篮子笔直穿过花园是直线距离;沿着蜿蜒的社区步道绕行是折线距离;按微信共同好友的数量衡量亲疏,又是另一种算法。三种定义下,“最近的邻居”可能是完全不同的三户人家。

在 KNN 里,这个定义由“距离度量”决定——它决定了哪些样本有资格当邻居,进而直接左右投票结果,是整个算法的地基。最常用的两种是欧氏距离(直线距离)和曼哈顿距离(街区折线距离),它们同属闵可夫斯基距离族,只是参数 p 不同:

此外还有余弦相似度——它不看两点相距多远,只看两个向量方向是否一致,常用于文本这类高维稀疏特征。小明最终选了“直线距离”作为默认,直观又计算简单;但他也记住了:距离选错了,邻居就选错了,投票全盘皆输。工程里面对复杂特征时,先想清楚“什么样的邻居才算近”,再谈算法。

d(x,z)=(∑j=1n∣xj−zj∣p)1/p\displaystyle d(\mathbf{x}, \mathbf{z}) = \left( \sum_{j=1}^{n} |x_j - z_j|^p \right)^{1/p}
p=1 时是曼哈顿距离(只能沿网格线走),p=2 时是欧氏距离(可以走直线)。p 越大,距离越被“差距最大的那个特征”主导。
  1. 特征差值两个样本在每一维特征上相差多少,取绝对值保证非负。
    ∣xj−zj∣|x_j - z_j|
  2. p 次幂p 是算法的“风格参数”,决定距离的种类。
    ∣xj−zj∣p|x_j - z_j|^p
  3. 求和把所有维度上的差距汇总成一个总值。
    ∑j=1n\sum_{j=1}^{n}
  4. 开 p 次方还原尺度,得到最后的距离数值。
    (⋅)1/p\left(\cdot\right)^{1/p}

K值选择:问几个邻居才靠谱

小明试过只问 1 户,那户大叔刚从工地回来,满身疲惫地抱怨“这破小区”,他差点连夜搬家;又试过问全小区 500 户,结果被远处别墅区的富豪们拉高了“生活质量均值”,判断同样失真。问几个邻居,直接决定了判断质量。

K 是 KNN 最重要的超参数。K=1 时模型近乎“死记硬背”每一个样本,决策边界极度崎岖,噪声一抖答案就变——这是过拟合;K 趋于全体样本数时,预测被全局均值主导,边界几乎消失——这是欠拟合。K 的选择,本质是在“对噪声过敏”和“被无关样本稀释”之间走钢丝。

从回归的角度最容易看清 K 的平滑作用——K 个邻居标签的均值就是预测值:

经验上可以从 K≈√N(N 为样本数)起步,再用交叉验证——把训练集切成几份、轮流当验证集——精调取值。二分类任务中通常取奇数,以避免平票僵局。小明最后的做法是“模拟试错”:分别问 1 户、3 户、5 户、10 户,谁的判断最吻合后来真实发生的事,就用谁——这正是交叉验证的朴素形态。邻居数量不多不少,刚刚好。

y^=1K∑i∈NK(x)yi\displaystyle \hat{y} = \frac{1}{K} \sum_{i \in N_K(\mathbf{x})} y_i
K 越大,预测越平滑、越稳定,但也越可能丢失局部细节;K 越小,预测越锋利、越贴近局部,但也越容易被单个异常点带偏。
  1. 邻居标签K 个邻居各自的输出值,比如每户的“房价报价”。
    yiy_i
  2. 求和把 K 个邻居的标签值全部加起来。
    ∑i∈NK(x)\sum_{i \in N_K(\mathbf{x})}
  3. 求平均除以 K 得到平滑的预测;K 越大,单个极端值的影响越小。
    1K\frac{1}{K}

分类与回归:举手表决与报价平均

同样是问邻居,问题不同,汇总方式也不同。“你们觉得这小区是文艺风还是程序员风?”——大家举手表决,票多者胜,这是分类;“你家这套房子大概多少钱?”——把几户报价取个平均,这是回归。

KNN 天生一身两用:分类输出离散标签,采用多数投票;回归输出连续数值,采用均值投票。更精细的做法是按距离加权——离得越近的邻居话语权越大,避免远处“邻居”一票顶近处十票。

加权投票的公式如下:

KNN 的决策边界也很有特点:它由全体训练样本共同拼出,是一块块非线性“拼图”;K 小时边界崎岖,K 大时边界平滑。小明把各家“风格标签”贴在地图上,用彩笔画出文艺区与程序员区的分界线;新住户落在哪边,就听哪边邻居的多数意见。分类与回归,不过是“举手表决”和“报价平均”这两件生活小事的数学化。

y^=arg⁡max⁡c∑i∈Nk(x)1di⋅I(yi=c)\displaystyle \hat{y} = \arg\max_{c} \sum_{i \in N_k(\mathbf{x})} \frac{1}{d_i} \cdot \mathbb{I}(y_i = c)
每张票不再等权:距离越近的邻居,手中的票越重。加权之后,近邻的声音被放大,远邻的干扰被压制。
  1. 距离倒数权重距离越近权重越大;距离为 0 时可用 1/(d+ε) 避免除零。
    1di\frac{1}{d_i}
  2. 加权票数每张票按亲疏关系乘以权重,不再是简单的一票一权。
    1di⋅I(yi=c)\frac{1}{d_i} \cdot \mathbb{I}(y_i = c)
  3. 加权汇总与决策对每个类别累加加权票数,取总分最高的类别。
    arg⁡max⁡c∑i∈Nk(x)\arg\max_{c} \sum_{i \in N_k(\mathbf{x})}

惰性学习:不备课的现问现答

小明从不备课。每次有人问他“这小区到底怎么样”,他都现跑下楼、挨家挨户敲门观察,回来再给答案。好处是永远不用维护什么《小区规律白皮书》,认知随问随新;坏处是——每次回答都气喘吁吁。

这种“训练阶段什么都不做,把所有计算推迟到预测阶段”的模式,叫惰性学习。KNN 是典型的惰性学习模型:训练时只是把数据原样存档,不学习任何参数。与之相对的是“急切学习”——比如线性回归在训练阶段就全力拟合出参数,预测时只需做一次简单乘法,就像小明提前把小区规律写成手册,之后翻书即可。

两种模式的代价差异,可以用复杂度公式直观刻画:

“不备课的老师”适合小班精讲(数据量小),但面对十万户的小区,每被问一次就跑十万户,迟早累瘫。这也解释了为什么 KNN 在工业落地时,总要配上 KD 树等索引结构,或干脆只在小规模场景使用。

T训练=O(1),T推理=O(n×d)\displaystyle T_{\text{训练}} = O(1), \quad T_{\text{推理}} = O(n \times d)
训练几乎不花时间(只是存数据),但每预测一个样本都要遍历全部 n 个训练样本、每个样本又要算 d 维距离,所以推理代价与样本数和维度数都成正比。
  1. 训练开销只做存储、不学参数,恒定时间完成。
    T训练=O(1)T_{\text{训练}} = O(1)
  2. 样本遍历每个新样本都要与全部 n 个旧样本计算距离,共进行 n 次距离计算。
    O(n)O(n)
  3. 维度乘积每次距离计算又需要遍历 d 个特征,总代价为两者相乘。
    O(n×d)O(n \times d)

优缺点分析:简单直观与维度隐忧

小明的方法朴实可靠,但问题在小区越扩越大、住户档案越来越厚后暴露了:每户记录身高、收入、口味、宠物、作息等几十上百个维度,他发现测出来的“最近的邻居”越来越不靠谱——所有人好像都一样远。

KNN 的优点一目了然:简单直观、无需训练、对数据分布几乎不做假设,天然支持多分类和回归。缺点同样致命:推理慢(上一节已算过这笔账)、对特征尺度敏感,以及高维特征空间下距离区分度骤降——这就是著名的“维度灾难”。

维度灾难有一个反直觉的数学事实:在高维空间里,任意点到“最近邻居”和“最远邻居”的距离几乎相等,“近邻”概念本身开始失效:

当“最近的邻居”和“最远的邻居”看起来一样远时,小明的经验法则彻底失灵。这也解释了为什么 KNN 在低维、小规模数据上表现惊艳,而在高维大数据上必须借助降维与索引加速才能“续命”。

dmax⁡−dmin⁡dmin⁡→m→∞0\displaystyle \frac{d_{\max} - d_{\min}}{d_{\min}} \xrightarrow{m \to \infty} 0
随着维度 m 不断增大,最近距离与最远距离的相对差距趋近于零。大家看起来都差不多远,还怎么选“最近邻居”?
  1. 最近与最远距离某个点到其最远邻居、最近邻居的距离。
    dmax⁡,dmin⁡d_{\max}, d_{\min}
  2. 距离差距两者相减,得到一个越来越小的差值。
    dmax⁡−dmin⁡d_{\max} - d_{\min}
  3. 比值趋零差值除以最小值后随维度增加趋近于 0,“远近”之分消失。
    →m→∞0\xrightarrow{m \to \infty} 0

实践要点:让邻居靠谱的工程秘笈

吃过几次亏后,小明总结了四条“问邻居”的秘笈:第一,身高(厘米)和收入(万元)不能放在一起比,得先统一量纲;第二,档案太厚就只挑最相关的几页看;第三,把全小区住户编成一本带索引的通讯录,找邻居不用整栋楼挨家跑;第四,程序员住户如果占九成,投票时得防止“人多势众”淹没少数派。

对应到 KNN 工程实践,就是四大要点:特征标准化、特征降维、KD树加速检索、类别不平衡处理。其中标准化的作用最基础——它直接决定距离算得公不公平。

标准化公式如下:

其余三点各有分工:降维用 PCA 把高维压到几十维以内,缓解维度灾难;加速用 KD 树按维度二分空间、剪枝跳过明显遥远的样本,把推理从“全楼跑”变成“翻索引”;类别不平衡则对多数类降采样、或给少数类样本更高投票权重。有了这套秘笈,小明再问邻居就从容多了:先统一度量衡,再精简档案,再翻索引,最后提防“人多势众”。KNN 在真实工程里好不好用,往往不是算法本身的问题,而是这些前置功夫做没做到位。

x′=x−μσ\displaystyle x' = \frac{x - \mu}{\sigma}
先把该特征减去均值 μ,让数据中心归零;再除以标准差 σ,让不同量纲的特征拥有相近的尺度。这样“身高”和“收入”才不会被量纲差距扭曲成“只有身高在主导距离”。
  1. 均值中心化减去该特征在所有样本上的平均值,把分布的中心搬到 0。
    x−μx - \mu
  2. 标准差归一σ 描述该特征的离散程度,除以 σ 即把尺度统一。
    σ\sigma
  3. 标准化特征得到的 x' 均值为 0、方差为 1,各维度对距离的贡献“一视同仁”。
    x′x'

AI 应用场景

个性化推荐里的“邻居拼单”

阶段:召回与初筛(推理阶段)

解决的问题:传统协同过滤需要离线训练矩阵分解模型,冷启动用户在没有任何历史交互时根本无法预测。KNN 换了个思路:不学参数,直接找“兴趣距离最近”的 K 个老用户,把这群邻居点过、买过的物品按热度排序推荐给新用户——相当于小明刚搬来,直接问最像自己的 K 户邻居“你们平时逛哪家店”。

具体案例:某电商 App 在用户注册且未产生任何行为时,基于注册问卷的偏好向量,用 KNN 找出相似老用户,从邻居的历史购买中召回 50 个候选商品池,再交给精排模型,使冷启动曝光点击率提升 18%。

异常检测:发现“谁都不认识的神秘住户”

阶段:数据预处理与安全风控

解决的问题:传统欺诈检测依赖手工规则,规则覆盖不全、维护成本高。KNN 异常检测计算样本到 K 个最近邻居的平均距离,距离显著大于阈值就判为异常——逻辑就像“你的邻居都不认识你,你大概率是新来的怪人”。

具体案例:风控团队对信用卡交易数据做标准化后,用 KNN 平均近邻距离筛选离群交易,将疑似盗刷样本送入人工复核队列,在保持召回率的同时把误报率降低了 30%,并显著减少了规则工程师的手工调参时间。

手写数字识别:入门级图像分类

阶段:模型推理(分类任务)

解决的问题:深度学习模型训练代价高,对小规模、低维的识别任务属于“杀鸡用牛刀”。KNN 把图像展平成像素向量,直接算欧氏距离找最近邻,几行代码就能搭建一个可用的基线模型。

具体案例:在 MNIST 手写数字数据集上,用 KNN(K=3,先做像素归一化)即可达到约 97% 的准确率。许多团队把它作为新任务的“第一个模型”,用来检测数据质量,并为后续复杂模型提供性能下限参考。

Python 演示

python45 行
import mathfrom collections import Counterfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score  def euclidean(a, b):    # 欧氏距离: 两点各维度差值的平方和开根号    return math.sqrt(sum((x - y) ** 2 for x, y in zip(a, b)))  def knn_predict(X_train, y_train, x, k=3):    # KNN 分类: 取最近 K 个邻居做多数投票    distances = sorted((euclidean(x, xn), i) for i, xn in enumerate(X_train))    top_k = [y_train[idx] for _, idx in distances[:k]]    label, _ = Counter(top_k).most_common(1)[0]    return label  def knn_regress(X_train, y_train, x, k=3):    # KNN 回归: 取最近 K 个邻居标签的均值    distances = sorted((euclidean(x, xn), i) for i, xn in enumerate(X_train))    top_k = [y_train[idx] for _, idx in distances[:k]]    return sum(top_k) / len(top_k)  def main():    data = load_iris()    X_train, X_test, y_train, y_test = train_test_split(        data.data, data.target, test_size=0.3, random_state=42    )    for k in (1, 3, 5, 9):        preds = [knn_predict(X_train, y_train, x, k) for x in X_test]        print("k = {} 分类准确率: {:.2f}".format(k, accuracy_score(y_test, preds)))     # 回归演示: 输入 1 维特征, 输出连续值    Xr = [[5.1], [4.9], [6.2], [5.8], [7.1], [6.3], [5.7], [4.8]]    yr = [1.4, 1.2, 2.8, 2.1, 3.0, 2.4, 1.9, 1.1]    pred = knn_regress(Xr, yr, [5.5], k=3)    print("特征值 5.5 的回归预测值: {:.2f}".format(pred))  if __name__ == "__main__":    main()
目的:从零实现 KNN 分类与回归,在鸢尾花数据集上比较不同 K 值的效果,并演示一维特征下的回归预测。
  1. return math.sqrt(sum((x - y) ** 2 for x, y in zip(a, b)))逐维度计算差值平方和再开根号,这就是欧氏距离。
  2. distances = sorted((euclidean(x, xn), i) for i, xn in enumerate(X_train))对全部训练样本算距离并升序排列,邻居按“亲疏”排队。
  3. top_k = [y_train[idx] for _, idx in distances[:k]]取排队最靠前的 K 个邻居的标签。
  4. label, _ = Counter(top_k).most_common(1)[0]用计数器做多数投票,取出票数最多的类别。
  5. return sum(top_k) / len(top_k)回归与分类的唯一区别:求和取平均而不是投票。
  6. for k in (1, 3, 5, 9):依次尝试不同 K,直观观察“过小过拟合、过大欠拟合”的现象。
  7. pred = knn_regress(Xr, yr, [5.5], k=3)用 8 条一维数据演示回归:预测特征 5.5 对应的输出。

常见误区

误区“KNN 不是也要调参吗?训练时它应该会自动学习一组最优的 K 值和距离权重吧。”

正解KNN 真正的“训练”只有一步——把训练数据存起来,没有任何参数学习。K 和距离度量属于超参数,是通过交叉验证等手段在外层“试”出来的,而不是在训练过程中“学”出来的。就像小明不是被训练成“该问几户”,而是自己试了 1 户、3 户、5 户后拍脑袋定的。

为何常见:Scikit-learn 里所有模型都调用统一的 fit 接口,让人误以为 KNN 也在学参数,忽略了惰性学习只是存储数据的本质。

误区“邻居问得越多信息越充分,K 越大预测肯定越准吧?”

正解K 过大会把距离很远、与你毫不相干的“邻居”拉进投票圈,决策被多数无关样本稀释,模型过于平滑(欠拟合);K 过小则只盯着一两个样本,噪声一抖答案就变(过拟合)。正确做法是画出“K-误差”曲线选拐点,或用交叉验证确定 K。

为何常见:直觉上“样本多=信息多=更准”,却忽略了 KNN 的邻居必须具有空间上的邻近性——数量多不等于相关性强。

误区“反正距离公式会自动综合所有维度,把原始数据直接丢进去算欧氏距离不就行了?”

正解如果“身高(厘米)”和“收入(万元)”一起算欧氏距离,数值大的维度会完全吞掉数值小的维度,距离几乎只反映身高差异。必须先标准化(减去均值除以标准差),让每个特征对距离的贡献公平。这也是 KNN 表现“忽好忽坏”最常见的元凶。

为何常见:距离公式看起来对每个维度一视同仁,但人们忽略了数值尺度本身并不等价,量纲天然给大数值特征加了隐性权重。

误区“KNN 名字里带'分类',应该只能做分类任务吧?回归得用别的算法。”

正解KNN 天然支持回归:把多数投票换成 K 个邻居标签的均值即可。分类是“举手表决”,回归是“报价取平均”。同样的距离检索加邻居聚合框架,稍作变化还能做异常检测、密度估计。

为何常见:教材和示例几乎都用分类来演示 KNN(鸢尾花、手写数字),导致很多人把它框定在分类任务里。

误区“KNN 又不用训练,那就把历史数据全存下来,样本越多知识越丰富,预测越准。”

正解KNN 的推理复杂度是 O(n×d)——每预测一个样本都要遍历全部训练样本算距离。直接上千万级样本,单次预测耗时不可接受。工程上必须用 KD 树、球树等索引剪枝,或先做聚类、采样减小候选集;而且极高维下距离区分度退化,数据再多也无济于事。

为何常见:只看到惰性学习“训练省力”的好处,忘了“省下的训练账都记在了预测头上”——训练越省,推理越贵。

面试题

Q1. KNN 的“训练”阶段,模型实际在做什么?

单选题 · easy

  • A.学习一组最优权重参数
  • B.存储全部训练样本← 正确答案
  • C.构建多层神经网络
  • D.生成决策树分支结构

答案:B。KNN 是惰性学习模型,训练阶段不做参数学习,只是把训练样本原样存起来,等价于“记住邻居名单”。A、C、D 都是急切学习模型(如线性模型、神经网络、决策树)在训练阶段做的事。

Q2. 当 K=1 时,KNN 的预测结果是?

单选题 · easy

  • A.所有样本的类别均值
  • B.随机一个样本的类别
  • C.最近一个样本的类别← 正确答案
  • D.最远一个样本的类别

答案:C。K=1 意味着只问“最近的那一户邻居”,它是什么类别,新样本就归为什么类别。这也解释了为什么 K=1 最容易过拟合——单一邻居可能恰好是噪声点。

Q3. 闵可夫斯基距离中 p=2 对应哪种距离?

单选题 · easy

  • A.曼哈顿街区距离
  • B.切比雪夫距离
  • C.欧氏直线距离← 正确答案
  • D.余弦相似距离

答案:C。闵可夫斯基距离是距离度量家族的总纲:p=1 时退化为曼哈顿距离(街区折线),p=2 时退化为欧氏距离(直线距离)。选 A 是把参数记反了。

Q4. K 值过小(如 K=1)更容易导致什么问题?

单选题 · mid

  • A.模型欠拟合
  • B.模型过拟合← 正确答案
  • C.训练速度变慢
  • D.发生维度灾难

答案:B。K 过小意味着只参考极少数邻居,决策边界极度崎岖,单个噪声点就能带偏预测——这是过拟合的典型表现。K 过大才会因引入大量远处样本而导致欠拟合。

Q5. 欧氏距离与曼哈顿距离的本质区别?

单选题 · mid

  • A.直线距离与街区折线← 正确答案
  • B.分类与回归的差异
  • C.计算速度快慢不同
  • D.只是叫法上的区别

答案:A。欧氏距离走两点间“直线”,曼哈顿距离只能沿坐标轴“折线”前进,就像在方格街区的城市里开车。二者都是闵可夫斯基家族成员,只是 p 取 2 还是 1。

Q6. 为什么高维数据下 KNN 效果会明显变差?

单选题 · mid

  • A.距离计算复杂度上升
  • B.最近最远距离趋于相等← 正确答案
  • C.训练样本数量被迫减少
  • D.标签中的噪声被放大

答案:B。维度灾难的核心表现是“距离浓度”:维度越高,任意点到最近与最远邻居的距离之比越趋近于 1,“近邻”失去区分度。复杂度上升只是“变慢”,并不是“变差”的根本原因。

Q7. 特征标准化对 KNN 的关键作用是?

单选题 · hard

  • A.让数据分布变成正态
  • B.消除量纲对距离的偏差← 正确答案
  • C.减少邻居搜索计算量
  • D.自动确定最优的 K 值

答案:B。KNN 直接用原始数值算距离,量纲大的特征会垄断距离计算。标准化(减去均值、除以标准差)让各特征对距离贡献公平,相当于先把“身高厘米”和“收入万元”换算到同一把尺子上。

Q8. KNN 回归得到预测值的方式是?

单选题 · mid

  • A.K 个邻居中最多的类别
  • B.K 个邻居标签的平均值← 正确答案
  • C.全体训练样本标签均值
  • D.最近单个邻居的标签值

答案:B。回归任务中,KNN 把“举手表决”换成“报价取平均”——对 K 个最近邻居的数值标签求均值。A 是分类的投票逻辑,D 是 K=1 的特例,C 则完全失去了“邻居”的意义。

Q9. 以下哪些属于 KNN 的缺点?

多选题 · mid

  • A.推理阶段计算开销大← 正确答案
  • B.对特征尺度非常敏感← 正确答案
  • C.训练阶段需要大量时间
  • D.高维下近邻概念失效← 正确答案

答案:ABD。KNN 推理要遍历全部样本算距离,开销大(A 对);没有标准化时量纲会扭曲距离(B 对);高维下最近与最远距离趋同、近邻失效(D 对)。C 恰恰相反——惰性学习的训练阶段几乎不花时间。

Q10. KNN 二分类投票出现平票时,下列哪些处理方式可行?

多选题 · extreme

  • A.从平票类别中随机选择← 正确答案
  • B.改用距离加权的方式计票← 正确答案
  • C.增大 K 值后重新进行投票← 正确答案
  • D.擅自修改训练样本的标签

答案:ABC。平票时随机选择是一种被广泛采用的无偏策略;距离加权让近邻话语权更大,能有效打破平票;增大 K(常取奇数)重投也是工程惯例。D 会篡改数据、破坏模型可信度,绝对不可取。