私もこの質問に興味があり、CalibratedClassifierCV(CCCV)をよりよく理解するためにいくつかの実験を追加したかったです。
既に述べたように、それを使用する2つの方法があります。
#Method 1, train classifier within CCCV
model = CalibratedClassifierCV(my_clf)
model.fit(X_train_val, y_train_val)
#Method 2, train classifier and then use CCCV on DISJOINT set
my_clf.fit(X_train, y_train)
model = CalibratedClassifierCV(my_clf, cv='prefit')
model.fit(X_val, y_val)
または、2番目の方法を試すこともできますが、当てはめたのと同じデータで調整するだけです。
#Method 2 Non disjoint, train classifier on set, then use CCCV on SAME set used for training
my_clf.fit(X_train_val, y_train_val)
model = CalibratedClassifierCV(my_clf, cv='prefit')
model.fit(X_train_val, y_train_val)
ドキュメントはばらばらのセットを使用するように警告しますが、これは検査できるので便利ですmy_clf
(たとえば、coef_
CalibratedClassifierCVオブジェクトからは利用できないを確認するため)。(キャリブレーションされた分類子からこれを取得する方法を知っている人はいますか?---そのうちの3つがあるので、係数を平均しますか?)
私は、これら3つの方法を、完全にテストされたテストセットでのキャリブレーションに関して比較することにしました。
データセットは次のとおりです。
X, y = datasets.make_classification(n_samples=500, n_features=200,
n_informative=10, n_redundant=10,
#random_state=42,
n_clusters_per_class=1, weights = [0.8,0.2])
クラスの不均衡をいくつか投げて、これを困難な問題にするために500サンプルしか提供しませんでした。
各メソッドを試行し、その検量線をプロットするたびに、100回の試行を実行します。
すべての試験でのBrierスコアの箱ひげ図:
サンプル数を10,000に増やす:
500のサンプルに戻って、分類子をNaive Bayesに変更した場合:
これは、較正するのに十分なサンプルではないようです。サンプルを10,000に増やす
完全なコード
print(__doc__)
# Based on code by Alexandre Gramfort <alexandre.gramfort@telecom-paristech.fr>
# Jan Hendrik Metzen <jhm@informatik.uni-bremen.de>
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import brier_score_loss
from sklearn.calibration import CalibratedClassifierCV, calibration_curve
from sklearn.model_selection import train_test_split
def plot_calibration_curve(clf, name, ax, X_test, y_test, title):
y_pred = clf.predict(X_test)
if hasattr(clf, "predict_proba"):
prob_pos = clf.predict_proba(X_test)[:, 1]
else: # use decision function
prob_pos = clf.decision_function(X_test)
prob_pos = \
(prob_pos - prob_pos.min()) / (prob_pos.max() - prob_pos.min())
clf_score = brier_score_loss(y_test, prob_pos, pos_label=y.max())
fraction_of_positives, mean_predicted_value = \
calibration_curve(y_test, prob_pos, n_bins=10, normalize=False)
ax.plot(mean_predicted_value, fraction_of_positives, "s-",
label="%s (%1.3f)" % (name, clf_score), alpha=0.5, color='k', marker=None)
ax.set_ylabel("Fraction of positives")
ax.set_ylim([-0.05, 1.05])
ax.set_title(title)
ax.set_xlabel("Mean predicted value")
plt.tight_layout()
return clf_score
fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, ncols=1, figsize=(6,12))
ax1.plot([0, 1], [0, 1], "k:", label="Perfectly calibrated",)
ax2.plot([0, 1], [0, 1], "k:", label="Perfectly calibrated")
ax3.plot([0, 1], [0, 1], "k:", label="Perfectly calibrated")
scores = {'Method 1':[],'Method 2':[],'Method 3':[]}
fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, ncols=1, figsize=(6,12))
ax1.plot([0, 1], [0, 1], "k:", label="Perfectly calibrated",)
ax2.plot([0, 1], [0, 1], "k:", label="Perfectly calibrated")
ax3.plot([0, 1], [0, 1], "k:", label="Perfectly calibrated")
scores = {'Method 1':[],'Method 2':[],'Method 3':[]}
for i in range(0,100):
X, y = datasets.make_classification(n_samples=10000, n_features=200,
n_informative=10, n_redundant=10,
#random_state=42,
n_clusters_per_class=1, weights = [0.8,0.2])
X_train_val, X_test, y_train_val, y_test = train_test_split(X, y, test_size=0.80,
#random_state=42
)
X_train, X_val, y_train, y_val = train_test_split(X_train_val, y_train_val, test_size=0.80,
#random_state=42
)
#my_clf = GaussianNB()
my_clf = LogisticRegression()
#Method 1, train classifier within CCCV
model = CalibratedClassifierCV(my_clf)
model.fit(X_train_val, y_train_val)
r = plot_calibration_curve(model, "all_cal", ax1, X_test, y_test, "Method 1")
scores['Method 1'].append(r)
#Method 2, train classifier and then use CCCV on DISJOINT set
my_clf.fit(X_train, y_train)
model = CalibratedClassifierCV(my_clf, cv='prefit')
model.fit(X_val, y_val)
r = plot_calibration_curve(model, "all_cal", ax2, X_test, y_test, "Method 2")
scores['Method 2'].append(r)
#Method 3, train classifier on set, then use CCCV on SAME set used for training
my_clf.fit(X_train_val, y_train_val)
model = CalibratedClassifierCV(my_clf, cv='prefit')
model.fit(X_train_val, y_train_val)
r = plot_calibration_curve(model, "all_cal", ax3, X_test, y_test, "Method 2 non Dis")
scores['Method 3'].append(r)
import pandas
b = pandas.DataFrame(scores).boxplot()
plt.suptitle('Brier score')
したがって、ブライアースコアの結果は決定的ではありませんが、曲線によると、2番目の方法を使用するのが最善のようです。