Spec-Zone.ru › scikit-learn

Примечание

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

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

В этом примере показано, как сигмоидальная калибровка изменяет предсказанные вероятности в задаче классификации на 3 класса. Показан стандартный 2-симплекс, три вершины которого соответствуют трём классам. Стрелки указывают направление от векторов вероятностей, предсказанных некалиброванным классификатором, к векторам вероятностей, предсказанным тем же классификатором после сигмоидальной калибровки на отложенной проверочной выборке. Цвета обозначают истинный класс объекта (красный: класс 1, зелёный: класс 2, синий: класс 3).

Данные

Ниже мы создадим набор данных для классификации из 2000 образцов, 2 признаков и 3 целевых классов. Затем разделим данные следующим образом:

  • обучающая выборка: 600 образцов (для обучения классификатора)
  • проверочная выборка: 400 образцов (для калибровки предсказанных вероятностей)
  • тестовая выборка: 1000 образцов

Обратите внимание, что мы также создаём X_train_valid и y_train_valid, включающие обе подвыборки: обучающую и проверочную. Они используются, когда мы хотим только обучить классификатор, но не калибровать предсказанные вероятности.

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

import numpy as np

from sklearn.datasets import make_blobs

np.random.seed(0)

X, y = make_blobs(
    n_samples=2000, n_features=2, centers=3, random_state=42, cluster_std=5.0
)
X_train, y_train = X[:600], y[:600]
X_valid, y_valid = X[600:1000], y[600:1000]
X_train_valid, y_train_valid = X[:1000], y[:1000]
X_test, y_test = X[1000:], y[1000:]

Обучение и калибровка

Сначала мы обучим RandomForestClassifier с 25 базовыми оценщиками (деревьями) на объединённых обучающих и проверочных данных (1000 образцов). Это некалиброванный классификатор.

from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier(n_estimators=25)
clf.fit(X_train_valid, y_train_valid)
RandomForestClassifier(n_estimators=25)
В среде Jupyter повторно запустите эту ячейку, чтобы отобразить представление HTML, или доверьте работу с блокнотом.
На GitHub представление HTML не отображается. Попробуйте открыть эту страницу с помощью nbviewer.org.
Параметры
n_estimators n_estimators: int, default=100

Количество деревьев в ансамбле.

.. versionchanged:: 0.22
Значение `n_estimators` по умолчанию изменено с 10 на 100
в версии 0.22.
25
criterion criterion: {"gini", "entropy", "log_loss"}, default="gini"

Функция для измерения качества разбиения. Поддерживаются критерии
"gini" для неоднородности Джини и "log_loss" и "entropy" — оба для
информационного выигрыша Шеннона; см. :ref:`tree_mathematical_formulation`.
Примечание: этот параметр относится к деревьям.
'gini'
max_depth max_depth: int, default=None

Максимальная глубина дерева. Если None, узлы расширяются, пока
все листья не станут чистыми или пока каждый лист не будет содержать
меньше образцов, чем min_samples_split.
None
min_samples_split min_samples_split: int or float, default=2

Минимальное количество образцов, необходимое для разделения внутреннего узла:

- Если задано целое число, `min_samples_split` рассматривается как минимальное количество.
- Если задано число с плавающей запятой, `min_samples_split` — это доля, а
`ceil(min_samples_split * n_samples)` — минимальное
количество образцов для каждого разбиения.

.. versionchanged:: 0.18
Добавлена поддержка значений с плавающей запятой, задающих доли.
2
min_samples_leaf min_samples_leaf: int or float, default=1

Минимальное количество образцов, необходимое для узла-листа.
Точка разбиения на любой глубине рассматривается, только если в каждой из
левой и правой ветвей остаётся не менее ``min_samples_leaf`` обучающих образцов.
Это может сглаживать модель,
особенно в задачах регрессии.

- Если задано целое число, `min_samples_leaf` рассматривается как минимальное количество.
- Если задано число с плавающей запятой, `min_samples_leaf` — это доля, а
`ceil(min_samples_leaf * n_samples)` — минимальное
количество образцов для каждого узла.

.. versionchanged:: 0.18
Добавлена поддержка значений с плавающей запятой, задающих доли.
1
min_weight_fraction_leaf min_weight_fraction_leaf: float, default=0.0

Минимальная взвешенная доля суммы весов (всех входных
образцов), необходимая для узла-листа. Если sample_weight не задан,
все образцы имеют одинаковый вес.
0.0
max_features max_features: {"sqrt", "log2", None}, int or float, default="sqrt"

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

- Если задано целое число, при каждом разбиении рассматривается `max_features` признаков.
- Если задано число с плавающей запятой, `max_features` — это доля, а
при каждом разбиении рассматривается `max(1, int(max_features * n_features_in_))` признаков.
- Если задано "sqrt", то `max_features=sqrt(n_features)`.
- Если задано "log2", то `max_features=log2(n_features)`.
- Если задано None, то `max_features=n_features`.

