データリークと実験管理 — 精度が高すぎたら疑うこと
モデルの数字が思ったより良いとき、喜ぶ前に疑うべきものがあります。予測時点では手に入らない情報が学習や選択に混ざる「リーク」を、結果由来の列・前処理・時間・重複・テストの擦り切れの5種類に分けて解説し、ラベルシャッフルなどの検知手順と、原因を後から特定できる実験記録の作り方までを前提知識ゼロから積み上げます。
模試の点だけが跳ね上がった受験生
ある受験生が模試で偏差値75を取りました。前回は55です。本人も驚いています。よく調べると、その模試の問題は前の週に配られた課題プリントとほぼ同じで、解答冊子も一緒に配られていました。この受験生の学力は上がっていません。上がったのは測定値だけです。
機械学習で「思ったより精度が良い」ときに起きているのは、たいていこれです。データリーク(data leakage) とは、予測する時点では本来手に入らないはずの情報が、学習・検証・モデル選択のどこかに混ざり込んでしまうことを指します。
やっかいなのは、リークが必ずスコアを良い方向にだけ歪めることです。バグならふつう数字は悪くなり、悪くなれば人は調べます。リークは数字を良くするので、誰も調べません。そのまま本番に出て、手元で0.95だったAUCが0.6になって初めて発覚する。しかも原因はモデルではなく測り方の側にあるので、モデルをいくら改良しても直りません。
train/validation/test をなぜ分けるのか、という土台の話は過学習と評価設計で扱っています。この記事が扱うのは、その一歩先です。分割は正しくやったつもりなのに、壊れているという状況を、5つの型に分けて潰していきます。
リークの定義を一行にする
型の話に入る前に、判定基準を1つだけ持っておきます。
このモデルが本番で予測を返す瞬間を思い浮かべる。そのとき実際に手元にある情報だけで、この特徴量を作れるか。
作れないならリークです。逆に言えば、リーク探しは「頭の良さ」ではなく「時刻の確認作業」です。列を1本ずつ見て、その値がいつ確定するのかを問う。それだけで大半は見つかります。
型1: 結果から生えた列
解約予測モデルに「解約手続き画面の閲覧回数」という列が入っていました。重症化予測に「ICUへの転棟フラグ」。設備の故障予測に「修理伝票の番号」。どれも、予測したい出来事が起きた後にしか埋まらない列です。
データベースの上では、これらは正解ラベルと同じ行に仲良く並んでいます。SELECT * で引いてくれば自然に混ざります。モデルは喜んでその列だけを使い、ほぼ完璧な精度を出します。
見つけ方は地味です。列の一覧を作り、それぞれに「この値が確定するのは、予測時点より前か後か」を書き込みます。特に危ないのが上書き型のテーブルです。顧客マスタの status 列のように、常に現在の値だけを持ち、過去の値を残さない設計になっていると、1年前の行を取り出しても入っているのは"今の"値です。この場合、テーブル全体が丸ごとリークしています。
型2: 前処理を、分割の前にやってしまう
これは善意の人がいちばん踏む地雷です。標準化を考えます。
は 番目の行のある特徴量の値、 と は全データで計算した平均と標準偏差、 は全行数です。要するに「データ全体をならしてから、訓練用とテスト用に切り分けた」という手順です。
ここでテストの行も の計算に参加しています。つまり、テストデータの分布という情報が、訓練側にわずかに染み出しています。正しくは を訓練データだけで計算し、その値をテストに適用する(テストからは何も学ばない)という向きにします。
標準化だけなら影響は小さいことが多いのですが、罪が重いのは同じ過ちが次にそのまま波及することです。
- 欠損補完: 中央値を全データで計算して埋める
- ターゲットエンコーディング: カテゴリごとの平均目的変数を全データで計算する(これは を直接見ているので致命的)
- 次元圧縮: PCAを全データで学習する
- 特徴選択: 全データで との相関上位 本を選ぶ
- オーバーサンプリング: SMOTEなどで少数派を増やしてから分割する
最後の2つは、実験そのものを無意味にします。完全な乱数の列を3000本用意し、目的変数と相関の高い上位20本を全データで選んでから交差検証すると、AUCは0.5どころか0.8を超えることがあります。中身はただの乱数です。選ぶ段階で を見てしまったので、選ばれた20本は「たまたま に似ていた乱数」であり、その には検証用の行も含まれている、というだけの話です。SMOTEも同じで、分割前に増やすとテスト行の近傍から作った合成点が訓練側に入ります。答えを薄めて写しているのと変わりません。
コメント
コメントにはログインが必要です