🎓 レベル:発展 | 重要度:A(必須)
要点(BLUF)
- 本番モデルを劣化させる変化は2種類:データドリフト(入力 の分布が変わる)とコンセプトドリフト(入力と出力の関係 が変わる)。原因も検知法も違います。
- データドリフトはラベルなしで検知できます。入力分布を学習時の基準と比較し、PSI(Population Stability Index)やKS検定で乖離を測ります。コンセプトドリフトはラベルが要る(関係の変化は答え合わせしないと分からない)ので、性能監視で捉えます。
- 検知は「劣化の予兆を早く掴む」ため。PSI/KS が異常を示したら調査し、必要なら再学習をトリガーします(再学習と継続的トレーニング(CT))。分布シフトの理論・頑健化(重要度重み付け等)は機械学習分野(分布シフトと頑健性)へ wikilink します。
1. 2種類のドリフト
| データドリフト | コンセプトドリフト | |
|---|---|---|
| 変わるもの | 入力分布 | 入出力の関係 |
| 例 | 新規ユーザー層が流入し年齢分布が変化 | 同じ属性でも購買傾向が変化(流行・景気) |
| 検知 | ラベル不要(入力分布の比較) | ラベル必要(性能の低下) |
| 反応速度 | 即時 | 遅延(ラベル待ち) |
データドリフトは必ずしも性能を落としません(モデルが使わない特徴量の変化など)が、早期警戒の主役です。コンセプトドリフトは性能を直接落としますが、検知にラベルが要るため遅れます。
2. 図解:ドリフト検知から再学習へ
flowchart LR
REF["学習時の基準分布"] --> C{"PSI と KS で比較"}
CUR["本番の入力分布"] --> C
C -->|"乖離が大きい"| ALERT["ドリフト警報"]
C -->|"安定"| OK["正常"]
ALERT --> INV["調査:原因特定"]
INV --> RT["再学習トリガー(06-03)"]
LAB["遅延ラベル"] --> PERF["性能監視"]
PERF -->|"低下"| RT
3. PSI と KS 検定
- PSI(Population Stability Index):分布をビンに分け、基準と現在の各ビン割合の差を集計。実務の定番。目安は < 0.1 安定 / 0.1–0.25 要注意 / > 0.25 顕著なドリフト。
- KS検定(Kolmogorov-Smirnov):2標本の累積分布の最大差を統計量に、分布が同一かを検定。p値が小さいほど「同一でない=ドリフト」。
PSI は「どれくらいズレたか」の連続量、KS は「ズレが統計的に有意か」の検定。両方見ると、効果量と有意性の両面で判断できます。
4. 動く最小例:特徴量ごとに PSI と KS でドリフトを検知
labs/06_drift/drift_detector.py に、特徴量ごとに PSI と KS 検定でドリフトを判定する検出器を置きました。中核は PSI です:
def population_stability_index(reference, current, bins=10):
edges = np.quantile(reference, np.linspace(0, 1, bins + 1))
edges[0], edges[-1] = -np.inf, np.inf
ref_frac = np.histogram(reference, bins=edges)[0] / len(reference)
cur_frac = np.histogram(current, bins=edges)[0] / len(current)
eps = 1e-6
ref_frac = np.clip(ref_frac, eps, None)
cur_frac = np.clip(cur_frac, eps, None)
return float(np.sum((cur_frac - ref_frac) * np.log(cur_frac / ref_frac)))
3特徴量(年齢=ドリフトなし/利用額=平均シフト/頻度=尺度拡大)で実行した結果:
特徴量 PSI 判定 KS統計 KS p値 ドリフト
年齢 0.0056 安定 0.0160 0.7175 no
利用額 0.5262 顕著なドリフト 0.2893 0.0000 YES
頻度 0.5704 顕著なドリフト 0.3107 0.0000 YES
ドリフト検知: ['利用額', '頻度']
出力の意味:分布を変えていない「年齢」は PSI=0.0056(安定)・KS p値=0.72(同一分布と矛盾しない)で正常判定。一方、平均をずらした「利用額」と尺度を広げた「頻度」は PSI が 0.25 を大きく超え(0.53・0.57)、KS p値も 0.0000 で、明確にドリフトと検知されました。どの特徴量がズレたかが特定できるので、調査と対応(再学習・特徴量修正)の的を絞れます。これはラベルなしで即座に動くので、本番モデルの監視の早期警戒の中核になります。
5. 運用の勘所
- 基準分布を学習時に保存する:学習データの分布を参照(reference)として固定し、本番と比較する。
- 特徴量ごとに見る:全体ではどの特徴がズレたか分からない。特徴量単位で PSI/KS を出す。
- PSI と KS を併用する:PSI は効果量(どれだけ)、KS は有意性(偶然か)。大標本では KS が過敏になりやすいので PSI のしきい値と併せて判断する。
- ドリフト=即再学習ではない:使っていない特徴量のドリフトは無害なことも。性能影響を見極めてから再学習を判断する(再学習と継続的トレーニング(CT))。
- 理論はMLへ:分布シフト下の頑健化・重要度重み付け・共変量シフト補正は機械学習(分布シフトと頑健性)。
なぜそうするのか
ドリフト検知を入力分布で行うのは、それがラベルを待たずに即座に動く唯一の手段だからです。コンセプトドリフト(関係の変化)は性能低下として最終的に現れますが、ラベル遅延のせいで気づくのが遅れます。入力分布の監視は、性能が崩れる「前」に「いつもと違う入力が来ている」ことを教えてくれる先行指標です。PSI/KS で定量化することで、「なんとなく変」ではなく「特徴量◯の PSI が0.5でしきい値超過」と客観的に判断・自動化できます。
⚠️ よくある落とし穴
- データドリフトとコンセプトドリフトを混同する:前者は入力、後者は関係の変化。検知法(ラベル要否)が違う。
- データドリフト=必ず性能劣化と決めつける:モデルが使わない特徴のドリフトは無害なことも。性能影響を確認する。
- 大標本で KS の p値だけ見る:標本が大きいと些細な差でも有意になる。PSI の効果量と併用する。
- 全体集計だけ見る:どの特徴がズレたか分からず対応できない。特徴量ごとに出す。
対応 lab
mlops-study/labs/06_drift/drift_detector.py— PSI と KS 検定による特徴量別ドリフト検知。python drift_detector.pyで実行。
関連ノート
- 本番モデルの監視(早期警戒の中核)
- 再学習と継続的トレーニング(CT)(ドリフトを再学習トリガーに)
- 学習推論スキューの防止(スキューとの違い:同時点 vs 時間方向)
- 分布シフトと頑健性(機械学習・分布シフトの理論)
- 第6章 監視と継続的学習 目次
- MLOps・AI基盤 全体目次