概念笔记
kNN(k 最近邻分类)
kNN 是「人以群分」的算法化:要判断一个新样本,就找特征空间里离它最近的 k 个已知样本,让它们投票定类别(或统计各类占比给概率)。它不训练参数、只靠「距离近的样本标签大概率相同」这个假设,所以简单,样本够多时很准。量化课堂用 38–41 四篇讲它:兔子故事讲原理、kd 树两篇讲加速、sklearn 篇讲实操。
一句话
「你,就是你最常接触的五个人的平均。」kNN 把这句话变成算法:看一个新样本最近处的 k 个已知样本是谁,多数是哪类就判哪类;量纲不归一、距离算不对,这套就失效。
当前理解
- 输入输出:特征(如兔子身高、体重)→ 类别标签(品种)。迷之兔子 40cm/2.7kg:k=1 → 痛苦(最近的点);k=15 → 绝望(近邻多数)。
- k 是偏差-方差旋钮:k 小 → 边界崎岖、贴历史(过拟合);k 大 → 边界平滑、丢细节(欠拟合)。38 篇让读者凭感觉选;41 篇用测试集打分量化:同分布 toy 数据 30NN 97% vs 1NN 过拟合 95%。
- 距离:常用 L₂(欧氏)=√Σ(xᵢ−yᵢ)²;Lₚ 一般式、L∞=max 差。距离满足四条公理(非负/零当且仅当同点/对称/三角不等式)。
- 归一化是硬要求:各轴数值差一个量级(身高约 10 倍于体重)时 L₂ 被大量纲轴主导,换单位(纳米 vs 吨)结果大变。解法:每轴除以 max−min 再算距离(38 篇公式,41 篇实现同款)。
- 概率 kNN:数 k 近邻里每类几个 ÷ k → 各类概率。37cm/4.8kg 的星点 k=15 → 8 悲伤 7 痛苦 = 53%/47%。可配阈值做风控:>30% 概率是悲伤就逃跑——从此没被喷过。
- sklearn(41 篇):
KNeighborsClassifier(n_neighbors=k, weights='uniform'/'distance', algorithm='brute'/'kd_tree'/'ball_tree'/'auto', leaf_size, p=2);fit/predict/predict_proba/kneighbors/score。weights='distance' 按距离倒数加权,能让「很近的少数派」翻盘等权投票。 - 复杂度:每次查询要和所有样本算距离(O(DN)),大数据慢 → kd 树加速到 O(D log N)(39/40 篇)。
- 诚实的边界:toy 正态数据 97% 正确率是人为同分布生成的;真实涨跌预测达不到这个精度(41 篇原文提醒)。
来源
- 一只兔子帮你理解 kNN — 原理:兔子故事/距离/归一化/概率 kNN(postId=2227)
- scikit-learn 之 kNN 分类 — sklearn 实操与打分(postId=3227)
- 关联:kd 树算法之思路篇、kd 树算法之详细篇(加速)、kd 树(把空间切成二叉树的最近邻索引)(数据结构页)、因子预处理(去极值、标准化与市值/行业中性化)(量纲统一的因子端对应)
常见混淆
- kNN 没有「训练」≠ 没有成本:fit 只是存数据/建树;真正的成本在查询时的距离计算——所以才有 kd 树。
- 归一化 ≠ 可选:不同单位/量纲直接算 L₂,结果被大数值轴独裁。注意 kNN 的「每轴除以 max−min」与聚宽因子的标准化/中性化是同一「量纲统一」家族里的不同做法,别混用口径。
- 分类 vs 回归:kNN 也能做回归(近邻取平均/加权),38 篇只讲分类。
- 「最近」≠「相关/因果」:特征近只说明「像」,不保证机制相同;把 kNN 用到股票要格外小心特征工程与过拟合(41/43 篇的诚实提醒)。
- 概率 kNN 的阈值(30%)是应用层选择,不是算法输出;换阈值就换决策。
- kNN 不是「选出最像的那一个」:k=1 只是极端;一般用多数投票,让一组近邻说话而不是一个。
开放问题
- k 怎么选没有普适解:偏差-方差之外,样本密度、类别不均衡、维度都影响;38 篇「凭感觉」、41 篇用测试集比较,均无自动选择法。
- 高维退化(维数灾难):维度增加时点与点距离趋同,kNN 效果变差——本库两篇都没展开。
- 归一化方式(min-max vs z-score 等)对结果的影响未讨论;类别不均衡时多数投票会被大类带偏,概率 kNN 同样受影响——未讨论。
- 41 篇 score 的训练/测试同分布生成,只测「同分布内泛化」;跨时段外推(股票语境)的过拟合风险仍是开放问题,答案在 W9 的回测方法论。
来源
更新 2026-09-06