Digital Reactor
機械学習

確率校正入門:分類器の「0.9」は本当に90%か(Platt・Isotonic・Temperature)

確率校正入門:分類器の「0.9」は本当に90%か(Platt・Isotonic・Temperature)

はじめに

モデルが「確信度90%」と出します。この0.9を、閾値判定や期待コストの計算にそのまま使ってよいのでしょうか。今回の実験に使った分類器は、当たり外れを見分ける力(AUCで0.85)はそれなりなのに、出してくる確率はかなり歪んでいました。予測が0.9の集団を集めても、実際に陽性なのは9割には届きません。予測確率と実測の頻度がどれだけずれているか(期待校正誤差、ECE)を測ると0.112ありました。

識別性能(当たり・外れを分ける力)と校正(確率の正しさ)は別物です。AUCが高くても確率がずれることは珍しくありません。この記事では、独立性の仮定が崩れて系統的に自信過剰になるナイーブベイズを題材に、その自信過剰を信頼性図とECEで診断し、Platt scaling・Isotonic回帰・Temperature scalingの3手法で後処理校正します。結論を先に言うと、AUCをまったく落とさずにECEを0.112から0.026まで下げられました。

対象読者:

  • 分類確率を閾値判定・リスク評価・意思決定に使う実務者
  • accuracyやAUCは見ているが、確率の校正までは見ていない方
  • 信頼度スコアの品質を測り、後付けで直したい方

記事のポイント:

  • 校正(予測確率=実際の頻度)と識別性能(AUC等)が別物であることを数値で確認します
  • 信頼性図とECEで校正のずれを可視化します
  • Platt / Isotonic / Temperature で後処理校正し、ECEとAUCへの影響を比較します

精度が高くても確率がずれる理由

決定境界の正しさ(識別)と、出力確率の正しさ(校正)は独立に動きます。閾値0.5でクラスを分けるだけなら、確率が0.6でも0.99でも判定は変わりません。AUCは順位だけを見る指標なので、確率を単調変換しても値は不変です。だから「AUCが高い=確率が信用できる」とは限りません。

自信過剰は特定のモデルで起きやすいです。深層モデルや勾配ブースティングは予測を0や1へ押し込みがちで、ナイーブベイズは特徴間の独立性を仮定するため、相関した特徴があると同じ証拠を何度も数えてしまい、極端な確率を出します。今回はこの性質を逆手に取り、相関・冗長特徴を含むデータでガウシアンナイーブベイズを学習させ、確実に自信過剰なモデルを作りました。

校正の測り方

信頼性図は、予測確率をビンに区切り、ビンごとに「予測確率の平均」と「実測の陽性率」を並べてプロットします。完全に校正されていれば点は対角線に乗ります。対角線から下に外れていれば、予測が実測より高い、つまり自信過剰です。

ECE(期待校正誤差)は、このずれをビンのサンプル数で重み付けして平均した1つの数値です。

ECE=bnbNacc(b)conf(b)\mathrm{ECE} = \sum_{b} \frac{n_b}{N} \left| \mathrm{acc}(b) - \mathrm{conf}(b) \right|

nbn_b はビン bb のサンプル数、acc(b)\mathrm{acc}(b) は実測陽性率、conf(b)\mathrm{conf}(b) は予測確率の平均です。0に近いほど校正がよいです。あわせてlog lossも見ておくと、校正と識別を合わせた確率予測全体の質が測れます。

後処理による校正手法

学習済みモデルはそのままに、出力確率だけを校正用のホールドアウトで補正します。

Temperature scalingは、log-odds(対数オッズ)を温度 TT で割ってから確率に戻します。T>1T>1 なら確率が中央に寄って自信過剰が和らぎ、T<1T<1 なら逆に鋭くなります。パラメータは TT ひとつだけで、順位を変えないので識別性能は完全に保たれます。

Platt scalingは、モデルの出力にロジスティック回帰を1本当てます。パラメータは2つで、少データでも安定しますが、シグモイド型のずれしか直せません。Isotonic回帰は、単調非減少という制約だけを課したノンパラメトリックな写像で、複雑なずれにも対応できるぶんデータを要求し、少ないと過学習します。