.. versionchanged:: 1.1
Значение `max_features` по умолчанию изменено с `"auto"` на `"sqrt"`.

Примечание: поиск разбиения продолжается, пока не будет найдено хотя бы одно
допустимое разбиение образцов узла, даже если для этого потребуется
фактически проверить больше признаков, чем указано в ``max_features``.
'sqrt'
max_leaf_nodes max_leaf_nodes: int, default=None

Выращивать деревья с ``max_leaf_nodes`` в порядке наилучшего первого.
Наилучшие узлы определяются по относительному снижению неоднородности.
Если задано None, количество узлов-листьев не ограничено.
None
min_impurity_decrease min_impurity_decrease: float, default=0.0

Узел будет разделён, если это разбиение приводит к снижению неоднородности
на величину, большую или равную этому значению.

Уравнение взвешенного снижения неоднородности имеет следующий вид::

N_t / N * (impurity - N_t_R / N_t * right_impurity
- N_t_L / N_t * left_impurity)

где ``N`` — общее количество образцов, ``N_t`` — количество
образцов в текущем узле, ``N_t_L`` — количество образцов в левом дочернем узле,
а ``N_t_R`` — количество образцов в правом дочернем узле.

Если передан ``sample_weight``, значения ``N``, ``N_t``, ``N_t_R`` и ``N_t_L``
обозначают взвешенные суммы.

.. versionadded:: 0.19
0.0
bootstrap bootstrap: bool, default=True

Используются ли при построении деревьев выборки, полученные бутстрэпом. Если False,
для построения каждого дерева используется весь набор данных.
True
oob_score oob_score: bool or callable, default=False

Использовать ли вневыборочные образцы для оценки обобщающей способности.
По умолчанию используется :func:`~sklearn.metrics.accuracy_score`.
Чтобы использовать пользовательскую метрику, передайте вызываемый объект с сигнатурой `metric(y_true, y_pred)`. Доступно только при `bootstrap=True`.

Пример оценки ошибки вневыборочных (OOB) данных приведён в примере
:ref:`sphx_glr_auto_examples_ensemble_plot_ensemble_oob.py`.
False
n_jobs n_jobs: int, default=None

Количество задач, выполняемых параллельно. Методы :meth:`fit`, :meth:`predict`,
:meth:`decision_path` и :meth:`apply` распараллеливаются по
деревьям. ``None`` означает 1, если только не используется контекст :obj:`joblib.parallel_backend`.
``-1`` означает использование всех процессоров. Подробнее см. :term:`Глоссарий
<n_jobs>`.
None
random_state random_state: int, RandomState instance or None, default=None

Управляет как случайностью бутстрэп-выборки, используемой
при построении деревьев (если ``bootstrap=True``), так и выбором
признаков, рассматриваемых при поиске наилучшего разбиения в каждом узле
(если ``max_features < n_features``).
Подробнее см. :term:`Глоссарий <random_state>`.
None
verbose verbose: int, default=0

Управляет подробностью вывода при обучении и предсказании.
0
warm_start warm_start: bool, default=False

Если задано ``True``, используется результат предыдущего вызова fit
и в ансамбль добавляются новые оценщики; в противном случае обучается
совершенно новый лес. Подробнее см. :term:`Глоссарий <warm_start>` и
:ref:`tree_ensemble_warm_start`.
False
class_weight class_weight: {"balanced", "balanced_subsample"}, dict or list of dicts, default=None

Веса классов задаются в виде ``{class_label: weight}``.
Если параметр не задан, предполагается, что вес всех классов равен единице. Для
задач с несколькими выходами можно передать список словарей в том же
порядке, что и столбцы y.

Обратите внимание: для задач с несколькими выходами (включая многометочную классификацию) веса следует
задавать для каждого класса каждого столбца в отдельном словаре. Например,
для многометочной классификации с четырьмя классами следует указать веса
[{0: 1, 1: 1}, {0: 1, 1: 5}, {0: 1, 1: 1}, {0: 1, 1: 1}], а не
[{1:1}, {2:5}, {3:1}, {4:1}].

Режим "balanced" использует значения y для автоматической корректировки
весов, обратно пропорциональных частотам классов во входных данных,
по формуле ``n_samples / (n_classes * np.bincount(y))``

Режим "balanced_subsample" аналогичен "balanced", но
веса вычисляются на основе бутстрэп-выборки для каждого выращенного дерева.

Для нескольких выходов веса каждого столбца y перемножаются.

Обратите внимание: если задан sample_weight, эти веса перемножаются с ним
(переданным через метод fit).
None
ccp_alpha ccp_alpha: non-negative float, default=0.0

Параметр сложности, используемый для минимальной обрезки по критерию стоимости и сложности. Будет выбрано поддерево
с наибольшей стоимостью сложности, меньшей, чем
``ccp_alpha``. По умолчанию обрезка не выполняется. Подробнее см.
:ref:`minimal_cost_complexity_pruning`. Пример такой обрезки приведён в
:ref:`sphx_glr_auto_examples_tree_plot_cost_complexity_pruning.py`.

