Data Leakage
データリークでは、予測時に利用できない情報が学習や評価に入り込み、本番環境では通用しないスコアを生みます。原因と対策を解説します。
機械学習 (ML)におけるデータリークは、モデルの学習データや評価に、実際の予測時には利用できない情報が含まれているときに発生します。たとえば、テストセットの例、未来の値、答えを示す特徴量などです。開発中のモデルテストでは高い精度に見えても、モデルが頼っていた近道がなくなるため、本番環境では性能が低下します。データリークは再現性のない結果を生む主な原因です。機械学習を用いた科学研究の調査では、17分野で影響を受けた論文が294件確認されました。また、内戦の予測では、リークを修正すると、複雑なモデルが数十年前のロジスティック回帰に対して示していた優位性が失われました。
データリークの発生要因#
リークは、データの分割、処理、入力の選択方法を通じて入り込みます。同じ誤りは、表形式モデル、時系列分析、行動認識などのビジョンタスクで繰り返し発生します。
- 学習データとテストデータの汚染: 正規化統計量、欠損値補完、特徴選択など、データから学習する処理を分割前にデータセット全体で適合させると、学習データに評価用分割の情報が入り込みます。分割前に作成した重複画像や拡張画像も同じ影響をもたらします。
- グループリーク: 関連するサンプルを別々の分割に分けることです。たとえば、同じ動画の連続フレーム、同じ患者の複数のスキャン、同じシーンの写真などが該当します。その結果、モデルはタスクを学習する代わりに、シーンや人物を認識して高いスコアを出すことがあります。
- 時間的リーク: 時系列データをランダムに分割したり、予測時点より後の値を使って特徴量を計算したりすると、モデルが未来を参照できてしまいます。
- ターゲットリーク: 入力がラベルの結果や代替指標になっている状態です。たとえば、疾患を予測するモデルにおける「治療を受けた」というフィールドが該当します。
- 評価データの再利用: テストセットを使ってチューニングしたり、大規模言語モデルのウェブ規模の事前学習データにベンチマークの問題が含まれていたりすると、評価データが学習信号になってしまいます。
画像にもターゲットリークが含まれることがあります。ChestX-ray14データセットでは、気胸のテストセットX線画像の80%に胸腔ドレーンが写っていました。胸腔ドレーンは、その症状の治療に使うチューブです。このデータセットで学習した分類器は、ドレーンありの画像でROC AUC 0.94を達成しましたが、検出器が見つけるべき未治療のケースである、ドレーンなしの画像では0.77にとどまりました。
コードでデータリークを実証する#
交差検証の前にデータ依存の処理を適合させるのは典型的な誤りで、その影響は簡単に測定できます。以下の例では完全なノイズを生成するため、新しいデータに対して50%を超える精度を達成できるモデルはありません。その後、ラベルを最もよく分離する20個の特徴量を選択し、ロジスティック回帰を2通りで交差検証します。1つ目はすべてのサンプルで特徴選択を適合させ、2つ目はscikit-learnパイプライン内で特徴選択を行い、各学習フォールドで再適合させます。
import numpy as np
from sklearn.feature_selection import SelectKBest
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline
# Pure noise: 100 samples, 5,000 random features, random labels (true accuracy is 50%)
rng = np.random.default_rng(0)
X = rng.normal(size=(100, 5000))
y = rng.integers(0, 2, size=100)
# Leaky: pick the 20 features that best separate the labels using every sample, then cross-validate
X_selected = SelectKBest(k=20).fit_transform(X, y)
leaky = cross_val_score(LogisticRegression(), X_selected, y, cv=5).mean()
# Correct: feature selection is refit inside each training fold
pipeline = make_pipeline(SelectKBest(k=20), LogisticRegression())
clean = cross_val_score(pipeline, X, y, cv=5).mean()
print(f"Leaky CV accuracy: {leaky:.2f}, correct CV accuracy: {clean:.2f}")リークのある方法ではランダムなラベルに対して85%の精度が報告されますが、パイプラインでは偶然の確率にあたる48%となります。サンプル数が100で特徴量が5,000個の場合、偶然にラベルと相関する特徴量が生じます。検証フォールドを含めて特徴量を選ぶと、その偶然の相関が各フォールドのスコアに組み込まれます。
データリークの防止#
防止策は分割から始めます。データから学習する処理より先に分割を行い、検証用データとテスト用データを未使用の状態に保ちます。
- 特徴量エンジニアリングの前に分割する: スケーラー、欠損値補完器、エンコーダー、特徴選択器は学習用分割だけで適合させ、他の分割には変更せずに適用します。
- グループまたは時間で分割する: 同じ患者、動画、シーンに属するすべてのサンプルを1つの分割にまとめ、過去のデータで学習して未来のデータでテストします。
- ハッシュと埋め込みで重複を排除する: 学習前に、ファイルハッシュで完全一致を確認し、分割をまたいだ近似重複は埋め込みの類似度で確認します。
- 入力を監査する: 各特徴量が予測時点で利用可能かを確認し、単独で支配的な特徴量や不自然に高いスコアを、調査すべきバグとして扱います。
リークはチェックポイントの選択も歪めます。Ultralytics YOLOは、データセットのYAMLに記載されたtrain画像で学習し、検証フィットネスが最も高いエポックのbest.ptを保存します。検出タスクの検証フィットネスはmAP50-95です。そのため、trainとvalで近似重複フレームを共有すると、チェックポイントの選択に使われるスコアと報告されるスコアの両方が水増しされます。
データリークと関連用語の比較#
- 過学習: モデルが正当な学習データ内のノイズを記憶し、クリーンな検証セットで低いスコアを出す状態です。リークは検証スコア自体を誤ったものにするため、過学習したモデルが良好に見えることがあります。
- ショートカット学習: モデルが、ラベルと相関する透かしや背景などの誤った手掛かりに依存することです。デプロイ時に利用できない情報から、その手掛かりが学習や評価に入り込む場合がデータリークに当たります。
- データセキュリティ: サイバーセキュリティでは、データリークは機密データが権限のない相手に漏れることを意味し、アクセス制御、暗号化、データ損失防止ツールで対処します。この2つの意味は、同じ名称を持つだけです。










