交叉验证
交叉验证将数据分成 k 个大小接近的折,轮流留出一折,用其余数据训练,再汇总 k 次评分。一次完整的 k 折中,每行恰好作为验证数据一次,降低只选一个留出集造成的偶然性。
本课用 20 张动物照片的二维特征和 1-NN:新照片复制训练集中最近照片的标签。同样 20 例,留出不同的四张,准确率可以从 1.00 变成 0.25。改变的是划分,不是算法。
方法解决了什么
一次 80/20 划分的分数既取决于模型,也取决于抽到哪些行。本数据的 400 次随机划分中,单次留出准确率只取 0.25、0.50、0.75、1.00,标准差为 0.2005;其中 140 次,即 35%,达到满分。作为参照,这组数据的留一法准确率是 80%,并非已知的总体真实准确率。
k 折先打乱一次,再分成 k 块,轮流留出。整轮始终有 n 个折外预测,每个预测都来自未见过该行的模型。谁被评估不再由抽签决定:每行都被评估。但某行对应的训练伙伴仍取决于分折,所以有限 k 下还会受划分影响。
本例确定性模型在 400 次划分下的结果是:
k | 完整交叉验证分数的标准差 | 折分数的离散程度 |
|---|---|---|
| 2 | 0.0685 | 0.1009 |
| 5 | 0.0351 | 0.1837 |
| 10 | 0.0186 | 0.2769 |
| 20 | 0.0000 | 0.4000 |
k = 20 时每折一张,划分编号不再改变训练/验证集合,因此完整分数固定;每折却只能得 0 或 1。折间标准差不是交叉验证估计的误差条。写成 0.80 ± 0.40 会混淆两个量。这组“增大 k 更稳定”的数值是本例结果,不是所有模型、数据和抽样过程的定律,在本例中也不是每一步都成立:k = 13 时标准差又回升到 0.0356;留一法也不消除数据采样不确定性。
注意 k 折的 k 是折数,k 近邻的 k 是邻居数,所以本课始终把模型叫作 1-NN。
逐步演示
默认 20 张照片,猫狗各 10,k = 5,划分编号 #8。这个编号用于展示一折满分、下一折很差的对照。
- 显示全部照片的二维特征。1-NN 的“训练”是保存训练例,不拟合参数。
- 留出第一折 #2、#12、#13、#15,其余 16 例成为模型。
- #2 找到距离
2.50的猫 #6,预测正确;#12 找 #16,#13 找 #19,#15 找 #9,也全部正确。 - 第一折
4/4 = 1.00。若此时停止,这就是单次留出的报告值。 - 第二折改为留出 #1、#4、#7、#8,重新用其他 16 例训练,其中包含刚才留出的四例。
- 狗 #1 找到距离
2.92的猫 #10,错误;猫 #4 找狗 #5,错误;狗 #7 找狗 #15,正确;猫 #8 找狗 #9,错误。 - 第二折
1/4 = 0.25。只换四个留出行,分数相差0.75。 - 后三折分别为
0.75(仅 #10 错)、1.00、1.00。 - 五折分数为
1.00、0.25、0.75、1.00、1.00。 - 等大折取平均即
16/20 = 0.800。记录表的每列恰有一个彩格:16 绿、4 红,验证每行只作一次折外预测。
换划分 #34,第一折变成 0.25,五折总分仍是 0.800。这两个编号的总分相同,不代表所有划分都相同。
计算成本与平均方式
需要 k 次训练,每次约 n(1 − 1/k) 行,总预测数恰好 n。增大 k 增加训练次数,也略增每次训练量。留一法有 n 次训练;若一次耗时一小时,20 次串行训练约需 20 小时,不含其他开销。
本数据从 5 折到 10 折,划分标准差从 0.0351 降至 0.0186;20 折为零只说明划分编号不再影响结果,不保证估计正确。5 折、10 折常用于成本与评估的折中,仍应按数据结构选择。
20 例分 3 折时大小为 7、7、6。不加权的折均分为 0.754,总正确数除以总例数为 0.750。cross_val_score(...).mean() 得到前者;后者按行加权,回答的聚合问题不同。本课在二者不同时都显示。
边界情况
- k 不整除 n:前
n % k折多一行,折均分和汇总正确率可能不同。 - 留一法
k = n:确定性模型每折为 0 或 1,划分编号无效,但有 n 次拟合,仍有样本不确定性。 k = 2:每次只有一半训练数据,本例 400 次均值为0.7609,低于留一法0.800。较小训练集可能造成悲观估计,不保证每一次都更差。- 重复主体:同一宠物两张照片、同一人的多次测量或同一视频多帧会相关。若目标是泛化到新主体,应按组切分;折数不能超过组数。
- 稀有类别:随机小折可能没有某个类别。分层划分尽量保持比例,但受整数和稀有类数量限制,不能保证每折都有所有类。
- 时间序列:随机打乱可能用未来预测过去,应按时间向前划分,并根据任务考虑间隔、重叠标签等泄漏。
先看一行代表什么
| 数据与目的 | 划分方式 | 作用 |
|---|---|---|
| 独立观测 | KFold | 轮流留出各行 |
| 独立的分类观测 | StratifiedKFold | 尽量保留类别比例;常见分类评分接口可默认采用 |
| 同一主体多次出现,评估新主体 | GroupKFold | 同组不跨训练与验证 |
| 时间点 | TimeSeriesSplit | 按过去到未来评估 |
| 小数据,想看划分敏感性 | 重复 k 折 | 比较完整运行分数,不把折间差当误差条 |
| 搜索超参数 | 嵌套交叉验证 | 内层选择,外层报告 |
常见错误
- 小样本只报一个划分:本例一折可能满分,也可能只有四分之一。可报告完整 k 折结果,并把折范围标明为离散程度,不称置信区间。足够大且代表性合理的独立测试集仍可有效。
- 把折标准差当估计误差:留一法的
0.80 ± 0.40不是有效的误差条。多次完整划分可测划分敏感性,但重复运行共享数据,其离散也不是完整的总体性能置信区间。 - 忽略组泄漏:第二数据集是 10 只动物、每只两张,共 20 张。随机 5 折得到
1.000,20 个验证例中 18 个在训练集中有同伴照片;设计的配对特征很近,示例距离比为2.24。改GroupKFold得0.500。留一法仍为1.000,因为同伴总在训练集。增加 k 不能修复主体泄漏。 - 在循环外拟合预处理:用全数据做缩放、填补或特征选择,会把验证统计量泄漏进训练。把所有需拟合的步骤放进一起交叉验证的
Pipeline。 - 用选择分数当最终报告:从 30 组超参数中选最高分后,该分数有选择偏差。用内层挑参数、外层评估选择过程,或保留独立测试集。
模型范围
这里实际执行分折、1-NN 预测、无权均分和组划分,只用 20 行、两个特征、准确率。两组数据都未分层;10 折时一折可能有两只同类动物,这是展示波动的设置。数据很大时单次划分通常更稳,但独立性、泄漏和代表性仍需检查。
真实评估可加入分层、重复或嵌套验证,各自解决不同问题。准确率适合作为这组平衡数据的演示指标,实际应结合类别比例与错误代价,另看精确率、召回率、F1、ROC-AUC 等;某些指标在单类折上未定义,不能机械地把同一平均规则套给所有情况。