.. versionadded:: 0.22
0.0
max_samples max_samples: int or float, default=None

Если bootstrap равно True, количество образцов, выбираемых из X
для обучения каждого базового оценщика.

- Если задано None (по умолчанию), выбирается `X.shape[0]` образцов независимо от
`sample_weight`.
- Если задано целое число, выбирается `max_samples` образцов.
- Если задано число с плавающей запятой, выбирается `max_samples * X.shape[0]` невзвешенных образцов
или `max_samples * sample_weight.sum()` взвешенных образцов.

.. versionadded:: 0.22

.. versionchanged:: 1.9
Для взвешенных образцов значение `max_samples` с плавающей запятой рассчитывается относительно `sample_weight.sum()`, а не
`X.shape[0]`.
None
monotonic_cst monotonic_cst: array-like of int of shape (n_features), default=None

Задаёт ограничение монотонности для каждого признака.
- 1: монотонное возрастание
- 0: без ограничений
- -1: монотонное убывание

Если monotonic_cst равно None, ограничения не применяются.

Ограничения монотонности не поддерживаются для:
- классификации на несколько классов (то есть когда `n_classes > 2`),
- классификации с несколькими выходами (то есть когда `n_outputs_ > 1`).

Ограничения применяются к вероятности положительного класса.

Подробнее см. :ref:`Руководство пользователя <monotonic_cst_gbdt>`.

.. versionadded:: 1.4
None
Обученные атрибуты
Имя Тип Значение
classes_ classes_: ndarray of shape (n_classes,) or a list of such arrays

Метки классов (задача с одним выходом) или список массивов
с метками классов (задача с несколькими выходами).
ndarray[int64](3,) [0,1,2]
estimator_ estimator_: :class:`~sklearn.tree.DecisionTreeClassifier`

Шаблон дочернего оценщика, используемый для создания набора обученных
подоценщиков.

.. versionadded:: 1.2
Имя `base_estimator_` изменено на `estimator_`.
DecisionTreeClassifier DecisionTreeClassifier()
estimators_ estimators_: list of DecisionTreeClassifier

Набор обученных подоценщиков.
list [DecisionTreeC...ate=209652396), DecisionTreeC...ate=398764591), DecisionTreeC...ate=924231285), DecisionTreeC...te=1478610112), ...]
estimators_samples_ estimators_samples_: list of arrays

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

