Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить его в браузере с помощью JupyterLite или Binder.

Сравнение калибровки классификаторов

Хорошо откалиброванные классификаторы — это вероятностные классификаторы, для которых результат predict_proba можно напрямую интерпретировать как уровень уверенности. Например, хорошо откалиброванный (бинарный) классификатор должен классифицировать объекты так, чтобы среди объектов, для которых значение predict_proba близко к 0.8, приблизительно 80% действительно принадлежали к положительному классу.

В этом примере мы сравним калибровку четырёх разных моделей: логистической регрессии, гауссовского наивного Байеса, классификатора на основе случайного леса и линейного SVM.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Набор данных

Мы будем использовать синтетический набор данных для бинарной классификации, содержащий 100 000 объектов и 20 признаков. Из 20 признаков только 2 являются информативными, 2 — избыточными (случайные комбинации информативных признаков), а остальные 16 — неинформативными (случайные числа).

Из 100 000 объектов 100 будут использованы для обучения модели, а остальные — для тестирования. Обратите внимание, что такое разделение довольно необычно: цель — получить стабильные оценки кривых калибровки для моделей, потенциально склонных к переобучению. На практике лучше использовать кросс-валидацию с более сбалансированным разделением, но это усложнило бы понимание кода примера.

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

X, y = make_classification(
    n_samples=100_000, n_features=20, n_informative=2, n_redundant=2, random_state=42
)

train_samples = 100  # Samples used for training the models
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    shuffle=False,
    test_size=100_000 - train_samples,
)

Кривые калибровки

Ниже мы обучаем каждую из четырёх моделей на небольшом обучающем наборе данных, а затем строим кривые калибровки (также известные как диаграммы надёжности) на основе предсказанных вероятностей для тестового набора данных. Кривые калибровки строятся путём разбиения предсказанных вероятностей на интервалы, а затем построения графика средней предсказанной вероятности в каждом интервале относительно наблюдаемой частоты («доли положительных объектов»). Под кривой калибровки мы строим гистограмму распределения предсказанных вероятностей, а точнее — количества объектов в каждом интервале предсказанных вероятностей.

import numpy as np

from sklearn.svm import LinearSVC


class NaivelyCalibratedLinearSVC(LinearSVC):
    """LinearSVC with `predict_proba` method that naively scales
    `decision_function` output."""

    def fit(self, X, y):
        super().fit(X, y)
        df = self.decision_function(X)
        self.df_min_ = df.min()
        self.df_max_ = df.max()

    def predict_proba(self, X):
        """Min-max scale output of `decision_function` to [0,1]."""
        df = self.decision_function(X)
        calibrated_df = (df - self.df_min_) / (self.df_max_ - self.df_min_)
        proba_pos_class = np.clip(calibrated_df, 0, 1)
        proba_neg_class = 1 - proba_pos_class
        proba = np.c_[proba_neg_class, proba_pos_class]
        return proba
from sklearn.calibration import CalibrationDisplay
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegressionCV
from sklearn.naive_bayes import GaussianNB

# Define the classifiers to be compared in the study.
#
# Note that we use a variant of the logistic regression model that can
# automatically tune its regularization parameter.
#
# For a fair comparison, we should run a hyper-parameter search for all the
# classifiers but we don't do it here for the sake of keeping the example code
# concise and fast to execute.
lr = LogisticRegressionCV(
    Cs=np.logspace(-6, 6, 101),
    cv=10,
    l1_ratios=(0,),
    scoring="neg_log_loss",
    max_iter=1_000,
    use_legacy_attributes=False,
)
gnb = GaussianNB()
svc = NaivelyCalibratedLinearSVC(C=1.0)
rfc = RandomForestClassifier(random_state=42)

clf_list = [
    (lr, "Logistic Regression"),
    (gnb, "Naive Bayes"),
    (svc, "SVC"),
    (rfc, "Random forest"),
]
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

fig = plt.figure(figsize=(10, 10))
gs = GridSpec(4, 2)
colors = plt.get_cmap("Dark2")

ax_calibration_curve = fig.add_subplot(gs[:2, :2])
calibration_displays = {}
markers = ["^", "v", "s", "o"]
for i, (clf, name) in enumerate(clf_list):
    clf.fit(X_train, y_train)
    display = CalibrationDisplay.from_estimator(
        clf,
        X_test,
        y_test,
        n_bins=10,
        name=name,
        ax=ax_calibration_curve,
        color=colors(i),
        marker=markers[i],
    )
    calibration_displays[name] = display

ax_calibration_curve.grid()
ax_calibration_curve.set_title("Calibration plots")

# Add histogram
grid_positions = [(2, 0), (2, 1), (3, 0), (3, 1)]
for i, (_, name) in enumerate(clf_list):
    row, col = grid_positions[i]
    ax = fig.add_subplot(gs[row, col])

    ax.hist(
        calibration_displays[name].y_prob,
        range=(0, 1),
        bins=10,
        label=name,
        color=colors(i),
    )
    ax.set(title=name, xlabel="Mean predicted probability", ylabel="Count")

plt.tight_layout()
plt.show()
Calibration plots, Logistic Regression, Naive Bayes, SVC, Random forest

Анализ результатов

