机器学习 · 互动实验室

数据泄漏

模型借用了实际预测时不该知道的信息,成绩可能因此虚高。

01看可用数据02看历史成绩03试用新设备
看这里
本页演示 · 未来信息泄漏现在,要预测设备下周会不会故障。

用过去的完整记录来学习,但每项输入都要问:在当时做预测的那一刻,拿得到吗?

输入和答案要分开:历史记录中的“是否故障”是训练时用来对答案的标签;机龄等用来预测的数据才是输入(特征)。

对照实验

同一批设备,同一场“考试”

300 条教学记录:200 条用来学习(训练集),另留 100 条打分(测试集)。

只用现在能拿到的数据

机龄、振动、温度、压力波动

—AUC
在同一批测试设备上计算

再加入下周的维修时长

多了一条未来才有的线索

—AUC
下一步,看这条线索怎样影响成绩

AUC 看区分能力:越接近 1,越能把会故障的设备排在前面;0.5 约等于随机排序。它不是准确率。

点击“看历史成绩”,比较两个模型。
记住这条判断,再认识其他泄漏

表里有这一列,不代表预测时就能用。先确定预测时点,再核对每项输入的来源和产生时间。

本页的训练设备与测试设备已经分开,泄漏仍会发生,因为输入里带着未来信息。其他常见泄漏还包括:同一对象的相关记录跨组,以及先用全部数据学习填补或标准化规则、再划分。

概念参考:scikit-learn 数据泄漏说明 ↗
现在可用的输入未来才有的线索教学合成数据 · 逻辑回归实时计算 · 不代表真实设备性能

文字版:数据泄漏在做什么

数据泄漏是指模型在训练时用到了「真正做预测的那一刻拿不到」的信息。它最危险的地方在于:模型不会报错,成绩还特别好看,一直要等到上线之后才发现全不对。这一页用同一批设备做对照实验,让你看见这个虚高是怎么来的。

画面上正在发生什么

左右两个模型用的是同一批设备、同一次划分、同一个算法,唯一的差别是右边多了一列「下周的维修时长」。这一列在真正要做预测的那一刻根本不存在——设备还没坏,维修还没发生。但它和「会不会故障」高度相关,于是模型的 AUC 立刻蹿上去。

把这个勾取消再看一次:AUC 掉回一个平实的水平。那个平实的数字才是这个模型的真实能力。判断标准只有一句话:在当时做预测的那一刻,这个数据拿得到吗?

什么时候它会骗你

  • 未来信息泄漏最常见。「住院总天数」用来预测住院时长、「退款金额」用来预测是否退款、「维修记录」用来预测是否故障——这些列都是结果的一部分,不是预测它的线索。
  • 预处理泄漏最隐蔽。在划分训练测试集之前做标准化、缺失值填补、特征选择或过采样,测试集的信息就已经通过统计量渗进了训练过程。正确做法是把所有预处理放进只在训练集上拟合的流水线里。
  • 同源样本泄漏最容易被忽略。同一个病人的多次就诊、同一张图像的多个裁剪、同一个用户的多条记录,如果被分到训练集和测试集两边,模型认出的是这个个体,不是这类个体。

常见问题

怎么判断一个特征算不算泄漏?
问一句:在真实上线、需要做出这个预测的那一刻,这个值已经产生了吗?拿不到的就是泄漏。另一个信号是这个特征的重要性高得离谱、或者去掉它成绩就崩——这类特征值得逐个追查它的产生时间。
模型成绩好到什么程度该起疑?
没有绝对界限,但在真实业务数据上 AUC 超过 0.95、准确率超过 95%,通常先怀疑泄漏而不是先庆祝。尤其是当这个问题本身公认很难、或者同类研究报告的成绩明显更低时。
已经发现泄漏了,怎么补救?
删掉泄漏特征重跑是第一步,但往往不够——要顺着这个特征的产生流程往回查,看还有没有别的列携带同样的信息。如果泄漏发生在划分或预处理环节,整条流水线都要重做,之前所有基于这批结果的结论都不能用。

本页使用 300 条教学合成记录(200 条训练、100 条测试),两个 AUC 由页面用逻辑回归实时计算,不代表真实设备的故障预测性能。

作者与维护:覃秉丰 · 关于覃秉丰 · 引用本页讲解

继续学习