TT Lab
はじめる
学ぶ 学習パス コース

先週のモデルの方が良かった。誰も見つけられない

同じ名前のCSVが昨日と違う

TT Labで続きを見る

目標

学習データに指紋を付けてバージョンとし、何が正常かを宣言した契約で新しい収集分を検査し、学習・評価の分割が重なったとき、指標が実際にどれだけ動くかを測ってみます。

なぜ重要なのか

再現が壊れるのは、たいていコードではなくデータです。train.csvという名前はそのままで、中の行が変わっても、何の警告もなく、指標だけが少し変わります。そのため、データには、名前ではなく内容のハッシュをバージョンとして付け、正常な範囲をあらかじめ宣言しておいて、新しく入った収集分を機械で突き合わせます。契約に違反した行を黙って捨てずに、隔離しておくのも、同じ理由です。黙って減ったサンプルは、数か月後に「なぜ性能が下がったのか」として戻ってきます。 最後の2つのステップは、よくある誤解を1つ、実測で崩します。リークがあれば、指標が目立って上がりそうですが、記憶力の弱いモデルでは、ほとんど動きません。

ステップ

  1. 3つの分割の指紋(ハッシュ・サイズ・行数・ヘッダー)を取ります。
  2. 業務ルールでデータ契約を宣言し、学習データがその中に収まるかを確認します。
  3. 新しい収集分を契約に突き合わせて、違反をリストにします。
  4. 違反した行を隔離し、学習に使う行だけを別に残します。
  5. 壊れた分割で、重なっている顧客を見つけ出します。
  6. 重なりを取り除いて2回学習させ、指標の差を測ります。
  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で実際に観察される[最小, 最大]です。

契約は、データから推測するものではなく、業務から宣言するものです。ただし、学習データがその宣言に収まるかは、必ず確認する必要があります。

新しく入った収集分を契約に突き合わせる

/opt/fixtures/mlops/week2.csvを/root/datacontract/contract.jsonで検査して、/root/datacontract/validation.jsonに、source・total_rows・violations・violation_count・passedを保存してください。violationsの各項目は、row(ヘッダーを除いた1からの行番号)・column・ruleの3つのキーだけを持ち、ruleは、空の値ならrequired、数値として読めなければtype、範囲を外れればrangeです。並べ替えは、行番号の昇順で、同じ行の中では、ファイルに書かれた列の順です。

検査のルールをコードの1か所にまとめておけば、来週の収集分にも、そのまま回せます。空文字列と0を同じものとして扱わないように、注意してください。

捨てた行も残す

契約に違反した行が1つでもある行は/root/datacontract/quarantine.csvに、残りは/root/datacontract/clean_week2.csvに分けて保存してください。2つのファイルとも、元と同じヘッダーを最初の行に置いて、元の順序を維持します。

黙って捨てた行は、来月、「データがなぜ減ったのか」として戻ってきます。隔離ファイルがあれば、何をなぜ捨てたのかを、あとでもう一度見られます。

分割が重なっていないかを構造で確認する

/opt/fixtures/mlops/bad_train.csvと/opt/fixtures/mlops/bad_valid.csvのcustomer_idを比べて、/root/datacontract/leakage.jsonに、train・valid(2つのファイルのパス)・overlap_count・overlap_ratio(重なった数÷評価の行数、小数点以下4桁に丸める)・overlapping_ids(辞書順の先頭5個)・split_validを保存してください。

重なりは、行ではなく個体で数えます。同じ顧客が両側にいれば、その顧客については、モデルが答えをすでに見たことになります。

リークを取り除いて、指標がどれだけ動くかを測る

/opt/fixtures/mlops/bad_valid.csvから、学習側の顧客を除いた行だけを残して、/root/datacontract/fixed_valid.csvを作ってください(ヘッダーと順序は維持)。そのあと、bad_train.csvで、lr 0.1、epochs 40、seed 7で2回学習させて、/root/datacontract/split_effect.jsonに、leaky_accuracy(bad_valid.csvで測った値)・clean_accuracy(fixed_valid.csvで測った値)・delta(clean − leaky、小数点以下4桁に丸める)・threshold(0.05)・visible_in_metric(|delta|がthreshold以上か)を保存してください。

結果を予想してから測ってください。予想と違えば、その差が、このステップで学ぶことです。

このデータで何を言えるかを書く

/root/datacontract/datacard.jsonに、train_sha256・contract_sha256(/root/datacontract/contract.jsonのハッシュ)・clean_week2_sha256・violation_count・leakage_overlap_count・approved_for_training・limitations(40文字以上)を保存してください。前のステップの出力から値を持ってきて合わせます。

データカードは自慢ではなく、限界を書く場所です。合成データでは言えないことを書いておけば、次の人が間違って使いません。