Scikit cách chính xác để hiệu chỉnh phân loại với CalibratedClassifierCV


14

Scikit có CalibratedClassifierCV , cho phép chúng ta hiệu chỉnh các mô hình của mình trên một cặp X, y cụ thể. Nó cũng nói rõ rằngdata for fitting the classifier and for calibrating it must be disjoint.

Nếu chúng phải rời rạc, việc đào tạo bộ phân loại với những điều sau đây có hợp pháp không?

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

Tôi sợ rằng bằng cách sử dụng cùng một tập huấn luyện, tôi đã phá vỡ disjoint dataquy tắc. Một sự thay thế có thể là có một bộ xác nhận

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

Mà có nhược điểm là để lại ít dữ liệu cho đào tạo. Ngoài ra, nếu CalibratedClassifierCV chỉ phù hợp với các mô hình phù hợp với một tập huấn luyện khác, tại sao các tùy chọn mặc định của nó lại cv=3phù hợp với công cụ ước tính cơ sở? Liệu xác nhận chéo có tự xử lý quy tắc rời rạc không?

Câu hỏi: cách chính xác để sử dụng CalibratedClassifierCV là gì?

Câu trả lời:


17

Có hai điều được đề cập trong các tài liệu CalibratedClassifierCV gợi ý về các cách có thể sử dụng:

base_estimator: Nếu cv = prefit, bộ phân loại phải phù hợp với dữ liệu.

cv: Nếu thông qua trước prefit, thì người ta cho rằng base_estimator đã được trang bị và tất cả dữ liệu được sử dụng để hiệu chuẩn.

Tôi rõ ràng có thể hiểu sai điều này, nhưng có vẻ như bạn có thể sử dụng CCCV (viết tắt của CalibratedClassifierCV) theo hai cách:

Số một:

  • Bạn đào tạo mô hình của bạn như bình thường your_model.fit(X_train, y_train),.
  • Sau đó, bạn tạo cá thể CCCV của bạn , your_cccv = CalibratedClassifierCV(your_model, cv='prefit'). Lưu ý rằng bạn đặt cvthành cờ rằng mô hình của bạn đã phù hợp.
  • Cuối cùng, bạn gọi your_cccv.fit(X_validation, y_validation). Dữ liệu xác nhận này chỉ được sử dụng cho mục đích hiệu chuẩn.

Số hai:

  • Bạn có một mô hình mới, chưa được đào tạo .
  • Sau đó, bạn tạo ra your_cccv=CalibratedClassifierCV(your_untrained_model, cv=3). Thông báo cvbây giờ là số lần.
  • Cuối cùng, bạn gọi your_cccv.fit(X, y). Vì mô hình của bạn chưa được đào tạo, X và y phải được sử dụng cho cả đào tạo và hiệu chuẩn. Cách để đảm bảo dữ liệu 'tách rời' là xác thực chéo: đối với bất kỳ lần cho trước nào, CCCV sẽ phân chia X và y thành dữ liệu huấn luyện và hiệu chuẩn của bạn, để chúng không trùng nhau.

TLDR: Phương pháp một cho phép bạn kiểm soát những gì được sử dụng cho đào tạo và hiệu chuẩn. Phương pháp hai sử dụng xác nhận chéo để thử và tận dụng tối đa dữ liệu của bạn cho cả hai mục đích.


12

Tôi cũng quan tâm đến câu hỏi này và muốn thêm một số thử nghiệm để hiểu rõ hơn về CalibratedClassifierCV (CCCV).

Như đã nói, có hai cách để sử dụng nó.

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

Ngoài ra, chúng tôi có thể thử phương pháp thứ hai nhưng chỉ cần hiệu chỉnh trên cùng một dữ liệu chúng tôi đã trang bị.

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

Mặc dù các tài liệu cảnh báo sử dụng một tập hợp rời rạc, nhưng điều này có thể hữu ích vì nó cho phép bạn kiểm tra my_clf (ví dụ, để xem coef_, không có sẵn từ đối tượng CalibratedClassifierCV). (Có ai biết làm thế nào để có được điều này từ các phân loại hiệu chỉnh --- cho một, có ba trong số chúng vì vậy bạn sẽ có hệ số trung bình không?).

Tôi quyết định so sánh 3 phương pháp này về mặt hiệu chuẩn của chúng trên một bộ thử nghiệm hoàn toàn được tổ chức.

Đây là một bộ dữ liệu:

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

Tôi đã làm mất cân bằng một số lớp và chỉ cung cấp 500 mẫu để làm cho vấn đề này trở nên khó khăn.

Tôi chạy 100 thử nghiệm, mỗi lần thử từng phương pháp và vẽ đồ thị đường chuẩn của nó.

nhập mô tả hình ảnh ở đây

Boxplots của Brier điểm qua tất cả các thử nghiệm:

nhập mô tả hình ảnh ở đây

Tăng số lượng mẫu lên 10.000:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Nếu chúng tôi thay đổi trình phân loại thành Naive Bayes, quay lại 500 mẫu:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Điều này dường như không đủ mẫu để hiệu chỉnh. Tăng mẫu lên 10.000

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Mã đầy đủ

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

Vì vậy, kết quả điểm Brier là không thuyết phục, nhưng theo các đường cong, có vẻ tốt nhất là sử dụng phương pháp thứ hai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.