Калибровка вероятности

Как получить откалиброванные вероятности с использованием набора данных по умолчанию для кредитной карты

В этом руководстве я расскажу о том, как получить откалиброванные вероятности с помощью набора данных по умолчанию для кредитных карт, который можно найти здесь, но сначала давайте рассмотрим некоторую предысторию калибровки вероятности и почему это может потребоваться.

Задний план

Калибровка вероятности важна, если требуемый выходной сигнал является истинной вероятностью, возвращенной классификатором, распределение вероятностей которого не соответствует ожидаемому распределению предсказанного класса. Это не тот случай, если требуемые выходные данные классификатора представляют собой ранжирующий или прогнозируемый класс, то есть 0 или 1 для двоичного классификатора.

Не все классификаторы производят хорошо откалиброванные вероятности, а для некоторых классификаторов прогнозируемая вероятность не соответствует выходным данным его функции принятия решения (например, SVC).

Известно, что логистическая регрессия дает хорошо откалиброванные вероятности тогда и только тогда, когда выполняются параметрические допущения модели. Наивный байесовский метод известен тем, что дает вероятности, близкие к своим крайним значениям, то есть 0 и 1, в то время как методы повышения и упаковки известны тем, что производят вероятности, отличные от 0 и 1, поэтому требуют калибровки.

Чтобы лучше понять, насколько хорошо откалиброваны различные классификаторы, настоятельно рекомендую эту страницу. Чтобы продемонстрировать вышеизложенное, давайте воспользуемся двумя разными моделями для прогнозирования дефолтов по кредитным картам.

Чтобы воплотить это в жизнь, давайте сделаем следующее:

  • Загрузите набор данных
  • Примените базовую предварительную обработку
  • Постройте модель случайного леса, которая прогнозирует вероятность того, что физическое лицо не выполнит платеж по кредитной карте.
  • Проверьте вероятность с помощью кривой надежности

Во-первых, давайте импортируем соответствующие пакеты.

import pandas as pd
import numpy as np
from sklearn.calibration import calibration_curve, CalibratedClassifierCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
import matplotlib.pyplot as plt

Затем прочтите набор данных Excel. Ниже приведена предварительная обработка, которую я применил. Для простоты мы будем работать только с числовыми характеристиками, поскольку цель состоит в демонстрации методов калибровки, а не в построении наиболее оптимальной модели.

data = pd.read_excel("credit_card_defaults.xls", header=1)
model_features = list(set(data.columns).difference({"ID", "default payment next month", "SEX", "EDUCATION", "MARRIAGE"}))
target = ["default payment next month"]
X = data[model_features]
y = data[target]
x_train, x_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=12)

В соответствии с передовой практикой я разделил данные на набор для обучения и тестирования, используя разделение для обучения и тестирования Scikit-learn, которое можно найти здесь. Однако, поскольку мы будем подбирать калибровочную модель, нам потребуется другой набор данных, который будет использоваться для этой подгонки, чтобы избежать переобучения. Для этого я дополнительно разделил набор данных поезда на набор для поездов и проверки, как показано ниже:

# Create a hold out dataset to train the calibrated model to prevent overfitting
x_model_train, x_valid, y_model_train, y_valid = train_test_split(x_train, y_train, stratify=y_train, random_state=12)

Затем мы подгоняем модель случайного леса к обучающему набору данных. Здесь можно провести дополнительную работу по определению оптимальных параметров для классификатора случайного леса.

rf_clf = RandomForestClassifier(n_estimators=100, 
                                max_depth=6, 
                                min_samples_split=200, 
                                random_state=12, 
                                class_weight="balanced")
rf_clf.fit(x_model_train, y_model_train)
rf_predictions = rf_clf.predict_proba(x_test)
rf_roc_score = roc_auc_score(y_test, rf_predictions[:,1])
# rf_roc_score = 0.77

Теперь давайте проверим вероятности выхода, посмотрев на кривую надежности. Это популярный способ диагностировать, насколько хорошо откалиброваны вероятности. К счастью для нас, для этого есть реализация sklearn, которую можно найти здесь.

Идеально откалиброванный классификатор имеет график надежности вида y = x.

