TT Lab
开始
学习 学习路径 课程

上周那个模型更好,可没人找得到

同名的 CSV 和昨天不一样

在 TT Lab 中继续学习

目标

给训练数据打上指纹作为版本,用声明了什么是正常的契约来检查新收集的数据,并测量当训练和评估的划分发生重叠时,指标实际上会动多少。

为什么重要

复现被破坏的地方,大多不是代码,而是数据。train.csv 这个名字没有变,里面的行变了也没有任何警告,只有指标稍微不同。所以要给数据贴上 内容哈希 作为版本,提前声明正常范围,再用机器去核对新收集的数据。把违反契约的行隔离起来,而不是悄悄丢掉,也是同样的理由——悄悄减少的样本,几个月后会变成“为什么性能下降了”。 最后两步用实测打破一个常见的误解。看起来有泄漏的话指标会明显升高,但在记忆力弱的模型里,它几乎纹丝不动。

步骤

  1. 给三个划分取指纹(哈希、大小、行数、表头)。
  2. 用业务规则声明数据契约,确认训练数据落在其中。
  3. 用契约核对新收集的数据,做出违规清单。
  4. 隔离违规的行,把用于训练的行单独留下。
  5. 在坏划分中找出重叠的客户。
  6. 去掉重叠,训练两次,测量指标差异。
  7. 把到目前为止的事实和局限汇总成数据卡。

参考

确认同名的文件是不是同一个文件

在 /root/datacontract/dataset.json 中创建 files 对象,对 train.csv、valid.csv、test.csv 分别保存 sha256、bytes、rows(去掉表头的数据行数)、columns(表头列表)。材料在 /opt/fixtures/mlops 下。

文件名不是版本。内容的哈希才是版本。行数要用 csv 模块跳过表头之后再数。

声明什么是正常的

在 /root/datacontract/contract.json 中保存 source、source_sha256、row_count、required、ranges、observed。source 是 /opt/fixtures/mlops/train.csv,required 是按表头中写的顺序排列的列名列表,ranges 是把业务规则(tenure_months 0..120、monthly_fee 0..200、support_tickets 0..20、late_payments 0..12、usage_hours 0..400、churn 0..1)写成 [最小值, 最大值] 的形式,observed 是在 train.csv 中实际观察到的 [最小值, 最大值]。

契约不是从数据里推断出来的,而是从业务出发声明的。不过,训练数据是否落在这个声明之内,必须确认。

用契约核对新收集的数据

用 /root/datacontract/contract.json 检查 /opt/fixtures/mlops/week2.csv,把 source、total_rows、violations、violation_count、passed 保存到 /root/datacontract/validation.json。violations 的每一项只有 row(去掉表头后从 1 开始的行号)、column、rule 三个键,rule 在为空值时是 required,读不成数字时是 type,超出范围时是 range。排序按行号升序,同一行内按文件中写的列顺序。

把检查规则集中放在代码的一处,下周收集的数据也能照样运行。注意不要把空字符串和 0 当成同一回事。

被丢弃的行也要留下

把只要有一处违反契约的行保存到 /root/datacontract/quarantine.csv,其余的保存到 /root/datacontract/clean_week2.csv。两个文件的第一行都放与原文件相同的表头,并保持原来的顺序。

悄悄丢掉的行,下个月会变成“数据为什么少了”。有隔离文件,以后就能重新看到丢掉了什么、为什么丢。

用结构来确认划分是否重叠

比较 /opt/fixtures/mlops/bad_train.csv 和 /opt/fixtures/mlops/bad_valid.csv 的 customer_id,把 train、valid(两个文件路径)、overlap_count、overlap_ratio(重叠数 ÷ 评估行数,四舍五入到小数点后第四位)、overlapping_ids(字典序靠前的 5 个)、split_valid 保存到 /root/datacontract/leakage.json。

重叠要按 个体 而不是按行来数。同一个客户如果两边都有,对这个客户来说,模型就已经看过答案了。

去掉泄漏,测一测指标动了多少

从 /opt/fixtures/mlops/bad_valid.csv 中只留下去掉训练一侧客户的行,生成 /root/datacontract/fixed_valid.csv(保持表头和顺序)。然后用 bad_train.csv 以 lr 0.1、epochs 40、seed 7 训练两次,把 leaky_accuracy(用 bad_valid.csv 测得的值)、clean_accuracy(用 fixed_valid.csv 测得的值)、delta(clean − leaky,四舍五入到小数点后第四位)、threshold(0.05)、visible_in_metric(|delta| 是否大于等于 threshold)保存到 /root/datacontract/split_effect.json。

先预测结果再去测。如果与预测不同,这个差别就是这一步要学的东西。

写下用这份数据能说什么

把 train_sha256、contract_sha256(/root/datacontract/contract.json 的哈希)、clean_week2_sha256、violation_count、leakage_overlap_count、approved_for_training、limitations(40 个字符以上)保存到 /root/datacontract/datacard.json。从前面步骤的产出中取值并对上。

数据卡不是用来夸耀的,而是用来写局限的。把用合成数据说不了的事写下来,下一个人就不会用错。