CalibratedClassifierCV ile sınıflandırıcıları kalibre etmenin doğru yolu


16

Scikit, modellerimizi belirli bir X, y çiftinde kalibre etmemizi sağlayan CalibratedClassifierCV'ye sahiptir . Ayrıca açıkça belirtiyor kidata for fitting the classifier and for calibrating it must be disjoint.

Ayrılmaları gerekiyorsa, sınıflandırıcıyı aşağıdakilerle eğitmek meşru mudur?

model = CalibratedClassifierCV(my_classifier)
model.fit(X_train, y_train)

Aynı eğitim setini kullanarak disjoint datakuralı ihlal ettiğimden korkuyorum . Alternatif bir doğrulama setine sahip olmak olabilir

my_classifier.fit(X_train, y_train)
model = CalibratedClassifierCV(my_classifier, cv='prefit')
model.fit(X_valid, y_valid)

Bu, eğitim için daha az veri bırakmanın dezavantajına sahiptir. Ayrıca, CalibratedClassifierCV'nin yalnızca farklı bir eğitim setine uyan modellere uyması gerekiyorsa cv=3, temel tahminciye de uyan neden varsayılan seçenekler olur ? Çapraz doğrulama ayrık kuralı kendi başına ele alıyor mu?

Soru: CalibratedClassifierCV'yi kullanmanın doğru yolu nedir?

Yanıtlar:


18

CalibratedClassifierCV belgelerinde , kullanılabilecek yollara ilişkin ipucu veren iki şey vardır :

base_estimator: cv = prefit ise, sınıflandırıcı zaten verilere uygun olmalıdır.

cv: “prefit” iletilirse, base_estimator'ın önceden takıldığı ve tüm verilerin kalibrasyon için kullanıldığı varsayılır.

Açıkçası bunu yanlış yorumluyor olabilirim, ancak CCCV'yi (CalibratedClassifierCV için kısa) iki şekilde kullanabilirsiniz:

Bir numara:

  • Modelinizi her zamanki gibi eğitiyorsunuz your_model.fit(X_train, y_train).
  • Ardından, CCCV örneğinizi oluşturun your_cccv = CalibratedClassifierCV(your_model, cv='prefit'). cvModelinizin zaten uygun olduğunu işaretlemek için ayarladığınıza dikkat edin .
  • Sonunda ararsınız your_cccv.fit(X_validation, y_validation). Bu doğrulama verileri yalnızca kalibrasyon amacıyla kullanılır.

İki numaralı:

  • Yeni, eğitimsiz bir modeliniz var.
  • Sonra siz yaratın your_cccv=CalibratedClassifierCV(your_untrained_model, cv=3). Dikkat cvşimdi kat sayısıdır.
  • Sonunda ararsınız your_cccv.fit(X, y). Modeliniz eğitimsiz olduğundan, hem eğitim hem de kalibrasyon için X ve y kullanılmalıdır. Verilerin 'ayrık' olmasını sağlamanın yolu çapraz doğrulamadır: herhangi bir katlama için CCCV, X ve y'yi eğitim ve kalibrasyon verilerinize böler, böylece çakışmazlar.

TLDR: Birinci yöntem, eğitim ve kalibrasyon için nelerin kullanıldığını kontrol etmenizi sağlar. İkinci yöntem, her iki amaçla da verilerinizden en iyi şekilde yararlanmak için çapraz doğrulamayı kullanır.


14

Ben de bu soruya ilgi duyuyorum ve daha iyi CalibratedClassifierCV (CCCV) anlamak için bazı deneyler eklemek istedim.

Daha önce de söylendiği gibi, onu kullanmanın iki yolu vardır.

#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)

Alternatif olarak, ikinci yöntemi deneyebiliriz, ancak taktığımız aynı verileri kalibre edebiliriz.

#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)

Dokümanlar ayrık bir küme kullanmak için uyarsa da, bu daha sonra incelemenize izin verdiği için yararlı olabilir my_clf(örneğin, coef_CalibratedClassifierCV nesnesinden kullanılamayanları görmek için ). (Herkes bunu kalibre edilmiş sınıflandırıcılardan nasıl alacağını biliyor mu? Birincisi, bunlardan üç tane var, bu yüzden ortalama katsayılar olur mu?

Bu 3 yöntemi tamamen yapılan bir test setindeki kalibrasyonları açısından karşılaştırmaya karar verdim.

İşte bir veri kümesi:

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])

Bazı sınıf dengesizliklerine girdim ve bunu zor bir problem haline getirmek için sadece 500 örnek verdim.

Her seferinde her yöntemi denemek ve kalibrasyon eğrisini çizmek için 100 deneme çalıştırıyorum.

resim açıklamasını buraya girin

Brier'in boxplotları tüm denemelerde puanlar:

resim açıklamasını buraya girin

Numune sayısını 10.000'e çıkarmak:

resim açıklamasını buraya girin

resim açıklamasını buraya girin

Sınıflandırıcıyı Naive Bayes olarak değiştirirsek, 500 örneğe geri döneriz:

resim açıklamasını buraya girin

resim açıklamasını buraya girin

Kalibrasyon için yeterli örnek yok gibi görünüyor. Örneklerin 10.000'e çıkarılması

resim açıklamasını buraya girin

resim açıklamasını buraya girin

Tam kod

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')

Bu yüzden Brier skor sonuçları kesin değildir, ancak eğrilere göre ikinci yöntemi kullanmak en iyisidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.