LogisticRegressionCV выдаёт достаточно хорошо откалиброванные предсказания, несмотря на малый размер обучающего набора: среди четырёх моделей её кривая надёжности ближе всего к диагонали.

Логистическая регрессия обучается путём минимизации логарифмической потери, которая является строго правильной функцией оценки: в пределе бесконечного объёма обучающих данных строго правильные функции оценки минимизируются моделью, предсказывающей истинные условные вероятности. Следовательно, такая (гипотетическая) модель была бы идеально откалибрована. Однако использование правильной функции оценки в качестве целевой функции обучения само по себе не гарантирует хорошую калибровку модели: даже при очень большом обучающем наборе логистическая регрессия может быть плохо откалибрована, если регуляризация слишком сильна или если выбор и предварительная обработка входных признаков приводят к неправильной спецификации модели (например, если истинная граница принятия решения в наборе данных является сильно нелинейной функцией входных признаков).

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

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

Остальные методы выдают менее хорошо откалиброванные вероятности:

  • GaussianNB в этом конкретном наборе данных склонен сдвигать вероятности к 0 или 1 (см. гистограмму), то есть демонстрирует избыточную уверенность. Главная причина в том, что уравнение наивного Байеса даёт правильную оценку вероятностей только при выполнении предположения об условной независимости признаков [2]. Однако признаки могут быть коррелированы, как и в этом наборе данных, содержащем 2 признака, полученных как случайные линейные комбинации информативных признаков. Эти коррелированные признаки фактически «учитываются дважды», из-за чего предсказанные вероятности сдвигаются к 0 и 1 [3]. Однако обратите внимание, что изменение начального значения генератора случайных чисел, используемого для создания набора данных, может привести к сильно различающимся результатам для оценщика наивного Байеса.
  • LinearSVC не является естественным вероятностным классификатором. Чтобы интерпретировать его предсказания как вероятности, мы без дополнительных предположений масштабировали результат decision_function в диапазон [0, 1] с помощью масштабирования min-max в классе-обёртке NaivelyCalibratedLinearSVC, определённом выше. На этих данных оценщик демонстрирует типичную сигмоидальную кривую калибровки: предсказания выше 0.5 соответствуют объектам с ещё большей фактической долей положительного класса (выше диагонали), а предсказания ниже 0.5 — ещё меньшим долям положительного класса (ниже диагонали). Такие неуверенные предсказания типичны для методов с максимальным зазором [1].
  • На гистограмме предсказаний RandomForestClassifier видны пики примерно на вероятностях 0.2 и 0.9, а вероятности, близкие к 0 или 1, встречаются очень редко. Объяснение этому дано в работе [1]: «Методам, таким как бэггинг и случайные леса, усредняющим предсказания базового набора моделей, может быть сложно выдавать предсказания, близкие к 0 и 1, поскольку дисперсия базовых моделей смещает предсказания, которые должны быть близки к нулю или единице, в сторону от этих значений. Поскольку предсказания ограничены интервалом [0, 1], ошибки, обусловленные дисперсией, вблизи нуля и единицы имеют тенденцию быть односторонними. Например, если модель должна предсказать p = 0 для некоторого случая, бэггинг может добиться этого, только если все деревья в ансамбле предсказывают ноль. Если добавить шум к деревьям, предсказания которых усредняются при бэггинге, из-за этого шума некоторые деревья будут предсказывать значения больше 0 для данного случая, тем самым сдвигая среднее предсказание ансамбля с бэггингом от нуля. Этот эффект особенно заметен в случайных лесах, поскольку деревья базового уровня, обученные в случайном лесу, имеют сравнительно высокую дисперсию из-за выбора подмножества признаков». Этот эффект может приводить к недостаточной уверенности случайных лесов. Несмотря на это возможное смещение, обратите внимание, что сами деревья обучаются с минимизацией критерия Джини или энтропии, и оба критерия приводят к разбиениям, минимизирующим правильные функции оценки: оценку Бриера или логарифмическую потерю соответственно. Подробнее см. в руководстве пользователя. Это может объяснить, почему на этом конкретном примере модель демонстрирует достаточно хорошую кривую калибровки. Действительно, модель случайного леса не демонстрирует существенно большую неуверенность, чем модель логистической регрессии.

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

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

Литература

[1] (1,2)

Предсказание хороших вероятностей с помощью обучения с учителем, A. Niculescu-Mizil & R. Caruana, ICML 2005

[2]

За пределами независимости: условия оптимальности простого байесовского классификатора Domingos, P., & Pazzani, M., Proc. 13th Intl. Conf. Machine Learning. 1996.

[3]

Получение откалиброванных оценок вероятностей с помощью деревьев решений и наивных байесовских классификаторов Zadrozny, Bianca, and Charles Elkan. Icml. Vol. 1. 2001.

Общее время выполнения скрипта: (0 минут 3.875 секунды)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_compare_calibration.ipynb

Download Python source code: plot_compare_calibration.py

Download zipped: plot_compare_calibration.zip

Связанные примеры

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

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

Калибровка вероятностей для классификации на 3 класса

Анализ сходимости моделей логистической регрессии со штрафом

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/calibration/plot_compare_calibration.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API