評価指標と確率の較正 ― AUC・logloss・RMSEを意思決定に翻訳する
公開ノートの評価セルを意思決定の言葉に翻訳します。回帰指標、分類指標、不均衡とコンペ指標の選ばれ方、確率の較正とビジネス閾値。コンペ指標と業務KPIの乖離、そして「予測に効く≠因果」を再掲し因果編へ送り出します。
by Akisame
AUCが高いモデルは、本当に「役に立つ」モデルなのでしょうか。結論から言えば、指標が高いことと、現場の意思決定が良くなることは別の話です。何を最適化しているのかを問わないと、スコアだけ立派で誰の判断も動かさないモデルが残ります。この回では、回帰・分類の指標を一枚の地図に並べ、出てきた確率を較正して——「確率70%」と出た相手のうち本当に7割で成果が出るように直して——ビジネス閾値に翻訳するところまでを、Titanicと過去の受託案件をもとに設計した架空企業SOLNAで通します。
公開ノートの末尾にはたいてい roc_auc_score(...) のような評価セルが一行だけ置かれています。写経ではここを「良い数字が出た/出ない」で通り過ぎますが、解読とは、その一行が何を測り、その数字が現場の何を動かすのかを言えることです。
この回で解読・移植できるようになること
- 回帰・分類の指標を地図として持ち、課題に合うものを選べる
- AUC・logloss・精度の違いと、不均衡データで精度が誤解を生む理由を言える
- 確率を較正し、コストや運用制約からビジネス閾値を決められる
- コンペ指標と業務KPIが食い違う構造を説明できる
- 「予測に効く変数 ≠ 因果のある変数」を言葉にできる(因果編への接続)
前提
第4回でロジスティック回帰が確率を出すこと、第5回でCVと正則化、第6回でGBDTを動かしました。つまり読者はすでに、学習済みモデルから予測確率 proba を取り出せる段階にいます。この回が扱うのは、その確率を「読む」工程だけです。
回帰指標(RMSE/MAE)と対数変換の意味
回帰の評価セルは多くが一行です。
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_error
rmse = np.sqrt(mean_squared_error(y_true, y_pred))
mae = mean_absolute_error(y_true, y_pred)下にある数学は単純です。、。違いは誤差の効き方で、RMSEは二乗するため大きな外れに敏感、MAEは一件いくらで均等に効きます。大きな外れ(誤差)に強く反応させたいならRMSE、典型的なズレを見たいならMAEです。
House Pricesのような右に歪んだ正の量(価格・LTV)では、目的変数を対数化してから評価することがあります。 の空間でRMSEを取る(RMSLE)と、絶対額ではなく比率の誤差を見ることになり、高額帯の大きな絶対誤差に評価が引きずられなくなります。
分類指標の地図(精度/再現率/AUC/PR/logloss)
分類は指標が多く、ここで迷子になりがちです。地図の縦軸は「閾値に依存するか/しないか」です。
しきい値依存(精度・再現率)と非依存(AUC)
精度(accuracy)・適合率(precision = TP/(TP+FP))・再現率(recall = TP/(TP+FN))は、すべて「確率をどこで0/1に切るか」という閾値を決めて初めて計算できる、閾値依存の指標です。一方AUCは閾値を決めません。AUCは「ランダムに選んだ正例(=当てたい側のクラス。例: churn する人)のスコアが、ランダムに選んだ負例(=それ以外)のスコアより高い確率」、つまり で、モデルの順位付けの良さだけを測ります。
ここで一つ目の誤解を解いておきます。精度が高い ≠ 役に立つ、です。正例が10%しかないデータでは、全件を「負」と予測するだけで精度90%が出ます。精度は不均衡の前ではほとんど何も言っていません。
PR曲線が効く場面(不均衡)
ROC曲線(とAUC)は負例が大量にあると楽観的に見えます。偽陽性率の分母(全負例)が巨大なので、多少の誤検知では曲線が崩れないからです。正例が稀で、しかも正例を当てることに価値がある問題(churn・不正検知・成約予測)では、PR曲線(precision-recall)とPR-AUCのほうが現場感覚に合います。
logloss(交差エントロピー)は順位ではなく確率そのものを評価します。。自信満々で外したとき(正例なのに p ≈ 0.01 と言ったとき)に強く罰せられる。loglossは「確率を真面目に出しているか」を問う指標で、後で出てくる較正と相性が良い性質(proper scoring rule)を持ちます。
不均衡データと、コンペ指標がどう選ばれるか
コンペの評価指標は、主催者が「このタスクで何を当ててほしいか」を一つの数式に畳んだものです。だから指標を見れば狙いが読めます。不均衡な検知タスクでAUCやPR-AUCが選ばれるのは、稀な正例の順位を重視したいから。確率の質を問いたいときはlogloss。順位も確率も一つに、というときはこれらが使い分けられています。
ここで二つ目の誤解です。コンペで効く ≠ 実務で効く。コンペの指標は固定で一つですが、実務のKPIは複数あり、しかも動きます。コンペのリーダーボードを0.001上げる工夫が、現場の意思決定を1ミリも変えないことは普通にあります。
確率の較正(calibration)とビジネス閾値設計
較正とは、モデルが「70%」と言ったとき、実際にその集団の約70%が正例である状態のことです。順位が良くても(AUCが高くても)、確率の絶対値がズレていることは珍しくありません。とくにGBDTやSVMは確率がS字に歪みやすく、ロジスティック回帰は比較的素直です。
Titanicで較正を確認し、ズレていれば直す最小構成です。
from sklearn.calibration import CalibratedClassifierCV, calibration_curve
from sklearn.metrics import brier_score_loss
# model は第6回までで学習済み(例: LightGBM)。proba は検証データへの予測確率。
proba = model.predict_proba(X_valid)[:, 1]
# 較正前: 信頼性曲線(予測確率の帯ごとに実測陽性率を並べる)
frac_pos, mean_pred = calibration_curve(y_valid, proba, n_bins=10)
brier_before = brier_score_loss(y_valid, proba) # 小さいほど良い
# 較正(isotonic は単調・非線形。データが少なければ sigmoid=Platt)
calibrated = CalibratedClassifierCV(model, method="isotonic", cv="prefit")
calibrated.fit(X_calib, y_calib) # 学習に使っていない別分割で較正する
proba_cal = calibrated.predict_proba(X_valid)[:, 1]
brier_after = brier_score_loss(y_valid, proba_cal)較正した確率があって初めて、閾値を意思決定として設計できます。閾値は精度を最大化する点ではなく、コストで決めます。偽陽性のコストを c_FP、偽陰性のコストを c_FN とすると、期待コストを最小化する最適閾値は です。見逃しが痛い問題(c_FN が大きい)なら閾値は下がり、誤検知が痛い問題なら上がる。閾値は現場のコスト構造の写し絵であって、データから一意に決まる量ではありません。
import numpy as np
# コスト比から最適閾値(PRML 1.5 の決定理論:損失と決定の分離)
c_fp, c_fn = 1.0, 5.0 # 見逃しが誤検知の5倍痛い、という現場の値
t_star = c_fp / (c_fp + c_fn) # = 0.1667...
action = proba_cal >= t_star # 「打つ/打たない」へ翻訳コンペ指標 vs 業務KPI ― 何を最適化しているのか
コンペは指標を一つに固定しますが、実務では「営業が今週かけられるのは150件まで」のような運用制約が指標より先に効きます。AUCはデータ全体の順位を最適化しますが、現場が触るのは上位K件だけ。だから業務では precision@K や、コスト重み付きの期待利得のほうが効く場面が多くなります。
SOLNAのChurn予測(第6回で subscriptions と orders から作ったモデル)を、通知閾値と営業優先順位に接続します。
# churn_proba: 較正済みの解約確率。ltv_to_date: 顧客の現時点LTV。
# save_rate: 介入が成功して引き留められる割合(過去の holdout から推定)。
import pandas as pd
df = customers.copy()
df["churn_proba"] = churn_proba_calibrated # 較正済みでないと期待値計算が壊れる
df["expected_saved"] = df["churn_proba"] * df["ltv_to_date"] * save_rate
# 運用制約:今週フォローできるのは上位 capacity 件だけ
capacity = 150
priority = df.sort_values("expected_saved", ascending=False).head(capacity)ここでの目的変数は「解約しそうか」ではなく「介入して救える期待金額」です。解約確率が高くてもLTVが小さい顧客より、確率は中くらいでもLTVが大きい顧客を先に追うほうが、同じ150件でも回収が大きい。較正されていない確率でこの掛け算をやると期待金額が歪み、優先順位が入れ替わってしまうので、較正は飾りではなく前提です。
一次データで較正の効き方を確認した結果(匿名化・レンジ表記)です。解約のベース率は約8〜12%とそもそも不均衡で、較正前のBrierスコアはおよそ0.11〜0.13。isotonic較正後は0.09〜0.10まで下がり、予測80%帯の実測解約率も較正後に実測へ寄りました。AUCは較正の前後でほぼ不変(較正は順位を変えないため)で、ここが「順位は良いが確率はズレる」を地で行く例になります。
伏線 ― 予測に効く変数 ≠ 因果のある変数
最後に三つ目の誤解です。「churn_probaが高い = その人に介入すれば効く」ではありません。解約確率を押し上げている変数(例:最近ログインしていない)は、解約をよく予測しますが、そこに介入したら解約が減るとは限らない。誰に打てば効くのかは予測ではなく因果の問いで、ここから先は本連載の範囲外です。深掘りは因果編に譲ります。本連載は「このコードは何を測っているか」までを担当し、「その変数に介入したら効くか」は因果編に送り出す、という棲み分けです。
対応書籍と読みどころ
- 評価指標入門(ホクソエム社):本記事で扱った回帰・分類指標と較正を、実装と落とし穴つきで体系化した一冊。指標を「数式」ではなく「どの意思決定に効くか」で並べる視点が、この回の地図と同じ方向を向いています。
- 門脇ら『Kaggleで勝つデータ分析の技術』評価の章:コンペ指標がどう選ばれ、どう最適化されるかの実務的な勘所。本記事の「コンペ指標 vs 業務KPI」の片側(コンペ側)の解像度を上げてくれます。
PRMLへの一歩
この回のバックボーンは決定理論(PRML 1.5)です。PRMLは「確率を推定すること(推論)」と「その確率から行動を決めること(決定)」を分けて論じます。本記事の流れ——モデルが確率を出す → 較正で確率を信頼できるものにする → コストから閾値を決めて行動に変える——は、まさに推論と決定の分離そのものです。loglossが proper scoring rule であることや、最適閾値がコスト比で決まることは、PRML 1.5を読む前段になります。
章末チェックリスト
- 課題(外れ値感度・不均衡・確率の質)に合う指標を選べる
- 精度が不均衡データで誤解を生む理由を説明できる
- 確率を較正し、コストや運用制約から閾値を決められる
- コンペ指標と業務KPIが食い違う構造を言える
- 「予測に効く ≠ 因果」を自分の言葉で説明できる
「誰に打てば効くのか」は予測ではなく因果の問いです。その先は因果編へ。何を測り、その数字で何を動かすかという判断の全体像は記述・予測編も合わせてどうぞ。次回は公開ノート後半(チューニング・解釈・運用)を解剖します。