单位 10 / 11

数据泄露和可重复性:无声的灾难和纪律

收益:

  • 能够识别数据泄漏的类型(目标、时间、预处理、分组行)并查询“好得令人难以置信”分数作为警报
  • 能够通过早期分离测试装置、管道和正确划分(按时间顺序/分组)来防止泄漏
  • 能够通过固定种子、版本控制和删除手动步骤使分析具有可重复性

在数据科学中有两个错误浪费了最多的精力,而且它们都是阴险的,因为它们会在一切“看起来都很好”的时候导致灾难。首先是数据泄漏:该模型在测试集上运行良好,但在生产中崩溃。第二个是不可重复性:六个月后进行分析,得到完全不同的结果。本单元致力于深入了解并避免这两个陷阱。人工智能可以增加这两种风险(快速生成、提示隐藏的泄漏、使您更容易采取手动步骤),但如果使用得当,也可以减少风险。区别在于纪律。

数据泄露:透视模型

数据泄漏是指模型在训练过程中看到实际预测时没有的信息。该模型利用这些信息进行“欺骗”,在测试集上看起来很棒,但在没有这些信息的情况下在生产中就会崩溃。泄漏的症状几乎总是相同的:好得令人难以置信。在看到 99% 的准确率而欣喜若狂之前,您应该先查找是否有漏洞。

泄漏的主要类型有:

1. 目标泄漏:特征是目标的结果。在“被取消”预测中,“取消日期”或“退款金额”栏是目标的结果;只有当结果明确时,它们才会被填充。

2. 时间泄漏:将未来的信息带到过去。计算“最近 30 天平均值”时,包括预测日之后的天数,或随机划分时间序列。

3. 预处理泄漏:在训练/测试分区之前从所有数据中学习变换,例如缩放、填充、编码。测试数据的平均值会干扰训练。

4. 重复/分组行泄漏:属于同一个人的行同时出现在训练和测试中(同一患者在不同组中两次就诊)。模型记住了这个人。

泄漏类型

是怎样诞生的

如何预防

目标泄漏

作为目标结果的列

“预测时我有吗”测试

时间泄漏

将未来带入过去

时间划分、窗口控制

预处理泄漏

预分割转换

管道,仅通过培训即可适应

分组行泄漏

同一单元分为两套

按组拆分 (GroupKFold)

防止泄漏的唯一纪律

所有类型泄漏的通用解决方案都归结为一句话:尽早隔离测试集以模拟真实的未来,并且不要“教”它任何东西。在实践中,这意味着:首先划分,然后仅从训练中学习所有转换并将它们应用到管道(将所有步骤收集在单个链中的结构)中。对于每个特征,询问“我在预测时是否有这些信息?”如果有时间,就按时间顺序划分;如果同一单元重复,则按组划分。

警告:泄漏最危险的方面是它表现为成功。一个糟糕的模型显然会产生糟糕的结果,并且会被注意到;泄露的模型效果很好,让每个人都满意,并投入生产——这就是崩溃的开始。这就是为什么“非常好”的结果会引起恐慌,而不是庆祝。

再现性:两次得到相同的结果

再现性是指当您在另一台机器上再次运行分析时获得相同结果的能力。如果没有这一点,你的分析就是偶然的,而不是科学的。影响再现性的主要原因和解决方案:

手动步骤:手动更改 Excel 中的单元格、手动编辑图表。解决方案:将每一步都写在代码中。

不固定的随机性:模型训练、采样、分裂都涉及随机性。解决方案:修复随机种子(随机生成器的初始值)(random_state=42)。

版本变化:当库版本发生变化时,结果可能会发生变化。解决方案:修复依赖关系(requirements.txt、环境文件)。

无记录保存:不清楚使用了哪些数据、哪些代码、哪些参数。解决方案:版本控制(Git — 保存所有版本代码的系统)和数据版本控制。

“它只适用于我的机器”:解决方案:记录环境,如果可能的话使用容器(Docker)。

三个迷你箱子

情况 1 — 目标泄漏。一项健康分析以“出院后用药”栏为特色,预测“患者是否会再次入院”。该栏仅在患者出院后才填充。模型给出了 96%,生产中给出了 61%。为期 8 周的项目是垃圾。课程:询问每个特征“在预测时是否存在?”