probablities = np.arange(0, 1.2, 0.2)
fraction_of_positives, mean_predicted_value = calibration_curve(y_test, rf_predictions[:,1], n_bins=10)
plt.plot(mean_predicted_value, fraction_of_positives, label="Random forest")
plt.plot(probablities, probablities, "--", label="Perfectly calibrated")
plt.legend()
plt.xlim([-0.05, 1.05])
plt.title("Reliability curve")
plt.show()

Кривая выше показывает, что выходная вероятность случайного леса может выиграть от калибровки.

Как формально определить хорошо откалиброванную вероятность?

Проще говоря, это вероятности, которые можно интерпретировать как доверительный интервал. Кроме того, считается, что классификатор производит хорошо откалиброванные вероятности, если для экземпляров (точек данных) вероятность получения 0,5, 50% этих экземпляров принадлежит к положительному классу.

Существует два популярных метода калибровки вероятностей:

1. Масштабирование Платта: также известное как логистическая калибровка - это параметрический подход с сигмоидальной калибровочной картой, которая предполагает, что вероятности каждого класса нормально распределены. Проще говоря, этот метод соответствует логистической регрессии для выходных вероятностей для получения более калиброванных вероятностей.

Pro. Хорошо работает с небольшим набором данных.

Con - может привести к худшей калибровке вероятностей, если предположения не верны.

2. Изотоническая регрессия: это непараметрический подход, который, как правило, хорошо работает, поскольку он соответствует кусочно-неубывающей функции прогнозируемым вероятностям, выводимым базовой моделью.

Pro - не делает никаких предположений о вероятностях ввода.

Con - для правильной работы требуется больше точек данных

Для этого набора данных мы будем использовать метод масштабирования Платта, чтобы откалибровать наши вероятности.

Есть 2 способа использования класса sklearn CalibratedClassifierCV:

  1. Передайте подобранную модель и тем самым установите для cv значение prefit. Важно отметить, что данные, используемые при подборе базовой оценки и калибратора, не пересекаются.
  2. Подбираем базовый оценщик с использованием перекрестной проверки k-кратной оценки, и затем вероятности для каждой кратности усредняются для прогнозирования.

Параметр method - это один из двух методов, описанных ранее для калибровки вероятностей, где sigmoid - это масштабирование по Платту, а изотонический - для изотонической регрессии. Документацию Sklearn для класса CalibratedClassifierCV можно найти здесь.

Для этой демонстрации мы будем использовать первый метод с использованием подходящего классификатора случайного леса и масштабирования Platt.

calib_clf = CalibratedClassifierCV(rf_clf, method="sigmoid", cv="prefit")
calib_clf.fit(x_valid, y_valid)
calibrated_predictions = calib_clf.predict_proba(x_test)
calib_roc_score = roc_auc_score(y_test, calibrated_predictions[:,1])

Наконец, давайте проверим кривую надежности для вероятностей случайного леса по сравнению с откалиброванными.

fig = plt.figure(figsize=(10, 7))
for outcomes, models, roc_scores in zip([rf_predictions,calibrated_predictions], 
    ["Random Forest", "Calibrated Model"],
    [rf_roc_score, calib_roc_score]):
    fraction_of_positives, mean_predicted_value =        calibration_curve(y_test, outcomes[:,1])
    plt.plot(mean_predicted_value, fraction_of_positives, label="%s with roc - (%1.2f)" % (models, roc_scores))
    plt.legend()
    plt.title("Reliability curve")
plt.show()

Глядя на график выше, очевидно, что мы получаем лучше откалиброванные вероятности после применения масштабирования Платта без влияния на выбранную нами метрику, которая является оценкой ROC.

Осторожно!

Поскольку масштабирование Платта - это параметрический метод, если вероятности выходной модели не соответствуют предположению, он может дать «откалиброванные» вероятности хуже, чем исходные вероятности от базовой оценки, и всегда стоит проверять логарифмические потери до и после калибровки.

Другие руководства, которые могут вас заинтересовать:

Если вы хотите первым узнавать о нашем новом содержании, включая новые руководства, тематические исследования и другие полезные ресурсы, нажмите здесь!