📑 本页目录(点开跳转)
11 · 标签噪声
⏱ 72 分钟 | ⭐⭐ 评测集里的一个错标签,比训练集里的十个更贵
🎯 一句话
你的标签里有百分之几是错的 —— 这不是"如果",是"已经"。 训练集里的噪声,大部分能被集成、正则和早停扛过去; 评测集里的噪声扛不过去 —— 它不让模型变差,它让你选错模型、选错方向。
🧭 一、先接受一个事实:标签本来就有错
很多人默认「标签 = 真值」,然后把所有精力花在模型上。 但 2021 年有人系统性地核查了十个最常用的公开测试集,结论大致是这样:
| 数据集 | 测试集里被判定标错的比例(量级) |
|---|---|
| MNIST / CIFAR-10 | ~0.15% / ~0.5% |
| 20news / Caltech / AudioSet | ~1%–1.5% |
| IMDB / Amazon 评论 | ~3%–4% |
| ImageNet 验证集 / CIFAR-100 | ~5.8% / ~5.9% |
| QuickDraw | ~10% ⭐ |
💀 这份核查最该被记住的不是错误率,是它的第二个结论: 把 ImageNet 验证集的错标签修正之后,模型的排名会变—— 在原始标签下更强的大模型,在修正后的标签下会输给更小的模型。 也就是说:过去很多"更大更好"的结论,一部分是在跟标签噪声较劲。
公开数据集是被反复审视过的,你自己的业务数据只会更差。 经验区间:外包标注的多分类任务 5%–15%,主观任务(意图、情感、内容尺度)15%–30% 都不罕见。
噪声从哪来(四条,前两条占绝大多数):
① 定义模糊 —— 指南没写清边界,两人理解不同
⭐ 最大的一类,且它产生的是【系统性】噪声
② 标注员漂移 —— 换人、换供应商、疲劳、KPI 压力(第 9、10 章)
③ 工具与流程 —— 界面默认选中、快捷键手滑、批量操作误伤
④ 客观困难样本 —— 图糊了、文本本来就有歧义
⚠️ 这不是"错",是"这条数据不该有确定标签"
⭐ 必须先分清两种噪声,它们的处置方式完全相反: 随机噪声(手滑、疲劳)——各类之间大致对称,模型的集成和正则能扛。 系统性噪声(指南理解偏差)——只往一个方向偏,正则一点用都没有, 因为正则的前提假设就是"错误是随机的"。 这一条是本章后面所有判断的分水岭。
🧪 二、噪声对训练到底有多大影响(实跑)
下面全是真跑出来的(16000 条、20 维、3 分类,训练 12000 / 干净测试集 4000)。 往训练标签里注入 x% 的对称噪声,在干净测试集上看准确率:
| 模型 | 0% | 5% | 10% | 20% | 30% | 40% |
|---|---|---|---|---|---|---|
| 逻辑回归 | 0.7635 | 0.7615 | 0.7638 | 0.7622 | 0.7605 | 0.7475 |
| 随机森林(200 棵) | 0.9463 | 0.9473 | 0.9467 | 0.9420 | 0.9270 | 0.9085 ⭐ |
| 无限深单棵树 | 0.8610 | 0.8080 | 0.7670 | 0.6853 | 0.6142 | 0.5407 💀 |
| 深度限制树(depth=6) | 0.8215 | 0.8150 | 0.8077 | 0.8053 | 0.8045 | 0.7668 |
| KNN(k=15) | 0.9200 | 0.9187 | 0.9175 | 0.9035 | 0.8795 | 0.8125 |
⭐ 第二行和第三行放在一起看,就是这一节的全部内容: 同一份数据、同样 40% 的错标签,随机森林只掉 3.8 个百分点,单棵深树掉 32 个百分点。 差别不在"模型多强",在于它有没有机会把每一条错标签单独记住。
同一批实验,看它们在自己训练数据上的拟合准确率(对着噪声标签):
| 模型 | 0% | 20% | 30% | 40% |
|---|---|---|---|---|
| 随机森林 / 无限深单棵树 | 1.0000 | 1.0000 | 1.0000 | 1.0000 💀 |
| 深度限制树 | 0.8442 | 0.6913 | 0.6228 | 0.5481 |
| 逻辑回归 | 0.7665 | 0.6342 | 0.5680 | 0.5042 |
💀 这张表值得单独记一条规矩: 在有噪声的数据上,「训练准确率 100%」不是好消息,是"它把 40% 的错标签也背下来了"。 记忆化(memorization)就长这样: 只要模型的容量够,它总能给每一条离谱的标签单独开一个小房间。 ⭐ 判据:训练准确率明显高于「1 − 你估计的噪声率」,就说明它在记噪声。 上面 40% 那一列,健康的上限应该在 0.6 附近,而两棵树都是 1.0。
为什么随机森林能扛住而单棵树不能:森林里每棵树只看到 bootstrap 的一部分数据, 一条错标签平均只影响 63% 的树,最后多数投票时它被淹掉了。 这条推论可以直接用:
| 抗噪的 | 不抗噪的 |
|---|---|
| 集成 + 投票/平均(RF、bagging)⭐ | 单模型、尤其是无限深的树 |
| 容量受限(限深、限叶子、强 L2) | 容量远大于数据量的网络 |
| 早停(噪声总是在后期才被拟合)⭐⭐ | 训到 loss 收敛为止 |
| 标签平滑、mixup、鲁棒损失(GCE) | 纯交叉熵 + 高学习率长训练 |
⭐ "早停"是抗标签噪声性价比最高的一招,而且是免费的: 神经网络的学习是有顺序的 —— 先学干净样本里的规律,后背错标签。 所以验证曲线通常「先涨到峰值,再缓慢下滑」, 那个峰值点就是"干净规律学完了、开始记噪声了"的分界 (ML 基础 10 · 正则化全家桶)。
⚠️ 但上面这些结论只对随机(对称)噪声成立。 换成系统性噪声,画风完全变了:
| 噪声率 | 对称噪声:总体 / 类0召回 | 非对称噪声(只把 0 标成 1):总体 / 类0召回 |
|---|---|---|
| 10% | 0.9433 / 0.9033 | 0.9390 / 0.8681 |
| 20% | 0.9393 / 0.9025 | 0.9257 / 0.8186 |
| 30% | 0.9233 / 0.8883 | 0.9015 / 0.7339 |
| 40% | 0.8960 / 0.8553 | 0.8405 / 0.5457 💀 |
💀 注意这张表的形状:40% 的非对称噪声下,总体准确率只掉了 5.6 个百分点 (0.8960 → 0.8405,很多人会觉得"还行"), 但类 0 的召回从 0.855 塌到 0.546。 ⭐ 系统性噪声不打总体指标,它只打某一类 —— 而那一类, 往往正是你花钱建这个模型要抓的那一类(欺诈、违规、故障、疾病)。 只看总体指标的团队,对系统性标签噪声是全盲的。
🔍 三、置信学习:把可疑标签捞出来
思路只有一句:让模型自己去和标签吵架,然后看谁更可信。 关键是"模型的意见"必须是折外(out-of-fold)的 —— 否则它见过这条标签, 自然会同意它自己。
① 5 折交叉验证,拿每条样本的【折外】预测概率 p(c | x)
② 自信度 = p(给定标签),越低越可疑
③ 只有当【模型对另一个类的自信度 > 该类的平均自信度】
才判"这条标错了" ⭐ 这一步叫 confident joint
它把"模型没把握"和"模型很有把握但和标签不一致"分开
import numpy as np
from sklearn.model_selection import cross_val_predict, StratifiedKFold
from sklearn.ensemble import HistGradientBoostingClassifier
def find_label_issues(X, y, n_classes, base=None, cv=5, seed=0):
"""置信学习:返回 (可疑掩码, 模型建议的标签, 自信度)
y 必须是 0..n_classes-1 的整数标签"""
y = np.asarray(y, int)
base = base or HistGradientBoostingClassifier(random_state=seed)
# ⭐ 必须是折外概率:模型不能见过它正在评判的那条标签
proba = cross_val_predict(
base, X, y, cv=StratifiedKFold(cv, shuffle=True, random_state=seed),
method="predict_proba", n_jobs=-1)
n = len(y)
pred = proba.argmax(1)
self_conf = proba[np.arange(n), y] # 对"现有标签"的自信度
# ⭐ 每一类的阈值 = 该类样本上的平均自信度(confident joint 的核心)
thr = np.array([proba[y == c, c].mean() for c in range(n_classes)])
suspect = (pred != y) & (proba[np.arange(n), pred] > thr[pred])
return suspect, pred, self_conf
# ⭐ 用法:suspect 直接送人工重标队列;self_conf 升序排序 = 优先级
实测(12000 条,注入不同比例的噪声):
| 噪声率 | 方法 | 标出条数 | 精确率 | 召回率 |
|---|---|---|---|---|
| 5%(600 条) | 直接 disagreement | 1211 | 0.485 | 0.978 |
| confident joint | 551 | 0.846 | 0.777 | |
| 10%(1200 条) | 直接 disagreement | 1828 | 0.636 | 0.968 |
| 自信度 Top-1200 | 1200 | 0.888 | 0.888 | |
| confident joint | 1074 | 0.875 | 0.783 | |
| 20%(2400 条) | 直接 disagreement | 3115 | 0.743 | 0.965 |
| confident joint | 2156 | 0.891 | 0.801 |
⭐ 两种方法的分工很清楚,别混用: 直接 disagreement(模型预测 ≠ 标签)召回极高(0.97)但精确率低 —— 适合当送人工核查的候选池,你不介意多看一些。 confident joint 精确率 0.87–0.89 —— 适合直接动手的清单。
⚠️ 一个所有人都会踩的坑:基模型的强弱决定一切。 同一份 10% 噪声的数据,用逻辑回归(本身准确率只有 0.76)做折外概率时, confident joint 的精确率只有 0.346;换成 GBDT(准确率 0.95)之后是 0.875。 置信学习找的是"模型和标签不一致"。模型不行的时候,不一致的那个是模型。 ⭐ 规矩:基模型在干净留出集上的准确率,要明显高于「1 − 噪声率」,才有资格审标签。
🛑 读到这里可以停 —— 前半章讲完了(约 22 分钟)。 后半章还有:捞出来之后:删、改,还是重标(实跑) · 评测集里的噪声更致命(本章的重点) · 事故复盘:一次"指标涨了 2.6 个点"的灾难 · 三条可以直接加进流程的门禁 回来的时候不用重读,直接从下一节接着看就行。
🛠️ 四、捞出来之后:删、改,还是重标(实跑)
这是最容易做错的一步。三种处置的实测对比(同一份数据、同一个随机森林):
| 噪声率 | 原样训练 | 删掉可疑 | 机器自动改标 | 只把可疑的送人工重标 | 全部标对(上限) |
|---|---|---|---|---|---|
| 10% | 0.9467 | 0.9407 | 0.9403 | 0.9403 | 0.9463 |
| 20% | 0.9420 | 0.9347 | 0.9290 | 0.9415 | 0.9463 |
| 30% | 0.9270 | 0.9247 | 0.9230 | 0.9383 ⭐ | 0.9463 |
⭐ 两个反直觉但很硬的结论: ① 10% 噪声那一行,什么都不做(0.9467)比三种"清洗"都好。 因为 confident joint 的精确率是 0.875 —— 你为了删掉 940 条错标签, 顺手删掉了 134 条对的,而随机森林本来就不在乎那 940 条。 ② 机器自动改标从来没赢过。 它把"模型的偏见"直接写进了标签, 下一轮训练时,模型会在自己的偏见上再自信一次。 💀 自动改标是这一章里最危险的一个动作,它制造的是看不见的系统性噪声。
那什么时候该重标?一张判据表:
| 你的情况 | 该做什么 |
|---|---|
| 噪声 < 10%、随机、模型是集成/有正则 | ⭐ 什么都不做。实测 10% 时随机森林一分没掉 |
| 噪声随机,但模型容易记忆(深树、大网络、小数据) | 早停 + 限容量 + 标签平滑,不用重标 |
| 噪声是系统性的(集中在某一类 / 某个标注员 / 某个批次) | ⭐⭐ 必须重标,正则救不了 —— 正则假设错误是随机的 |
| 类别极不平衡,正样本很少 | 重标正样本:一条错的正样本,影响力等于几十条负样本 |
| 评测集有噪声 | ⭐⭐ 一定重标,理由见下一节 |
| 分不清是随机还是系统性 | 先抽 300 条做双人独立重标,看错误是不是集中在少数几种混淆上 |
⭐ 最省钱的组合:训练集用置信学习捞 Top-N,只送人工重标,不删不改; 评测集不用置信学习,直接重标或换一套独立标注的。 表里 30% 那一行,重标 3471 条换来 +1.13pp(0.9270 → 0.9383), 而删除和自动改标都是负收益。
💀 五、评测集里的噪声更致命(本章的重点)
前面四节讲的都是训练集。现在把噪声搬到评测集上,后果完全不是一个量级。
后果一:你的分数有天花板,而且你不知道它在哪。
一个真实水平 0.9463 的干净模型,放在带噪声的评测集上:
| 评测集噪声 | 你测出来的分数 | 这个评测集的天花板 |
|---|---|---|
| 0% | 0.9463 | 1.00 |
| 2% | 0.9263 | 0.98 |
| 5% | 0.9020 | 0.95 |
| 10% | 0.8568 | 0.90 |
| 20% | 0.7628 | 0.80 |
💀 模型一点没变,分数掉了 9 个百分点。 而你看到的现象是"模型只有 0.857,还差得远" —— 于是你去加特征、调参、换架构, 在一个上限只有 0.90 的尺子上追一个永远追不到的数。 ⭐ 这是标签噪声制造的最大浪费:不是模型变差,是研发方向被带偏。
后果二(更贵):排名翻转 —— 你会选错模型。
模拟两个真实水平很接近的模型:A = 0.900,B = 0.885(真实差 1.5 个百分点), 两者对 90% 的样本判定一致。看在不同评测集下"B 反超 A"的概率:
| 评测集噪声 | 300 条 | 1000 条 | 3000 条 |
|---|---|---|---|
| 0%(干净) | 22.6% | 7.2% | 0.4% |
| 3% | 27.4% | 12.7% | 2.5% |
| 5% | 30.4% | 15.1% | 4.0% |
| 10% | 34.9% | 21.5% | 8.3% 💀 |
💀 看最右边那一列:3000 条的评测集,干净时选错模型的概率是 0.4%; 只要评测集有 10% 的标签噪声,这个概率变成 8.3% —— 二十倍。 同时,测出来的差的标准差从 0.0058 涨到 0.0090(方差涨 2.4 倍)。 ⭐⭐ 换算一下就是:10% 的评测集标签噪声, 等于把你 3000 条的评测集缩水成了 1250 条。 你以为你在用一把 3000 条的尺子,实际手里只有 1250 条。
后果三:真实的改进被系统性打折。
同一组实验,两个模型的真实差距是 +0.0395:
| 评测集噪声 | 测出来的差 | 相当于真实差的 |
|---|---|---|
| 0% | +0.0395 | 100% |
| 5% | +0.0365 | 92% |
| 10% | +0.0336 | 85% |
| 20% | +0.0281 | 71% |
⭐ 这个缩水可以算:K 分类对称噪声下,测出的差 ≈ 真实差 × (1 − e·K/(K−1))。 后果很具体:一个真值 +2pp 的改进,在 10% 噪声的评测集上只显示 +1.7pp, 再撞上置信区间,就会被判成"没效果"然后被放弃。 💀 标签噪声不只让你选错模型,还会让你扔掉正确的方向。
后果四:同样的标注预算,花在评测集上的边际价值高一到两个数量级。
一个把上面所有账算清楚的实验 —— 训练集 10% 噪声、评测集 10% 噪声:
现状:你测出来 0.8560,真实水平是 0.9473(被低估 9.1 个百分点)
方案 A:花 1000 条预算随机修【训练】标签
→ 真实水平 0.9473 → 0.9480(+0.0007,基本白花)
→ 而且你测出来的还是 0.85,因为尺子没变
方案 B:花 400 条预算重标一小份【评测】集
→ 测出 0.9475,与真实值只差 +0.0002 ⭐⭐
→ 模型一点没变,但你第一次知道了它真正的水平
⭐⭐ 这是本章最该带走的一条: 修训练标签买的是模型的边际提升(很小),修评测标签买的是"你知不知道自己在哪"(无价)。 预算紧张时的顺序永远是:先把评测集弄干净,再谈训练集。 具体的预算分法在第 12 章。
💀 六、事故复盘:一次"指标涨了 2.6 个点"的灾难
系统:短视频平台的「引流广告」识别模型(自动下架 + 送人工复核队列)
规模:日均入审 380 万条,正样本率约 0.9%
标注:外包团队,训练集 42 万条、评测集 3 万条
⭐ 同一批人、同一个批次、从同一个池子里随机切出来的
发生了什么
第 3 季度换了标注供应商。新团队对指南里的一条边界理解反了: 「简介里留了联系方式,但视频内容本身与推广无关」—— 旧指南写的是不算引流广告,新团队一律标成算。 这类样本占全部正样本的 23%。
| 时间 | 事件 |
|---|---|
| 第 1 周 | 新供应商接手,42 万条训练数据 + 3 万条评测数据在同一批次产出 |
| 第 5 周 | 新模型训练完成,评测集 F1 从 0.881 涨到 0.907(+2.6pp) ⭐ 全组认为是季度三个优化的功劳 |
| 第 6 周 | 评审通过,全量上线 |
| 第 8 周 | 申诉量从日均 220 条涨到 1,940 条 —— 被归因为"新社区政策让用户更敏感" |
| 第 12 周 | 一个头部创作者公开发帖,运营找过来,才开始查标签 |
为什么没被发现(四条,第一条是根)
① 评测集和训练集【同一批人、同一个批次】标的 ⭐⭐ 根因
→ 模型学到的偏差和评测集里的偏差【完全一致】
→ 模型越"错得像标注员",评测分数越高
💀 这套评测集在结构上已经没有能力发现这个问题
② F1 涨 2.6 个点,正好落在"这季度做了三个优化"的预期里
—— 指标符合预期时,没人会去质疑指标本身
③ 抽检只抽【模型判为正、且置信度低】的样本
💀 而这批误判的置信度【很高】——模型学得很好,它很自信
⭐ 系统性标签噪声恰恰藏在模型最自信的地方
④ 只看总体 F1,没按"指南的每一条边界规则"分桶
—— 见第二节:系统性噪声不打总体指标
代价
从上线到定位 27 天
误下架内容 约 11.6 万条
申诉成功率 87% ← 反过来证明这批下架确实是错的
公关 3 个头部创作者公开发声,平台发公告 + 补偿
返工 重标评测集 3 万条 ¥8.4 万 / 11 天
重标训练集 9.7 万条 ¥27 万 / 5 周
⭐ 但最贵的一项是:
第 3 季度基于这套评测集做的 14 次实验,结论【全部作废】
该补什么
| 缺失 | 补上之后 |
|---|---|
| 评测集和训练集同源同批 | ⭐⭐ 评测集必须独立标注:不同的人、不同的时间、更严的流程、多人交叉 + 仲裁 |
| 没有黄金集 | 留一份 500–1000 条的黄金集:资深标注员 3 人一致才收;换供应商、换指南、换批次时先跑它 |
| 没有标注员级别的监控 | 按标注员 / 批次 / 周统计各类的正样本率,偏离 > 2σ 报警(第 10 章) |
| 抽检只抽低置信度样本 | ⭐ 抽检必须包含高置信度的正样本 —— 系统性噪声就藏在那里 |
| 指标只看总体 F1 | 按指南的每一条边界规则分桶看;总体涨、某个桶塌是最典型的形状 |
| 指南变更没有留痕 | 指南进版本库,每次修订跑一次黄金集(第 17 章) |
💀 这个事故一句话总结: 当评测集和训练集共享同一个标注偏差时,评测集测的不是"模型对不对", 是"模型有没有学会和标注员犯一样的错"。 ⭐ 而模型学得越好,这个分数就越高 —— 指标和真相是反向的。
🧰 七、三条可以直接加进流程的门禁
- ① 评测集独立性:标注人员与训练集重叠为 0、不同批次产出、做过多人交叉 + 仲裁 ⭐⭐
- ② 噪声率估计(每季度):从评测集抽 300 条双人独立重标,把「本次评测天花板 ≈ 1 − e」写进模型报告 ⭐
- ③ 记忆化体检(每次训练):训练准确率明显高于
1 − 估计噪声率= 它在背噪声
估噪声率的最小实现(只需要一份双标数据):
import numpy as np
from collections import Counter
def noise_rate_from_double_labeling(orig, ann_a, ann_b):
"""orig: 线上在用的标签 ann_a/ann_b: 两位标注员独立重标的结果
返回:标注员之间的不一致率(噪声下界)、以及原标签的估计错误率"""
orig, a, b = map(lambda v: np.asarray(v), (orig, ann_a, ann_b))
disagree = (a != b).mean() # ⭐ 两人都不一致 = 这批题本身就难
both_agree = a == b
# 只在两位标注员一致的那些题上,评判原标签对不对(这时可以近似当作真值)
err = (orig[both_agree] != a[both_agree]).mean()
# ⭐ 最有用的一列:错误集中在哪几种混淆上
conf = Counter((int(o), int(t)) for o, t in
zip(orig[both_agree], a[both_agree]) if o != t)
return {
"标注员不一致率": round(float(disagree), 4),
"原标签估计错误率": round(float(err), 4),
"评测天花板": round(1 - float(err), 4), # ⭐ 写进模型报告的那个数
"Top5 混淆": conf.most_common(5), # ⭐ 只有 1-2 种 = 系统性噪声
}
# 判读:Top5 混淆高度集中在一两对类别上 → 系统性噪声 → 改指南 + 重标,别加正则
⭐ "Top5 混淆"这一列是本章最实用的一个输出: 错误均匀分布在各种类别对上 = 随机噪声,加正则、用集成就行; 错误集中在一两对上 = 指南有洞,只能改指南 + 重标。 这一个输出就能替你做完第四节那张判据表里最难的那个判断。
🔗 这一章连到哪里
| 去哪 | 为什么 |
|---|---|
| 第 10 章 · 标注一致性 | 噪声的上游:一致性指标(Kappa 等)就是本章"噪声率"的另一面 |
| 第 12 章 · 标注预算与主动学习 | 本章第五节说"先修评测集",那一章讲这笔钱具体怎么切 |
| 第 13 章 · 评测集也是数据 | ⭐⭐ 评测集噪声只是评测集问题的一种,那一章是评测方法论的总入口 |
| 第 7 章 · 异常值是错还是真 | 同一个判断的另一半:特征侧的"错还是真",本章是标签侧的 |
| ML 基础 10 · 正则化全家桶 | 早停、标签平滑、mixup 的具体做法 —— 抗随机噪声的主力工具 |
| Kaggle 02 · 训练策略与正则化 | 竞赛视角的抗噪训练:鲁棒损失、软标签、伪标签的噪声控制 |
| 模型上线之后 07 · 没有标签怎么发现退化 | 线上根本拿不到干净标签时,怎么估计模型真实水平 |
✅ 检查点
- 公开数据集的标签错误率大概是什么量级?那份核查最重要的第二个结论是什么?
- 随机噪声和系统性噪声该怎么区分?为什么这个区分是本章所有判断的分水岭?
- 实测里 40% 噪声下,随机森林和无限深单棵树的准确率各是多少?差别的原因是什么?
- 为什么说「训练准确率 100%」在有噪声的数据上是坏消息?判据怎么写?
- 非对称噪声那张表里,40% 时总体准确率掉了多少、类 0 召回掉了多少?这说明什么?
- 置信学习的三步是什么?为什么折外概率是必须的?基模型不够强会怎样(给数字)?
- 「删掉可疑 / 机器自动改标 / 送人工重标」三种处置,实测哪个最好、哪个最危险?10% 噪声时最该做什么?
- 评测集 10% 噪声会带来哪四个后果?其中"3000 条缩水成 1250 条"是怎么算出来的?
- 修 1000 条训练标签和修 400 条评测标签,各买到了什么?
- 那个短视频的事故里,根因是什么?为什么模型学得越好、评测分数越高?抽检为什么没抓到?
👀 答案
- 从 MNIST 的 ~0.15% 到 QuickDraw 的 ~10%,ImageNet 验证集约 5.8%、CIFAR-100 约 5.9%,十个测试集平均 3% 左右。第二个结论更重要:修正标签之后模型排名会变 —— 原始标签下更强的大模型会输给更小的模型。业务数据只会更差:外包多分类 5%–15%,主观任务 15%–30%。
- 随机噪声(手滑、疲劳)各类之间大致对称;系统性噪声(指南理解偏差、某个标注员、某个批次)只往一个方向偏。分水岭是因为:正则、集成、早停这些手段的前提假设就是"错误是随机的",对系统性噪声完全无效,只能改指南 + 重标。
- 随机森林 0.9085(只掉 3.8pp),无限深单棵树 0.5407(掉 32pp)。原因是森林里每棵树只看到 bootstrap 的一部分,一条错标签平均只影响 63% 的树,多数投票时被淹掉;单棵深树则可以给每一条错标签单独开一个叶子。
- 因为它意味着模型把错标签也背下来了(记忆化)。判据:训练准确率明显高于「1 − 估计噪声率」就说明它在记噪声 —— 40% 噪声下健康上限约 0.6,而随机森林和深树都是 1.0000。
- 总体只掉 5.6pp(0.8960 → 0.8405),类 0 召回从 0.8553 塌到 0.5457。说明系统性噪声不打总体指标,只打某一类 —— 而那一类往往正是你要抓的那一类(欺诈、违规、疾病)。只看总体指标的团队对它是全盲的。
- ①5 折交叉验证拿折外预测概率 ②自信度 = p(给定标签),越低越可疑 ③confident joint:只有当模型对另一个类的自信度高过该类平均自信度时才判"标错"。折外是必须的,因为模型见过这条标签就会同意它自己。基模型不够强时:逻辑回归(准确率 0.76)做基模型,confident joint 精确率只有 0.346;换成 GBDT(0.95)后是 0.875 —— 模型不行时,不一致的那个是模型。
- 送人工重标最好(30% 噪声:0.9270 → 0.9383),机器自动改标最危险(它把模型的偏见写进标签,制造看不见的系统性噪声,实测从没赢过)。10% 噪声时什么都不做最好(0.9467,比三种清洗都高)—— 因为 confident joint 精确率 0.875,你会连带删掉对的样本,而随机森林本来就不在乎那些噪声。
- ①分数有天花板(真实 0.9463 的模型在 10% 噪声评测集上只测出 0.8568,天花板 0.90)②排名翻转(3000 条评测集,干净时选错概率 0.4%,10% 噪声时 8.3%,二十倍)③真实改进被打折(真差 0.0395 → 测出 0.0336,只剩 85%;20% 噪声时剩 71%)④预算的边际价值错配。"缩水"是这样算的:测出的差的标准差从 0.0058 涨到 0.0090,方差涨 2.4 倍,而方差和 n 成反比,所以 3000/2.4 ≈ 1250 条。
- 修 1000 条训练标签:真实水平 0.9473 → 0.9480,+0.0007,基本白花,而且你测出来的还是 0.85。修 400 条评测标签:测出 0.9475,和真实值只差 +0.0002 —— 模型没变,但你第一次知道了它真正的水平。⭐ 修训练标签买的是模型的边际提升,修评测标签买的是"你知不知道自己在哪"。
- 根因是评测集和训练集由同一批人、同一批次标注,模型学到的偏差和评测集里的偏差完全一致 —— 模型越"错得像标注员",评测分数越高,指标和真相是反向的。抽检没抓到是因为只抽了置信度低的样本,而这批误判置信度很高 —— ⭐ 系统性噪声恰恰藏在模型最自信的地方。代价:27 天定位、误下架 11.6 万条、申诉成功率 87%、返工 ¥35 万,以及当季 14 次实验结论全部作废。
🛑 可以停在这里
⚡ 走神救援
⭐⭐标签本来就有错:公开数据集实测 MNIST ~0.15%、ImageNet 验证集 ~5.8%、CIFAR-100 ~5.9%、QuickDraw ~10%,十个测试集平均 3% 左右;业务数据外包多分类 5–15%,主观任务 15–30%。💀那份核查更重要的第二结论是:修正标签后模型排名会变——原始标签下更强的大模型会输给更小的模型。⭐必须先分两种噪声:随机噪声(手滑疲劳,集成/正则/早停扛得住)和系统性噪声(指南理解偏差,⚠️正则完全无效,因为正则假设错误是随机的)。训练侧实跑(3 分类、干净测试集):40% 噪声下随机森林只掉 3.8pp(0.9463→0.9085)而无限深单棵树掉 32pp(0.8610→0.5407)——差别在于森林里一条错标签只影响 63% 的树,投票时被淹掉;💀而两者的训练准确率在 40% 噪声下都还是 1.0000,⭐「训练准确率 100%」在有噪声的数据上不是好消息,判据是「训练准确率明显高于 1−噪声率 = 它在背噪声」。抗噪排序:集成投票 > 早停(⭐最便宜,因为网络总是先学规律后背噪声,验证曲线的峰值就是分界)> 限容量/标签平滑/鲁棒损失。⚠️但这些只对对称噪声成立:非对称噪声(只把类0标成类1)40% 时总体只掉 5.6pp 而类0召回从 0.8553 塌到 0.5457——⭐系统性噪声不打总体指标只打某一类,而那一类正是你要抓的那一类。置信学习三步:①5 折折外概率(见过标签就会同意自己)②自信度 = p(给定标签) ③confident joint:只有模型对另一个类的自信度高过该类平均自信度才判错标。实测 10% 噪声:disagreement 召回 0.968 精确率 0.636(当候选池),confident joint 精确率 0.875 召回 0.783(当行动清单)。⚠️基模型强弱决定一切:逻辑回归(0.76)做基模型精确率只有 0.346,换 GBDT(0.95)后 0.875——模型不行时不一致的是模型。捞出来之后怎么办(实跑):10% 噪声时⭐什么都不做(0.9467)比删掉可疑(0.9407)、机器改标(0.9403)都好;30% 噪声时只把可疑的送人工重标最好(0.9270→0.9383);💀机器自动改标从来没赢过,它把模型的偏见写进标签,制造看不见的系统性噪声。⭐最省钱的组合:训练集用置信学习捞 Top-N 但只送人工重标不删不改;评测集不用置信学习,直接重标或换独立标注的一套。💀💀评测集噪声更致命,四个后果:①天花板——真实 0.9463 的模型在 10% 噪声评测集上只测出 0.8568(天花板 0.90),你会以为模型不行然后去做无用优化;②排名翻转——真实差 1.5pp 的两个模型,3000 条评测集干净时选错概率 0.4%,10% 噪声时变 8.3%(二十倍),⭐⭐方差涨 2.4 倍 = 3000 条的评测集缩水成 1250 条;③真改进被打折——真差 0.0395 在 10% 噪声下只显示 0.0336(85%),20% 噪声下 71%,公式 ≈ 真实差×(1−e·K/(K−1)),💀一个真值 +2pp 的改进会被判成"没效果"然后被放弃;④⭐⭐预算错配——花 1000 条修训练标签只涨 +0.0007(白花),花 400 条修评测标签就把测量偏差从 −9.1pp 修到 +0.02pp:修训练标签买模型的边际提升,修评测标签买"你知不知道自己在哪",预算紧张时永远先修评测集。💀事故:短视频引流广告识别,换供应商后新团队把一条边界理解反了(占正样本 23%),而评测集和训练集是同一批人同一批次标的 ⭐⭐,于是模型越"错得像标注员",评测 F1 越高(0.881→0.907,+2.6pp)——指标和真相是反向的。上线后误下架 11.6 万条、申诉从 220 涨到 1940 条/天、申诉成功率 87%、27 天才定位。没被发现的三条:抽检只抽低置信度样本而这批误判置信度很高(⭐系统性噪声藏在模型最自信的地方)、只看总体 F1 没按指南边界分桶、+2.6pp 正好落在预期里。代价还包括当季 14 次实验结论全部作废。改法核心:评测集必须独立标注(不同的人、不同的时间、多人交叉+仲裁)+ 留一份 500–1000 条的黄金集,换供应商/改指南时先跑它。最后三条门禁:评测集独立性检查、每季度抽 300 条双标估噪声率(写进报告:本次评测天花板 = 1−e)、每次训练做记忆化体检;⭐ 双标输出里最有用的是「Top5 混淆」——均匀分布=随机噪声可以加正则,集中在一两对上=指南有洞只能重标。
下一节 👉 12-标注预算与主动学习.md