数据泄漏
模型借用了实际预测时不该知道的信息,成绩可能因此虚高。
用过去的完整记录来学习,但每项输入都要问:在当时做预测的那一刻,拿得到吗?
输入和答案要分开:历史记录中的“是否故障”是训练时用来对答案的标签;机龄等用来预测的数据才是输入(特征)。
同一批设备,同一场“考试”
300 条教学记录:200 条用来学习(训练集),另留 100 条打分(测试集)。
只用现在能拿到的数据
机龄、振动、温度、压力波动
再加入下周的维修时长
多了一条未来才有的线索
AUC 看区分能力:越接近 1,越能把会故障的设备排在前面;0.5 约等于随机排序。它不是准确率。
展开 ROC 曲线(可选)
每条曲线都来自上面的 100 条测试记录。横轴看误报,纵轴看查出;虚线表示随机排序。
换一台现在刚来的设备
机龄、振动、温度等可以测;下周的维修还没发生,维修时长未知。
记住这条判断,再认识其他泄漏
表里有这一列,不代表预测时就能用。先确定预测时点,再核对每项输入的来源和产生时间。
本页的训练设备与测试设备已经分开,泄漏仍会发生,因为输入里带着未来信息。其他常见泄漏还包括:同一对象的相关记录跨组,以及先用全部数据学习填补或标准化规则、再划分。
概念参考:scikit-learn 数据泄漏说明 ↗文字版:数据泄漏在做什么
数据泄漏是指模型在训练时用到了「真正做预测的那一刻拿不到」的信息。它最危险的地方在于:模型不会报错,成绩还特别好看,一直要等到上线之后才发现全不对。这一页用同一批设备做对照实验,让你看见这个虚高是怎么来的。
画面上正在发生什么
左右两个模型用的是同一批设备、同一次划分、同一个算法,唯一的差别是右边多了一列「下周的维修时长」。这一列在真正要做预测的那一刻根本不存在——设备还没坏,维修还没发生。但它和「会不会故障」高度相关,于是模型的 AUC 立刻蹿上去。
把这个勾取消再看一次:AUC 掉回一个平实的水平。那个平实的数字才是这个模型的真实能力。判断标准只有一句话:在当时做预测的那一刻,这个数据拿得到吗?
什么时候它会骗你
- 未来信息泄漏最常见。「住院总天数」用来预测住院时长、「退款金额」用来预测是否退款、「维修记录」用来预测是否故障——这些列都是结果的一部分,不是预测它的线索。
- 预处理泄漏最隐蔽。在划分训练测试集之前做标准化、缺失值填补、特征选择或过采样,测试集的信息就已经通过统计量渗进了训练过程。正确做法是把所有预处理放进只在训练集上拟合的流水线里。
- 同源样本泄漏最容易被忽略。同一个病人的多次就诊、同一张图像的多个裁剪、同一个用户的多条记录,如果被分到训练集和测试集两边,模型认出的是这个个体,不是这类个体。
常见问题
- 怎么判断一个特征算不算泄漏?
- 问一句:在真实上线、需要做出这个预测的那一刻,这个值已经产生了吗?拿不到的就是泄漏。另一个信号是这个特征的重要性高得离谱、或者去掉它成绩就崩——这类特征值得逐个追查它的产生时间。
- 模型成绩好到什么程度该起疑?
- 没有绝对界限,但在真实业务数据上 AUC 超过 0.95、准确率超过 95%,通常先怀疑泄漏而不是先庆祝。尤其是当这个问题本身公认很难、或者同类研究报告的成绩明显更低时。
- 已经发现泄漏了,怎么补救?
- 删掉泄漏特征重跑是第一步,但往往不够——要顺着这个特征的产生流程往回查,看还有没有别的列携带同样的信息。如果泄漏发生在划分或预处理环节,整条流水线都要重做,之前所有基于这批结果的结论都不能用。
本页使用 300 条教学合成记录(200 条训练、100 条测试),两个 AUC 由页面用逻辑回归实时计算,不代表真实设备的故障预测性能。