Temperatureの実装は短いです。校正用集合でlog lossを最小化する TT を1次元探索するだけです。

def fit_temperature(p_cal, y_cal):
    z = logit(p_cal)
    def nll(T):
        pt = 1 / (1 + np.exp(-z / T))
        return log_loss(y_cal, pt, labels=[0, 1])
    return minimize_scalar(nll, bounds=(0.05, 10.0), method="bounded").x

PlattとIsotonicは、学習済みモデルを凍結してCalibratedClassifierCVに渡します。scikit-learn 1.6以降はFrozenEstimatorでラップする点に注意してください。

frozen = FrozenEstimator(base)
platt = CalibratedClassifierCV(frozen, method="sigmoid").fit(Xcal, ycal)
iso   = CalibratedClassifierCV(frozen, method="isotonic").fit(Xcal, ycal)

過学習させたモデルで試す

相関・冗長特徴を持つ2クラスデータを生成し、学習用・校正用・テスト用に分けます。校正はテストとは別のホールドアウトで行います。ここを学習データで済ませると、モデルが見た答えに合わせて校正してしまい、リークになります。乱数シードは42に固定しました。

校正前と校正後(Isotonic)の信頼性図を重ねると、自信過剰だった赤い曲線が、緑ではほぼ対角線に乗ります。

校正前後の信頼性図

4手法を並べると、それぞれの癖が見えます。

4手法の信頼性図

得られた温度は T=2.30T=2.30 でした。1より大きいので、モデルが自信過剰だったことがそのまま数字に出ています。テスト集合での指標は次のとおりです。

手法ECEAUClog loss
校正なし0.1120.8500.599
Temperature (T=2.30)0.0420.8500.487
Platt0.0500.8500.495
Isotonic0.0260.8490.494

各手法のECE

どの校正手法を選ぶか

AUCがどの手法でも0.850のまま動かなかった点が重要です。校正は確率の目盛りを付け替えるだけで、順位、つまり識別性能には触れていません。校正されていないからといってモデルが「悪い」わけではなく、確率の解釈を直せば済みます。

手法ごとに得意は分かれました。校正用に3000件使えた今回はIsotonicが最良(ECE0.026)で、複雑なずれに追随できる強みが出ました。信頼性図をよく見ると、Plattは予測が0.13から0.82の範囲に圧縮され、両端に届きません。シグモイドで押し込む性質の裏返しです。Temperatureは1パラメータでここまで下げており、校正データが少ない場面での安定性を考えると、少ない手間でよく効きます。校正用データが数百件しか取れないなら、Isotonicの過学習を避けてTemperatureやPlattを選ぶ、という判断になります。

log lossも0.599から0.49前後へ改善しました。確率を意思決定に使う場面、たとえば期待損失の最小化や、確率に応じてコストの違う対応を振り分ける運用では、この改善がそのまま効いてきます。信用スコアリングの実務でも、スコアの順位だけでなく「このスコア帯の実際のデフォルト率」が効くため、校正は順位性能と同じくらい問われます。

使ううえでの注意点はいくつかあります。校正は必ずテストとは別のホールドアウトで行います。ECEはビン分割の仕方に依存するので、適応ビンやクラスワイズECEも併用すると安定します。そして校正は学習時の分布に対して成立するもので、分布シフトが起きれば崩れます。運用中はECEを監視項目に入れておくのが安全です。確率そのものではなく予測区間に被覆率保証を付けたい場合は、Conformal Predictionが分布フリーの選択肢になります。

まとめ

識別できることと、確率が正しいことは別問題です。今回はAUC0.85を保ったまま、ECEを0.112から0.026へ下げられました。確率を閾値設計や期待コスト計算、与信や医療のようなリスク領域の意思決定に使うなら、校正は省けない工程になります。まず手元のモデルで信頼性図とECEを描き、校正用ホールドアウトを1つ確保します。校正データが潤沢ならIsotonic、少なければTemperatureかPlattから始めるとよいでしょう。

関連記事

← 技術ブログ一覧へ