本节摘要:K 近邻是唯一「零训练」的主流分类器:把全部算力推迟到预测时刻,用最近的 K 个邻居投票。追问集中在三处——K 怎么选、距离怎么定、预测为什么慢以及慢怎么办。它同时是讲「维度灾难」和「决策边界复杂度」的最佳教具。
这一节与前几节气质不同:KNN 没有损失函数、没有训练过程、没有参数估计,恰恰因为「什么都没做」,它的每个设计选择都裸露在追问之下。它也给了我们一个干净的参照系——后面第 2.5 节的朴素贝叶斯与之对照,能带出判别式与生成式这组大分野。
主问题:「KNN 的原理一句话就能说完,它的 K 和距离度量分别怎么定?」
KNN 对新样本计算它与训练集中每个点的距离,取最近的 K 个邻居做多数表决(回归则取均值),K 是唯一的模型复杂度旋钮。K 取一,决策边界最扭曲、噪声敏感,方差拉满;K 取到样本总数,直接退化成永远预测多数类,偏差拉满——又是第 1 章那对老朋友,只不过旋钮从正则系数换成了邻居数。距离度量默认欧氏,文本用余弦,类别特征需 Value Difference 类度量或先做编码处理。
值得主动补充的是三个预处理纪律:特征必须先标准化(量纲会暗中决定距离的主导者);类别不平衡时多数表决会被大类绑架,可改用距离加权投票;K 通常取奇数以规避平票。三句话齐出,「简单」的印象立刻改观。
追问:「K 取多少合适?拍脑袋吗?」
参考答法:K 用交叉验证选——把 K 当超参数放进第 6 章的网格里,按验证集表现扫描奇数序列;经验上从样本量的平方根附近起步。关键是要说清 K 与偏差方差的单调关系:K 增大,边界平滑、方差下降但偏差上升;反之亦然。再补一刀验证纪律:K 的选择必须发生在验证集上而不是测试集上,否则选 K 本身就在泄漏(这个话题第 6.1 节会展开成完整的方法论)。
追问:「KNN 预测要对全库算距离,业务上库有千万条怎么办?」
这题从教科书跳进工程现场,回答分两层。
理论层的加速:KD 树把空间递归划分以剪枝搜索,低维(约二十维以内)有效;维度一高,剪枝失效,退化回线性扫描——这正是维度灾难的一个侧面:高维空间里「最近」与「其他」的距离差趋于消失,近邻失去几何意义。球树、NSW/HNSW 这类图索引与局部敏感哈希(LSH)是高维场景的续命方案,代价是把「精确最近邻」放宽为「近似最近邻」。
工程层的换问法:很多业务其实不需要全体近邻,只需要「同预算下的 top-K 候选」,近似检索完全够用;再往后走就是向量数据库与内积量化(PQ)的领域。能把「精确度换吞吐」的交易讲清楚,比背出 KD 树结构更能得分。
from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.pipeline import make_pipeline pipe = make_pipeline(StandardScaler(), # 距离模型必须先标准化 KNeighborsClassifier(weights="distance")) grid = GridSearchCV(pipe, {"kneighborsclassifier__n_neighbors": [3, 5, 7, 11, 21]}, cv=5, scoring="f1_macro") # 不平衡数据看 macro-F1 grid.fit(X_train, y_train) print("最优 K:", grid.best_params_, "CV 得分:", round(grid.best_score_, 4))
流水线写法在这里不只是整洁:标准化器若在切分前对全量数据拟合,均值方差里就混进了验证折的信息,属于典型的小型泄漏——这个坑在第 6.1 节会被再次点名。
及格:说清投票机制与 K 的作用;良好:K 的选择连着偏差方差讲,距离度量按数据类型给出对应方案;优秀:维度灾难能讲到「距离集中现象」这层原因,加速方案能从 KD 树讲到近似检索的工程取舍。KNN 题表面在考算法,实际在考你对「简单模型的一切都被裸露」这件事的敬畏心。
顺着「简单模型」的话头,下一节来看朴素贝叶斯:一个假设离谱到近乎冒犯、却在文本分类里活得好好的生成式模型。
问:KNN 是参数模型还是非参数模型?
非参数——模型复杂度随训练集增长,没有固定数量的待估参数;「记忆本身就是模型」。这也解释了它的训练与预测成本结构:训练零成本,预测随库增大线性变贵,与参数模型正好相反。
问:距离加权投票解决了什么问题?
解决了「远邻居与近邻居一人一票」的不公平,也让 K 取大一点时边界不至于过度平滑,同时天然缓解平票。但它救不了维度灾难——距离本身失去意义时,加权无意义,先降维或换度量才是正路。
问:为什么 KNN 常被当作基线而不是生产模型?
预测延迟与库大小线性相关、内存驻留大、对特征尺度与缺失敏感、解释性弱。但它的零训练成本与「无需假设数据分布」让它成为验证特征质量的试金石——KNN 都学不动的特征表示,换复杂模型大概率也悬。
表达纪律:KNN 题请主动把话题带向维度灾难与近似检索,那是从「会背」到「用过」的分界线。
| 数据形态 | 推荐度量 | 一句理由 |
|---|---|---|
| 连续特征、各维同质 | 欧氏或曼哈顿 | 几何直观、实现最简 |
| 文本或稀疏向量 | 余弦相似度 | 只比方向不比模长,长度噪声免疫 |
| 有序类别混合 | Gower 距离 | 逐维选度量再加权聚合 |
| 时间序列 | DTW 动态时间规整 | 容许时间轴上的伸缩错位 |
| 高维稀疏二值 | 杰卡德或汉明 | 只关心共同出现的模式 |
距离度量的选择本质上是在回答「这个数据里什么叫相似」——把这句话说出口,距离题就从背表升级为设计。
**追加一问:ANN 近似检索的「近似」误差怎么控制?**主流图索引(HNSW 类)用召回率@候选数标定:扩大候选队列与搜索深度,召回逼近精确检索,代价是延迟上升——精度与延迟的滑杆由业务定标。面试能报出「召回率对延迟的权衡曲线」这个说法,近似检索的题就算答透了。