Calibration(キャリブレーション)について


Calibration(キャリブレーション)とは?

Calibration(キャリブレーション)とはモデルの予測確率が、実際に観測される頻度と一致するように補正する事を言います。

例えば、天気アプリが降水確率を80%として予測したとします。この時に10回中約8回はその通りになることを期待しますが、補正されていないモデルでは、下記の2つの問題がしばしば起きます。

過信:モデルが出力する確信度が実際よりも高い。例えば、モデルに99%の確信があっても、実際に降水確率が80%の場合はモデルは過信している。

自信不足:モデルが出力する確信度が実際よりも低い。例えば、モデルが50%の降水確率であると予測していたが、実際にはもっと雨が降っている場合、モデルに自信が足りない。

Calibrationはこのような過信または自信不足の問題を修正します。

Calibration

それでは、実際にモデルを作ってCalibrationを行ってみたいと思います。

シミュレーションデータの生成

from sklearn.datasets import make_classification

X, y = make_classification(n_samples=10000, n_features=100, n_informative=2, random_state=42)

訓練データとテストデータの分割

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

ベースモデルの構築

今回はランダムフォレストのベースモデルを作った後、Calibrationを実施してみます。

import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.calibration import CalibrationDisplay

clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)

CalibrationDisplay.from_estimator(clf, X_test, y_test)
plt.show()
Calibration curve

Calibration Curveを出力しています。黒い点線に近ければ近いほど、信頼度が高いです。ベースモデルでは過信と自信不足の問題が見受けられます。

from sklearn.metrics import brier_score_loss

y_pred = clf.predict_proba(X_test)[:,1]
print('Brier score: ', brier_score_loss(y_test, y_pred))

モデルの精度についてBrier Scoreで測っています。
Brier scoreが低ければ低いほど、モデルに高い精度があることを示しています。補正前のランダムフォレストモデルのBrier scoreは下記の通りになりました。

Brier score: 0.0626651

Calibrationを行う

Calibrationを行うために、CalibratedClassifierCVを使用します。Calibrationの方法として、sigmoidisotonicから選択します。
デフォルトはsigmoidになります。

from sklearn.calibration import CalibratedClassifierCV

calibrated_clf = CalibratedClassifierCV(clf, method='sigmoid')
calibrated_clf.fit(X_train, y_train)

y_pred = calibrated_clf.predict_proba(X_test)[:,1]
print('Brier score: ', brier_score_loss(y_test, y_pred))

CalibrationDisplay.from_estimator(calibrated_clf, X_test, y_test)
plt.show()
sigmoid

sigmoidを選択して補正した後のCalibration curveです。補正前よりも黒い点線に近づいている事がわかります。またBrier scoreは下記の通りでした。こちらも補正前のスコアよりも改善されました。

Brier score: 0.05647428373181069

calibrated_clf = CalibratedClassifierCV(clf, method='isotonic')
calibrated_clf.fit(X_train, y_train)

y_pred = calibrated_clf.predict_proba(X_test)[:,1]
print('Brier score: ', brier_score_loss(y_test, y_pred))

CalibrationDisplay.from_estimator(calibrated_clf, X_test, y_test)
plt.show()
isotonic

こちらはisotonicを選択して補正した後のCalibration curveです。
かなり良い感じに補正されているように見えます。Brier scoreとしても一番良いスコアが出ました。

Brier score: 0.05592473171724596