案例 2 — 预处理泄漏。一个团队缩放了所有数据,然后将其拆分。测试数据的均值涉及缩放。 CV 得分 89%,实际产量 76%。当我转向 Pipeline 并仅通过培训了解转换时,虚假的成功就消失了。教训:先划分,后转化。

情况 3 — 无法重现。三个月后,一位分析师想要更新他向管理层提交的图表,但不记得他是如何制作的;许多步骤都是在 Excel 中手动完成的。结果并没有成功,信任也动摇了。教训:没有手动步骤,一切都在代码和 Git 中。

四个可复制模板

1)泄漏检查:

您的角色:泄漏检查员。目标:“流失”(0/1),预测参考日期:record_date。我会给你这个功能列表。对于每个特征:(a)它是目标的结果吗?(b)在预测时我可以使用它吗?(c)时间窗口是否包括未来?将其标记为“不安全/可疑/泄漏”并写下原因。特点:[列表]

2)管道无泄漏:

设置 sklearn 管道:首先分割训练/测试(分层,种子 = 42),然后仅将所有预处理(插补、缩放、编码)放入管道中。解释为什么代码是无泄漏的,哪一步是在哪里学到的。

3) 再现性检查表代码:

我想让我的分析具有可重复性。建议添加以下代码/结构:(1) 所有随机性的硬种子,(2) 使用的打印库版本,(3) 数据和输出的日期/版本标签。还给我一份清单,以确保没有手动步骤。

4)分组分区(同一单元泄漏):

在数据中,同一 customer_id 存在于多行中。进行拆分(GroupKFold 或GroupShuffleSplit,group = customer_id),以防止同一客户同时参与培训和测试。包含代码以验证拆分后两组中均没有客户。

弱提示/强提示

弱提示:

我的模型返回了 98% 的准确率,不是很好吗?优化代码。

庆祝 98% 隐藏了泄密事件。在优化之前,应该质疑这个分数是否真实。

强力提示:

您的角色:泄漏检查员。我的模型在测试集上返回 98% 的准确率,这对我来说听起来“好得令人难以置信”。检查:(1) 是否有任何特征是目标的结果,(2) 是否在分割之前完成的转换,(3) 两组中的单元是否相同,(4) 是否存在任何时间泄漏。列出任何可疑点;专注于寻找漏洞,而不是修复分数。

在这里,高分被视为值得质疑的标志,而不是值得庆祝的标志。

常见错误

  • 庆祝“非常好”的结果。好得令人难以置信的分数是一个泄漏警报,而不是一项成就。
  • 在划分之前学习所有数据的变换。最常见的泄漏;首先用管道分割。
  • 随机分割时间序列。模型预见未来;按时间顺序划分是必须的。
  • 将同一单元分成两组。模型记住了人;按组划分。
  • 不手动介入并写入代码。分析变得不可重现;一切都应该在代码和 Git 中。
提示:在项目开始时写下两句话的“荣誉誓言”:“在生产中看到测试集之前,我没有以任何方式接触过它。每一步都在代码中,种子是固定的。”如果你不能诚实地在这两句话上签名,那么你的结果还不可靠。

综上所述

数据泄露和不可重复性是数据科学中最昂贵的两个无声错误。泄漏是模型对未来的愿景,表现为虚假的成功;解决方案是尽早分割测试集,仅从训练(管道)中学习转换,向每个特征询问“我在预测时是否有它”的问题,并进行正确的分割(按时间顺序/分组)。再现性是指能够两次得到相同的结果;他的解决方案是手动删除步骤、固定种子、冻结版本,并将所有内容保留在 Git 中。人工智能可以增加或减少这些风险;这是你的纪律决定的。

应用任务

获取您已构建的模型(或假设模型)的特征列表,并向每个特征询问“我在预测时是否有这些信息?”以书面形式;找到至少一个泄漏候选者。然后填写一份清单,使您的分析具有可重复性:种子是否已修复、是否有手动步骤、版本是否已注册、是否在 Git 中。修复缺陷。

清单

  • [ ] 我是否将“好得令人难以置信”的分数作为泄漏警报进行查询?
  • [ ] 我是否仅通过训练就学会了分裂后的所有转变?
  • [ ] 我是否按照时间/组结构(chronological/GroupKFold)进行划分?
  • [ ] 我是否使用固定种子使所有随机性都可重复?
  • [ ] 我是否删除了手动步骤并将所有内容保留在代码和版本控制中?