.. versionadded:: 1.4
list [array([236, 2... dtype=int32), array([107, 1... dtype=int32), array([301, 5... dtype=int32), array([900, 3... dtype=int32), ...]
feature_importances_ feature_importances_: ndarray of shape (n_features,)

Важность признаков, рассчитанная на основе неоднородности.
Чем выше значение, тем важнее признак.
Важность признака вычисляется как (нормированное)
общее снижение критерия, обеспеченное этим признаком. Этот показатель также
известен как важность Джини.

Предупреждение: важность признаков на основе неоднородности может вводить в заблуждение для
признаков с большим количеством уникальных значений. В качестве альтернативы см.
:func:`sklearn.inspection.permutation_importance`.
ndarray[float64](2,) [0.44,0.56]
n_classes_ n_classes_: int or list

Количество классов (задача с одним выходом) или список, содержащий
количество классов для каждого выхода (задача с несколькими выходами).
int 3
n_features_in_ n_features_in_: int

Количество признаков, использованных при :term:`обучении`.

.. versionadded:: 0.24
int 2
n_outputs_ n_outputs_: int

Количество выходов при выполнении ``fit``.
int 1


Чтобы обучить калиброванный классификатор, мы берём тот же RandomForestClassifier, но обучаем его только на обучающей подвыборке (600 образцов), а затем калибруем с помощью method='sigmoid', используя проверочную подвыборку (400 образцов) в два этапа.

from sklearn.calibration import CalibratedClassifierCV
from sklearn.frozen import FrozenEstimator

clf = RandomForestClassifier(n_estimators=25)
clf.fit(X_train, y_train)
cal_clf = CalibratedClassifierCV(FrozenEstimator(clf), method="sigmoid")
cal_clf.fit(X_valid, y_valid)
CalibratedClassifierCV(estimator=FrozenEstimator(estimator=RandomForestClassifier(n_estimators=25)))
В среде Jupyter повторно выполните эту ячейку, чтобы отобразить HTML-представление, или доверьте выполнение блокноту.
На GitHub HTML-представление не отображается. Попробуйте открыть эту страницу с помощью nbviewer.org.
Параметры
estimator estimator: экземпляр оценщика, по умолчанию=None

Классификатор, выходные данные которого необходимо откалибровать, чтобы получить более
точные результаты `predict_proba`. По умолчанию используется классификатор
:class:`~sklearn.svm.LinearSVC`.

.. versionadded:: 1.2
FrozenEstimat...stimators=25))
method method: {'sigmoid', 'isotonic', 'temperature'}, по умолчанию='sigmoid'

Метод калибровки. Возможные варианты:

- 'sigmoid' — метод Платта (то есть модель бинарной логистической
регрессии).
- 'isotonic' — непараметрический подход.
- 'temperature' — масштабирование температуры.

Методы калибровки sigmoid и isotonic изначально поддерживают только бинарные
классификаторы, а для многоклассовой классификации используют стратегию «один против остальных» (OvR)
с последующей перенормировкой, то есть корректировкой вероятностей после
калибровки, чтобы их сумма равнялась 1.

В отличие от них, масштабирование температуры естественным образом поддерживает многоклассовую калибровку, применяя
`softmax(classifier_logits/T)` со значением `T` (температуры),
которое минимизирует log loss.

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

Калибровка isotonic не рекомендуется, если число калибровочных объектов
слишком мало ``(≪1000)``, поскольку в этом случае она склонна к переобучению.

.. versionchanged:: 1.8
Добавлен вариант 'temperature'.
'sigmoid'
cv cv: int, генератор перекрёстной проверки или итерируемый объект, по умолчанию=None

Определяет стратегию разбиения для перекрёстной проверки.
Возможные значения cv:

- None — использовать перекрёстную проверку с 5 блоками по умолчанию,
- целое число — задать количество блоков,
- :term:`разбиватель CV`,
- итерируемый объект, возвращающий разбиения (train, test) в виде массивов индексов.

Для целочисленных значений и None, если ``y`` — бинарный или многоклассовый,
используется :class:`~sklearn.model_selection.StratifiedKFold`. Если ``y``
не является ни бинарным, ни многоклассовым, используется :class:`~sklearn.model_selection.KFold`.

Сведения о различных стратегиях перекрёстной проверки, которые можно использовать здесь,
см. в :ref:`Руководстве пользователя <cross_validation>`.

.. versionchanged:: 0.22
Значение ``cv`` по умолчанию изменено с 3 блоков на 5, если задано None.
None
n_jobs n_jobs: int, по умолчанию=None

Количество заданий, выполняемых параллельно.
``None`` означает 1, если только не используется контекст :obj:`joblib.parallel_backend`.
``-1`` означает использование всех процессоров.

Клоны базового оценщика обучаются параллельно на итерациях перекрёстной
проверки.

Подробнее см. :term:`Глоссарий <n_jobs>`.

.. versionadded:: 0.24
None
ensemble ensemble: bool или "auto", по умолчанию="auto"

Определяет способ обучения калибратора.

"auto" задаёт `False`, если `estimator` является
:class:`~sklearn.frozen.FrozenEstimator`, и `True` в противном случае.

Если задано `True`, для каждого блока `cv` оценщик обучается на обучающих данных,
а калибровка выполняется на тестовых данных. Итоговый оценщик
представляет собой ансамбль из `n_cv` обученных пар классификатора и калибратора, где
`n_cv` — количество блоков перекрёстной проверки. Результат — это
среднее предсказанных вероятностей всех пар.

Если задано `False`, параметр `cv` используется для вычисления несмещённых предсказаний с помощью
:func:`~sklearn.model_selection.cross_val_predict`; затем эти предсказания
используются для калибровки. Во время предсказания используется
`estimator`, обученный на всех данных.
Обратите внимание, что этот метод также реализован внутри оценщиков
:mod:`sklearn.svm` с параметром `probabilities=True`.

.. versionadded:: 0.24

.. versionchanged:: 1.6
Добавлен вариант `"auto"`, установленный по умолчанию.
'auto'
Обученные атрибуты
Имя Тип Значение
calibrated_classifiers_ calibrated_classifiers_: список (длина равна cv или 1, если `ensemble=False`)

Список пар классификатора и калибратора.

- Если задано `ensemble=True`, содержит `n_cv` обученных пар `estimator` и калибратора.
`n_cv` — количество блоков перекрёстной проверки.
- Если задано `ensemble=False`, содержит `estimator`, обученный на всех данных, и обученный
калибратор.

.. versionchanged:: 0.24
Случай с одним откалиброванным классификатором при `ensemble=False`.
list [<sklearn.cali...x7841646428e0>]
classes_ classes_: ndarray формы (n_classes,)

Метки классов.
ndarray[int64](3,) [0,1,2]
n_features_in_ n_features_in_: int

Количество признаков, использованных во время :term:`fit`. Атрибут определяется только в том случае, если
базовый оценщик предоставляет такой атрибут при обучении.

.. versionadded:: 0.24
int 2
FrozenEstimator(estimator=RandomForestClassifier(n_estimators=25))
RandomForestClassifier(n_estimators=25)
Параметры
n_estimators n_estimators: int, по умолчанию=100

Количество деревьев в лесу.

.. versionchanged:: 0.22
Значение ``n_estimators`` по умолчанию изменено с 10 на 100
в версии 0.22.
25
criterion criterion: {"gini", "entropy", "log_loss"}, по умолчанию="gini"

Функция для измерения качества разбиения. Поддерживаются критерии
"gini" для примеси Джини и "log_loss" и "entropy" для
информационного выигрыша Шеннона; см. :ref:`tree_mathematical_formulation`.
Примечание: этот параметр относится к конкретному дереву.
'gini'
max_depth max_depth: int, по умолчанию=None

Максимальная глубина дерева. Если значение равно None, узлы расширяются до тех пор,
пока все листья не станут чистыми или не будут содержать менее
min_samples_split образцов.
None
min_samples_split min_samples_split: int или float, по умолчанию=2

Минимальное количество образцов, необходимое для разделения внутреннего узла:

- Если задано значение int, `min_samples_split` задаёт минимальное количество.
- Если задано значение float, `min_samples_split` — это доля, а
`ceil(min_samples_split * n_samples)` — минимальное
количество образцов для каждого разбиения.

.. versionchanged:: 0.18
Добавлена возможность задавать доли значениями типа float.
2
min_samples_leaf min_samples_leaf: int или float, по умолчанию=1

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

- Если задано значение int, `min_samples_leaf` задаёт минимальное количество.
- Если задано значение float, `min_samples_leaf` — это доля, а
`ceil(min_samples_leaf * n_samples)` — минимальное
количество образцов для каждого узла.

.. versionchanged:: 0.18
Добавлена возможность задавать доли значениями типа float.
1
min_weight_fraction_leaf min_weight_fraction_leaf: float, по умолчанию=0.0

Минимальная взвешенная доля суммы весов (всех
входных образцов), необходимая в листовом узле. Если sample_weight не задан, образцы
имеют одинаковый вес.
0.0
max_features max_features: {"sqrt", "log2", None}, int или float, по умолчанию="sqrt"

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

- Если задано значение int, при каждом разбиении рассматриваются `max_features` признаков.
- Если задано значение float, `max_features` — это доля, и
при каждом разбиении рассматривается `max(1, int(max_features * n_features_in_))` признаков.
- Если задано значение "sqrt", то `max_features=sqrt(n_features)`.
- Если задано значение "log2", то `max_features=log2(n_features)`.
- Если задано значение None, то `max_features=n_features`.

.. versionchanged:: 1.1
Значение `max_features` по умолчанию изменено с `"auto"` на `"sqrt"`.

Примечание: поиск разбиения продолжается, пока не будет найдено хотя бы одно
допустимое разбиение образцов узла, даже если для этого придётся фактически
проверить больше признаков, чем ``max_features``.
'sqrt'
max_leaf_nodes max_leaf_nodes: int, по умолчанию=None

Выращивать деревья, ограничивая число листьев значением ``max_leaf_nodes``, в порядке наилучшего результата.
Наилучшие узлы определяются относительным уменьшением примеси.
Если значение равно None, число листовых узлов не ограничено.
None
min_impurity_decrease min_impurity_decrease: float, по умолчанию=0.0

Узел будет разделён, если это разбиение приводит к уменьшению примеси,
большему или равному этому значению.

Уравнение для взвешенного уменьшения примеси имеет следующий вид::

N_t / N * (impurity - N_t_R / N_t * right_impurity
- N_t_L / N_t * left_impurity)

где ``N`` — общее количество образцов, ``N_t`` — количество
образцов в текущем узле, ``N_t_L`` — количество образцов в левом дочернем узле,
а ``N_t_R`` — количество образцов в правом дочернем узле.

Если передан ``sample_weight``, ``N``, ``N_t``, ``N_t_R`` и ``N_t_L``
обозначают взвешенные суммы.

.. versionadded:: 0.19
0.0
bootstrap bootstrap: bool, по умолчанию=True

Используются ли бутстрэп-выборки при построении деревьев. Если значение равно False,
для построения каждого дерева используется весь набор данных.
True
oob_score oob_score: bool или callable, по умолчанию=False

Использовать ли вневыборочные образцы для оценки качества обобщения.
По умолчанию используется :func:`~sklearn.metrics.accuracy_score`.
Чтобы использовать пользовательскую метрику, передайте вызываемый объект с сигнатурой `metric(y_true, y_pred)`. Доступно только при `bootstrap=True`.

Пример оценки ошибки на вневыборочных образцах (OOB) см. в примере
:ref:`sphx_glr_auto_examples_ensemble_plot_ensemble_oob.py`.
False
n_jobs n_jobs: int, по умолчанию=None

Количество задач, выполняемых параллельно. Методы :meth:`fit`, :meth:`predict`,
:meth:`decision_path` и :meth:`apply` распараллеливаются по
деревьям. ``None`` означает 1, кроме случаев, когда используется контекст
:obj:`joblib.parallel_backend`. ``-1`` означает использование всех процессоров. Подробнее см. :term:`Глоссарий
<n_jobs>`.
None
random_state random_state: int, экземпляр RandomState или None, по умолчанию=None

Управляет как случайностью при формировании бутстрэп-выборок, используемых
при построении деревьев (если ``bootstrap=True``), так и выбором
признаков, рассматриваемых при поиске наилучшего разбиения в каждом узле
(если ``max_features < n_features``).
Подробнее см. :term:`Глоссарий <random_state>`.
None
verbose verbose: int, по умолчанию=0

Управляет подробностью вывода при обучении и предсказании.
0
warm_start warm_start: bool, по умолчанию=False

Если задано значение ``True``, используется результат предыдущего вызова fit
и в ансамбль добавляются новые оценщики; в противном случае обучается полностью
новый лес. Подробнее см. :term:`Глоссарий <warm_start>` и
:ref:`tree_ensemble_warm_start`.
False
class_weight class_weight: {"balanced", "balanced_subsample"}, dict или список словарей, по умолчанию=None

Веса классов в формате ``{class_label: weight}``.
Если параметр не задан, предполагается, что вес всех классов равен единице. Для
задач с несколькими выходами можно передать список словарей в том же
порядке, что и столбцы y.

Обратите внимание: для нескольких выходов (включая многометочную классификацию) веса следует
задавать для каждого класса каждого столбца в отдельном словаре. Например,
для многометочной классификации с четырьмя классами следует указать веса
[{0: 1, 1: 1}, {0: 1, 1: 5}, {0: 1, 1: 1}, {0: 1, 1: 1}], а не
[{1:1}, {2:5}, {3:1}, {4:1}].

Режим "balanced" использует значения y для автоматической корректировки
весов, обратно пропорциональных частотам классов во входных данных,
по формуле ``n_samples / (n_classes * np.bincount(y))``

Режим "balanced_subsample" аналогичен "balanced", но
веса вычисляются на основе бутстрэп-выборки для каждого построенного дерева.

Для нескольких выходов веса каждого столбца y перемножаются.

Обратите внимание: если задан sample_weight, эти веса будут перемножены с sample_weight (передаваемым
через метод fit).
None
ccp_alpha ccp_alpha: неотрицательное значение float, по умолчанию=0.0

Параметр сложности, используемый для минимальной обрезки по критерию стоимости и сложности. Будет выбрано
поддерево с наибольшей сложностью, меньшей, чем
``ccp_alpha``. По умолчанию обрезка не выполняется. Подробнее см.
:ref:`minimal_cost_complexity_pruning`. Пример такой обрезки см. в
:ref:`sphx_glr_auto_examples_tree_plot_cost_complexity_pruning.py`.

.. versionadded:: 0.22
0.0
max_samples max_samples: int или float, по умолчанию=None

Если bootstrap равно True, количество образцов, выбираемых из X
для обучения каждого базового оценщика.

- Если задано значение None (по умолчанию), выбирается `X.shape[0]` образцов независимо от
`sample_weight`.
- Если задано значение int, выбирается `max_samples` образцов.
- Если задано значение float, выбирается `max_samples * X.shape[0]` невзвешенных образцов
или `max_samples * sample_weight.sum()` взвешенных образцов.

.. versionadded:: 0.22

.. versionchanged:: 1.9
Для взвешенных образцов значение float параметра `max_samples` рассчитывается относительно `sample_weight.sum()`, а не
`X.shape[0]`.
None
monotonic_cst monotonic_cst: array-like из int формы (n_features), по умолчанию=None

Задаёт ограничение монотонности для каждого признака.
- 1: монотонное возрастание
- 0: ограничение отсутствует
- -1: монотонное убывание

Если monotonic_cst равно None, ограничения не применяются.

Ограничения монотонности не поддерживаются для:
- классификации с несколькими классами (то есть когда `n_classes > 2`),
- классификации с несколькими выходами (то есть когда `n_outputs_ > 1`).

Ограничения применяются к вероятности положительного класса.

Подробнее см. :ref:`Руководство пользователя <monotonic_cst_gbdt>`.

.. versionadded:: 1.4
None
Обученные атрибуты
Имя Тип Значение
classes_ classes_: ndarray формы (n_classes,) или список таких массивов

Метки классов (задача с одним выходом) или список массивов
меток классов (задача с несколькими выходами).
ndarray[int64](3,) [0,1,2]
estimator_ estimator_: :class:`~sklearn.tree.DecisionTreeClassifier`

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

.. versionadded:: 1.2
`base_estimator_` переименован в `estimator_`.
DecisionTreeClassifier DecisionTreeClassifier()
estimators_ estimators_: список DecisionTreeClassifier

Коллекция обученных вложенных оценщиков.
list [DecisionTreeC...te=1686997841), DecisionTreeC...te=1827923621), DecisionTreeC...te=1443447321), DecisionTreeC...ate=305097549), ...]
estimators_samples_ estimators_samples_: список массивов

