【要約】機械学習で回収率100.6%が出たとき、最初に疑ったこと [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
筆者が自作の競馬予測モデルをバックテストした際、理論上あり得ない回収率100.6%を記録した。期待値を超える異常な数値は、モデルが「未来の情報」を学習しているデータリークの兆候である。具体的には以下の問題に直面した。
- ・JRAの控除率(約80%)を大幅に上回る、市場の歪みを利用したかのような異常な成績。
- ・血統データを追加した直後に、想定(+10pt)を上回る+13pt超の精度向上。
- ・2022年単年で153.2%という、特定の期間における極端な成績の偏り。
// Approach
筆者は、異常な数値の正体を突き止めるために、実装ミスからデータの構造的欠陥へと段階的に疑いを深める検証を行った。単なる値の検証では見抜けない、データの「欠損」に注目したアプローチを採用している。
- ・集計バグの確認:独立したコードで再計算を行い、実装ミスや二重計上の有無を検証した。
- ・値のリーク確認:特徴量の値自体に未来の情報が混入していないか、抜き取り検査を実施した。
- ・欠損パターンの検証:特徴量の欠損率を時間軸(年別)で集計し、取得状況に時間勾配がないかを確認した。
- ・対照実験:問題の血統列を除外して再学習を行い、数値が現実的な範囲に収束するかを検証した。
// Result
欠損パターンのリークが原因であることを特定し、モデルの信頼性を回復させた。データの取得順序が、意図せず未来の情報をモデルに伝えていたことが判明した。
- ・「直近の馬から優先的に取得する」という工程が、生存バイアスを生んでいた。
- ・血統列を除外した結果、回収率は153.2%から87.3%へと、現実的な数値に修正された。
- ・全データを取得した状態での再実験では、血統の寄与は+8.4ポイントという妥当な改善幅に収束した。
Senior Engineer Insight
> 時系列予測において、欠損値は単なる「情報の欠如」ではなく、強力な「特徴量」になり得る。特に、データのバックフィルを行う際、取得順序が時間軸と相関を持つと、モデルは「欠損の有無」から未来の生存確率を学習してしまう。これは、ログの欠損やDBのレコード削除を伴う実務上のデータパイプラインでも頻発する致命的な罠だ。精度向上に喜ぶ前に、まず「欠損率の時系列推移」を確認する習慣を徹底すべきである。