数据泄漏防御 — 线上暴跌的头号嫌疑人
R — 原文 (Reading)
Data leakage is the creation of unexpected additional information in the training set, allowing a model to make unrealistically good predictions.(转述)
— 转述自 Daniel Kaufman 等, "Leakage and the reproducibility crisis in ML-based science", Patterns 2023(来源性质:业界对泄漏的系统化定义文献)
The general rule is this: apply every transformation that depends on the data distribution to train only, then propagate to validation/test.(转述)
— 转述自 scikit-learn 官方文档 "Common pitfalls: data leakage" 一节(来源性质:事实标准库文档)
来源说明: 本 skill 属批C"工程实践共识"系列——《机器学习》(西瓜书)不含工程落地内容, 其最接近的锚点是第2章"测试集必须与训练集互斥"的出题类比;本 skill 把这一原则从"评估集 选择"扩展到整条数据管道。R 段改引业界公开文献并标注来源性质;凡无法保证逐字精确处一律标(转述)。
I — 方法论骨架 (Interpretation)
泄漏 = 让模型在训练时接触了"考试时拿不到的信息"。它不产生真知识,只产生虚高的指标,且几乎总是上线后才暴露。按发生位置分三大类型:
- 特征-目标泄漏:某个特征本身就是目标(或目标的代理)——预测"是否流失"却放进了"注销日期",预测住院时长放进了出院诊断编码。典型信号:单一特征重要性高得反常。
- 训练-测试污染:测试信息混进训练过程——重复样本跨集合存在、按时间问题却随机 shuffle 后划分、测试集参与了特征选择或超参搜索。
- 过程泄漏:顺序错误让统计量穿越边界——先全量归一化/填充再划分、目标编码在全量上 fit、SMOTE 重采样放在划分之前。每个变换器都是一个潜在的泄漏点。
防御的元原则只有一条:一切依赖数据分布的计算(均值、分位数、分箱边界、编码映射、重采样、特征选择),只在训练折内执行,再 transform 到其余部分。检测靠三组信号:线下暴涨线上暴跌、单特征重要性异常、极小的模型间差距(大家都在拟合同一个泄漏源)。泄漏的代价是不对称的——它不会被训练损失发现,只能靠流程纪律和怀疑精神拦截。
A1 — 业界公开案例 (Past Application)
注: 西瓜书无对应案例,本节用业界公开案例充当类比素材;书内仅提供原则回声。
案例 1: Netflix Prize 的残留隐变量泄漏 (Bell & Korbel, 2007; 社区复盘)
- 问题: 参赛者普遍用"用户-电影"评分矩阵的隐特征做特征,但不少队伍把整个评分历史(含待预测时间点之后的部分)一起分解。
- 方法论的使用: 赛后复盘确认部分高分方案把未来评分信息带进了过去时点的预测,属于典型的时序穿越型特征-目标泄漏。
- 结论: 竞赛排行榜第一名的方案未必能原样上线;时序任务必须按时间切并审计每列信息的可得时点。
- 结果: "Netflix 泄漏教训"成为推荐系统与竞赛社区反复引用的经典案例。
案例 2: 医疗 ML 的"治疗即特征"事故 (Kaufman et al., 2012)
- 问题: 用 ICU 数据预测患者结局,特征里混入了吸氧量、用药等"因为病重才有的干预措施"。
- 方法论的使用: 治疗变量是结局的果而非因,模型靠它们走捷径拿到漂亮 AUC;识别方法是逐特征质询"该值在预测时点是否已产生"。
- 结论: 临床预测模型的特征必须满足"预测时点可得性",否则是在预测"病历写得好不好"。
- 结果: 该文成为医学 AI 文献中泄漏讨论的标准引文,可得性质询被写进多家医院的建模规范。
案例 3: 书内原则回声——10 道练习题的考试类比 (c2)
- 问题: 怎么向初学者解释为什么测试集必须与训练集互斥?
- 方法论的使用: 原书用"老师用练习原题考试,成绩无法反映学习效果"的类比立起"见过答案的评估不算数"的原则。
- 结论: 泄漏防御是该原则的全管道推广版——不仅考卷不能泄题,连"平时作业的平均分"(统计量、编码表、特征选择)都不能借给考场。
- 结果: 工程界把"折内拟合、折外 transform"固化为 sklearn Pipeline 与各类框架的默认纪律。
A2 — 触发场景 (Future Trigger) ★
用户会在什么情境下需要这个 skill?
- 用户报告"交叉验证 0.95,一上线/换一批数据就掉到 0.7",线下线上严重脱节。
- 某个特征重要性一骑绝尘(如占比 80%+),用户拿不准该高兴还是该害怕。
- 用户在写预处理管道:问归一化/缺失填充/SMOTE/target encoding 应该放在切分前还是切分后。
- 时序任务里用户随手
train_test_split(shuffle=True),或验证集参与了特征选择/调参后又被当作最终评估。 - 复现别人论文/接手同事代码,怀疑结果好得不真实,要一次系统性的找漏排查。
语言信号 (用户的话里出现这些就应激活)
- "泄漏了吗" / "data leakage" / "target leakage 目标泄漏"
- "线下虚高/线上暴跌" / "CV 分数很高但 test 很差" / "offline-online gap"
- "这个特征重要性也太高了吧" / "好得可疑" / "too good to be true" / "suspiciously accurate"
- "归一化应该在划分前还是划分后" / "shuffle 了还能按时间切吗" / "SMOTE 放哪一步"
- "帮我查一下这段代码有没有泄漏" / "audit my pipeline"
与相邻 skill 的区分
- 与
ml-pitfall-audit的区别: audit 是实验前的六问前提整体审查,泄漏只是其中一问、点到为止;本 skill 是泄漏专项深挖——类型学、检测信号、逐项清单。六问审完仍存疑的泄漏问题移交本 skill。 - 与
ml-evaluation-design的区别: 那是正面设计切分方案与比较协议;本 skill 是对已成管道的反面审计。设计在前、审计在后;本 skill 步骤 0 直接复用其划分结论。 - 与
ml-feature-engineering的区别: 那是造特征的决策手册(怎么造);本 skill 是验管道的安检仪(造的过程有没有漏)。其步骤 7 的异常重要性是本 skill 的常客。 - 与
ml-diagnosis的区别: 效果不好(偏低)归它;效果"太好"(偏高且不可信)归本 skill。
E — 可执行步骤 (Execution)
当 skill 被激活后, agent 按上线前泄漏检查清单执行:
第 0 步: 取得划分基线
- 向用户确认当前训练/验证/测试(或 CV 折)如何划分、是否时序任务、shuffle 是否开启。
- 完成标准: 一句话写出"数据是什么 + 怎么切的";无划分方案 → 移交 ml-evaluation-design。
- 判停条件: 若用户只是泛泛问"什么是数据泄漏"而无具体项目 → 直接讲解三大类型即可,不走清单。
类型一扫描: 特征-目标泄漏
- 逐列质询头部重要性与全部候选特征:"该值的计算范围是否完全落在预测时点之前?它是不是目标的结果/代理?"重点排查 ID、状态类、事后登记类字段。
- 完成标准: 每个入模特征获得 可得性 ✓/✗ 标记;✗ 或存疑者列出处置建议(剔除/滞后化)。
类型二扫描: 训练-测试污染
- 查四项: 重复/近重复样本是否跨集合;时序是否误用随机划分;测试集是否参与过特征选择、阈值选择、超参搜索;同组实体(同一患者/用户多行)是否被拆进不同集合而需要 GroupKFold。
- 完成标准: 四项各留一行结论(通过/违规+修法)。
类型三扫描: 过程泄漏
- 按管道顺序核对每个变换器的拟合范围: 归一化/填充统计量、分箱边界、目标编码映射、重采样(SMOTE 只许在训练折内)、特征选择的样本范围。凡"fit 在全量、transform 在划分后"即为违规。
- 完成标准: 输出一张"变换器 × 拟合范围"对照表;违规项给出 Pipeline/折外改法。
检测信号核对
- 问三个问题: 线下-线上(或新旧数据)差距多大?头号特征重要性占比是否异常?换不同模型族分数是否挤在一起?
- 完成标准: 三问各有数字/证据;任一命中 → 回到步骤 2-4 定位泄漏源。
- 判停条件: 清单全过且三问均阴性 → 出具"未发现泄漏"结论并注明检查范围与局限。
整改与复核
- 修复违规项 → 重跑管道 → 对比修复前后分数:真实泄漏修复后线下分数应当下降到可信区间。
- 完成标准: 输出前后对照(分数变化 + 定位到的泄漏源清单);提醒用户"分数下降是修复成功的标志,不是退步"。
B — 边界 (Boundary) ★
不要在以下情况使用此 skill
- 手头没有代码/管道可查,只有一句"我觉得有泄漏":审计需要具体变换器与划分方式,否则只能科普类型学,别假装做了审计。
- 问题实为分布漂移(训练与线上的数据分布本身变了):那不是泄漏——训练时并未接触未来信息,是"未来不再像过去";处置方向是监控与再训练,不是查管道。
- 效果偏低的常规诊断(欠拟合/过拟合归因):那是 ml-diagnosis 的地盘;泄漏通常造成的是虚高而非偏低。
业界警告的失败模式
- "线下涨了就是变好了": 泄漏的每一处修改都会让线下分数上涨,这正是它阴险之处——没有护栏的迭代会一路滑向自欺。
- 只信一种验证: 单次划分 + 单一指标挡不住泄漏;需交叉验证、时间外样本(OOF/holdout by time)多重印证。
- Pipeline 只包住模型不包住变换器: 把归一化留在 Pipeline 外等于白包——scikit-learn 文档列为头号 pitfall。
- 修复后舍不得降分: 明知泄漏却保留"因为它让 LB 更高",是把竞赛技巧误用到生产。
作者盲点 / 时代局限 (为何需要本 skill)
- 西瓜书的工程落地环节不在书内(BOOK_OVERVIEW 批判: "'评估'止步于离线指标"、不讲线上-线下一致性)——书中"测试集互斥"原则只覆盖考卷本身,不覆盖统计量穿越、编码器泄漏等过程泄漏;本 skill 即对该盲点的补全。
- 书中 i.i.d. 前提使"时序不能乱 shuffle""实体分组不得拆散"这类分组/时间结构问题完全缺位。
- 因果视角缺席(批判节原文)意味着书中无从讨论"特征是目标的果"这类因果性泄漏,本 skill 的可得性质询是其替代防线。
容易混淆的邻近方法论
- 过拟合 ≠ 泄漏: 过拟合是记住了训练集的噪声(方差问题,ml-diagnosis 管辖);泄漏是训练时拿到了不该拿的信息(流程缺陷)。症状都可表现为泛化差,但处方一个是正则化、一个是改管道。
- 分布漂移 ≠ 泄漏: 见上"不要使用"第三条——判据是有没有信息穿越边界。
- 作弊式调参(测试集调参): 它是训练-测试污染的一种,但常被误认为"只是多试了几次";每次对着测试集改设计都是一次隐性训练。
相关 skills
- contrasts-with: ml-pitfall-audit(专项深挖 vs 六问总审), ml-diagnosis(虚高 vs 偏低)
- depends-on: ml-evaluation-design(划分基线由其提供)
- composes-with: ml-feature-engineering(编码器安全用法 ↔ 异常重要性深查), ml-experiment-tracking(版本化管道便于审计追溯)
审计信息
- 验证通过: 批C·工程实践共识单元(书内仅 c2 提供原则回声);V1 ✓ / V2 ✓ / V3 ✓ 待阶段 3 统一复核
- 测试通过率: 待阶段 3 测试 (详见 test-prompts.json)
- skill_version: 0.0.1
- 蒸馏时间: 2026-08-24