Spec-Zone.ru › scikit-learn

Примечание

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

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

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

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

Авторы: Разработчики scikit-learn SPDX-License-Identifier: BSD-3-Clause

#
# Dataset
# -------
#
# We will use a synthetic binary classification dataset with 100,000 samples
# and 20 features. Of the 20 features, only 2 are informative, 2 are
# redundant (random combinations of the informative features) and the
# remaining 16 are uninformative (random numbers).
#
# Of the 100,000 samples, 100 will be used for model fitting and the remaining
# for testing. Note that this split is quite unusual: the goal is to obtain
# stable calibration curve estimates for models that are potentially prone to
# overfitting. In practice, one should rather use cross-validation with more
# balanced splits but this would make the code of this example more complicated
# to follow.

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, scoring="neg_log_loss", max_iter=1_000
)
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 был настроен на подбор параметра регуляризации для минимизации логарифмической потери также с помощью внутренней перекрестной проверки, чтобы найти наилучшее компромиссное решение для данной модели в условиях малого обучающего набора.

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

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

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

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

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

Ссылки

[1] (1,2)

Прогнозирование хороших вероятностей с помощью контролируемого обучения, А. Никулеску-Мизил и Р. Каруана, ICML 2005

[2]

За пределами независимости: Условия оптимальности простого байесовского классификатора Домингос, П., и Пацзани, М., Труды 13-й международной конференции по машинному обучению. 1996 г.

[3]

Получение откалиброванных оценок вероятности из решающих деревьев и наивных байесовских классификаторов Задрозный, Бьянка, и Чарльз Элкан. Icml. Том 1. 2001 г.

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

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-классовой классификации

Постройте вероятности классов, рассчитанные VotingClassifier

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

Spec-Zone.ru

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