Подмножество выбранных образцов (то есть образцы в выборке) для каждого базового
оценщика. Каждое подмножество задано массивом выбранных индексов.

.. versionadded:: 1.4
list [array([ 66, ..., dtype=int32), array([313, 4..., dtype=int32), array([237, 4..., dtype=int32), array([ 1, 2..., dtype=int32), ...]
feature_importances_ feature_importances_: ndarray формы (n_features,)

Важность признаков, основанная на примеси.
Чем выше значение, тем важнее признак.
Важность признака вычисляется как (нормированное)
общее уменьшение критерия, обусловленное этим признаком. Также известна
как важность по Джини.

Предупреждение: важность признаков, основанная на примеси, может вводить в заблуждение для
признаков с высокой кардинальностью (множеством уникальных значений). В качестве альтернативы см.
:func:`sklearn.inspection.permutation_importance`.
ndarray[float64](2,) [0.45,0.55]
n_classes_ n_classes_: int или список

Количество классов (задача с одним выходом) либо список, содержащий
количество классов для каждого выхода (задача с несколькими выходами).
int 3
n_features_in_ n_features_in_: int

Количество признаков, полученных при :term:`обучении`.

.. versionadded:: 0.24
int 2
n_outputs_ n_outputs_: int

Количество выходов при выполнении ``fit``.
int 1


Сравнение вероятностей

Ниже мы строим график 2-симплекса со стрелками, показывающими изменение предсказанных вероятностей для тестовых образцов.

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 10))
colors = ["r", "g", "b"]

clf_probs = clf.predict_proba(X_test)
cal_clf_probs = cal_clf.predict_proba(X_test)
# Plot arrows
for i in range(clf_probs.shape[0]):
    plt.arrow(
        clf_probs[i, 0],
        clf_probs[i, 1],
        cal_clf_probs[i, 0] - clf_probs[i, 0],
        cal_clf_probs[i, 1] - clf_probs[i, 1],
        color=colors[y_test[i]],
        head_width=1e-2,
    )

# Plot perfect predictions, at each vertex
plt.plot([1.0], [0.0], "ro", ms=20, label="Class 1")
plt.plot([0.0], [1.0], "go", ms=20, label="Class 2")
plt.plot([0.0], [0.0], "bo", ms=20, label="Class 3")

# Plot boundaries of unit simplex
plt.plot([0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], "k", label="Simplex")

# Annotate points 6 points around the simplex, and mid point inside simplex
plt.annotate(
    r"($\frac{1}{3}$, $\frac{1}{3}$, $\frac{1}{3}$)",
    xy=(1.0 / 3, 1.0 / 3),
    xytext=(1.0 / 3, 0.23),
    xycoords="data",
    arrowprops=dict(facecolor="black", shrink=0.05),
    horizontalalignment="center",
    verticalalignment="center",
)
plt.plot([1.0 / 3], [1.0 / 3], "ko", ms=5)
plt.annotate(
    r"($\frac{1}{2}$, $0$, $\frac{1}{2}$)",
    xy=(0.5, 0.0),
    xytext=(0.5, 0.1),
    xycoords="data",
    arrowprops=dict(facecolor="black", shrink=0.05),
    horizontalalignment="center",
    verticalalignment="center",
)
plt.annotate(
    r"($0$, $\frac{1}{2}$, $\frac{1}{2}$)",
    xy=(0.0, 0.5),
    xytext=(0.1, 0.5),
    xycoords="data",
    arrowprops=dict(facecolor="black", shrink=0.05),
    horizontalalignment="center",
    verticalalignment="center",
)
plt.annotate(
    r"($\frac{1}{2}$, $\frac{1}{2}$, $0$)",
    xy=(0.5, 0.5),
    xytext=(0.6, 0.6),
    xycoords="data",
    arrowprops=dict(facecolor="black", shrink=0.05),
    horizontalalignment="center",
    verticalalignment="center",
)
plt.annotate(
    r"($0$, $0$, $1$)",
    xy=(0, 0),
    xytext=(0.1, 0.1),
    xycoords="data",
    arrowprops=dict(facecolor="black", shrink=0.05),
    horizontalalignment="center",
    verticalalignment="center",
)
plt.annotate(
    r"($1$, $0$, $0$)",
    xy=(1, 0),
    xytext=(1, 0.1),
    xycoords="data",
    arrowprops=dict(facecolor="black", shrink=0.05),
    horizontalalignment="center",
    verticalalignment="center",
)
plt.annotate(
    r"($0$, $1$, $0$)",
    xy=(0, 1),
    xytext=(0.1, 1),
    xycoords="data",
    arrowprops=dict(facecolor="black", shrink=0.05),
    horizontalalignment="center",
    verticalalignment="center",
)
# Add grid
plt.grid(False)
for x in [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]:
    plt.plot([0, x], [x, 0], "k", alpha=0.2)
    plt.plot([0, 0 + (1 - x) / 2], [x, x + (1 - x) / 2], "k", alpha=0.2)
    plt.plot([x, x + (1 - x) / 2], [0, 0 + (1 - x) / 2], "k", alpha=0.2)

plt.title("Change of predicted probabilities on test samples after sigmoid calibration")
plt.xlabel("Probability class 1")
plt.ylabel("Probability class 2")
plt.xlim(-0.05, 1.05)
plt.ylim(-0.05, 1.05)
_ = plt.legend(loc="best")
Change of predicted probabilities on test samples after sigmoid calibration

На рисунке выше каждая вершина симплекса представляет идеально предсказанный класс (например, 1, 0, 0). Центральная точка внутри симплекса соответствует предсказанию трёх классов с равной вероятностью (т. е. 1/3, 1/3, 1/3). Каждая стрелка начинается в точке некалиброванных вероятностей и заканчивается наконечником в точке калиброванных вероятностей. Цвет стрелки соответствует истинному классу данного тестового образца.

Некалиброванный классификатор слишком уверен в своих предсказаниях, что приводит к большому значению логарифмической функции потерь. Калиброванный классификатор обеспечивает меньшее значение логарифмической функции потерь по двум причинам. Во-первых, обратите внимание, что на рисунке выше стрелки в целом направлены от рёбер симплекса, где вероятность одного из классов равна 0. Во-вторых, значительная часть стрелок направлена к истинному классу: например, зелёные стрелки (образцы, истинный класс которых — «зелёный») в целом направлены к зелёной вершине. Благодаря этому становится меньше чрезмерно уверенных предсказаний с вероятностью 0, а предсказанные вероятности правильного класса одновременно возрастают. Таким образом, калиброванный классификатор выдаёт более точные предсказанные вероятности, для которых значение логарифмической функции потерь меньше.

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

from sklearn.metrics import log_loss

loss = log_loss(y_test, clf_probs)
cal_loss = log_loss(y_test, cal_clf_probs)

print("Log-loss of:")
print(f" - uncalibrated classifier: {loss:.3f}")
print(f" - calibrated classifier: {cal_loss:.3f}")
Log-loss of:
 - uncalibrated classifier: 1.327
 - calibrated classifier: 0.549

Качество калибровки можно также оценить с помощью оценки Брайера для вероятностных предсказаний (чем меньше значение, тем лучше; возможный диапазон — [0, 2]):

from sklearn.metrics import brier_score_loss

loss = brier_score_loss(y_test, clf_probs)
cal_loss = brier_score_loss(y_test, cal_clf_probs)

print("Brier score of")
print(f" - uncalibrated classifier: {loss:.3f}")
print(f" - calibrated classifier: {cal_loss:.3f}")
Brier score of
 - uncalibrated classifier: 0.308
 - calibrated classifier: 0.310

Согласно оценке Брайера, калиброванный классификатор не лучше исходной модели.

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

plt.figure(figsize=(10, 10))
# Generate grid of probability values
p1d = np.linspace(0, 1, 20)
p0, p1 = np.meshgrid(p1d, p1d)
p2 = 1 - p0 - p1
p = np.c_[p0.ravel(), p1.ravel(), p2.ravel()]
p = p[p[:, 2] >= 0]

# Use the three class-wise calibrators to compute calibrated probabilities
calibrated_classifier = cal_clf.calibrated_classifiers_[0]
prediction = np.vstack(
    [
        calibrator.predict(this_p)
        for calibrator, this_p in zip(calibrated_classifier.calibrators, p.T)
    ]
).T

# Re-normalize the calibrated predictions to make sure they stay inside the
# simplex. This same renormalization step is performed internally by the
# predict method of CalibratedClassifierCV on multiclass problems.
prediction /= prediction.sum(axis=1)[:, None]

# Plot changes in predicted probabilities induced by the calibrators
for i in range(prediction.shape[0]):
    plt.arrow(
        p[i, 0],
        p[i, 1],
        prediction[i, 0] - p[i, 0],
        prediction[i, 1] - p[i, 1],
        head_width=1e-2,
        color=colors[np.argmax(p[i])],
    )

# Plot the boundaries of the unit simplex
plt.plot([0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], "k", label="Simplex")

plt.grid(False)
for x in [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]:
    plt.plot([0, x], [x, 0], "k", alpha=0.2)
    plt.plot([0, 0 + (1 - x) / 2], [x, x + (1 - x) / 2], "k", alpha=0.2)
    plt.plot([x, x + (1 - x) / 2], [0, 0 + (1 - x) / 2], "k", alpha=0.2)

plt.title("Learned sigmoid calibration map")
plt.xlabel("Probability class 1")
plt.ylabel("Probability class 2")
plt.xlim(-0.05, 1.05)
plt.ylim(-0.05, 1.05)

plt.show()
Learned sigmoid calibration map

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

В целом стратегии многоклассовой калибровки One-vs-Rest, реализованной в CalibratedClassifierCV, не следует слепо доверять.

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

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_calibration_multiclass.ipynb

Download Python source code: plot_calibration_multiclass.py

Download zipped: plot_calibration_multiclass.zip

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

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

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

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

Примеры использования FrozenEstimator

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

Spec-Zone.ru

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