Spec-Zone.ru › scikit-learn

3.3. Настройка порога принятия решения для предсказания класса

Классификацию лучше разделить на две части:

  • статистическую задачу обучения модели для предсказания, в идеале, вероятностей классов;
  • задачу принятия решения о конкретных действиях на основе этих предсказанных вероятностей.

Рассмотрим простой пример, связанный с прогнозом погоды: первый пункт касается ответа на вопрос «Какова вероятность того, что завтра пойдёт дождь?», а второй — ответа на вопрос «Стоит ли мне завтра взять зонт?».

В API scikit-learn первый пункт реализуется путём получения оценок с помощью predict_proba или decision_function. Первый метод возвращает оценки условных вероятностей \(P(y|X)\) для каждого класса, а второй — оценку решения для каждого класса.

Решение, соответствующее меткам, получается с помощью predict. В задаче бинарной классификации правило принятия решения или действие определяются пороговым значением оценок, в результате чего для каждого образца предсказывается метка одного класса. В scikit-learn для бинарной классификации предсказания меток классов получаются с помощью жёстко заданных пороговых правил: положительный класс предсказывается, если условная вероятность \(P(y|X)\) больше 0.5 (получена с помощью predict_proba) или если оценка решения больше 0 (получена с помощью decision_function).

Ниже приведён пример, иллюстрирующий связь между оценками условных вероятностей \(P(y|X)\) и метками классов:

>>> from sklearn.datasets import make_classification
>>> from sklearn.tree import DecisionTreeClassifier
>>> X, y = make_classification(random_state=0)
>>> classifier = DecisionTreeClassifier(max_depth=2, random_state=0).fit(X, y)
>>> classifier.predict_proba(X[:4])
array([[0.94     , 0.06     ],
       [0.94     , 0.06     ],
       [0.0416, 0.9583],
       [0.0416, 0.9583]])
>>> classifier.predict(X[:4])
array([0, 0, 1, 1])

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

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

3.3.1. Настройка порога принятия решения после обучения

Один из способов решить проблему, описанную во введении, — настроить порог принятия решения классификатора после обучения модели. TunedThresholdClassifierCV настраивает этот порог с помощью внутренней перекрёстной проверки. Оптимальный порог выбирается так, чтобы максимизировать заданную метрику.

На следующем изображении показана настройка порога принятия решения для классификатора на основе градиентного бустинга. Хотя исходный и настроенный классификаторы возвращают одинаковые выходные данные predict_proba и, следовательно, одинаковые ROC-кривые и кривые «точность–полнота», предсказания меток классов различаются из-за настроенного порога принятия решения. Исходный классификатор предсказывает интересующий класс, если условная вероятность больше 0.5, тогда как настроенный классификатор предсказывает интересующий класс при очень низкой вероятности (около 0.02). Этот порог принятия решения оптимизирует метрику полезности, заданную бизнесом (в данном случае страховой компанией).

../_images/sphx_glr_plot_cost_sensitive_learning_002.png

3.3.1.1. Способы настройки порога принятия решения

Порог принятия решения можно настроить с помощью разных стратегий, задаваемых параметром scoring.

Один из способов настройки порога — максимизировать заранее определённую метрику scikit-learn. Эти метрики можно найти, вызвав функцию get_scorer_names. По умолчанию используется сбалансированная точность, однако важно выбрать метрику, подходящую для конкретного случая использования.

Примечание

Важно учитывать, что у этих метрик есть параметры по умолчанию, в частности метка интересующего класса (т. е. pos_label). Поэтому, если эта метка не подходит для вашего приложения, необходимо определить функцию-оценщик и передать правильное значение pos_label (а также дополнительные параметры) с помощью make_scorer. Информацию о том, как определить собственную функцию оценки, см. в разделе Вызываемые функции-оценщики. Например, ниже показано, как передать функции-оценщику информацию о том, что интересующая метка — 0, при максимизации f1_score:

>>> from sklearn.linear_model import LogisticRegression
>>> from sklearn.model_selection import TunedThresholdClassifierCV
>>> from sklearn.metrics import make_scorer, f1_score
>>> X, y = make_classification(
...   n_samples=1_000, weights=[0.1, 0.9], random_state=0)
>>> pos_label = 0
>>> scorer = make_scorer(f1_score, pos_label=pos_label)
>>> base_model = LogisticRegression()
>>> model = TunedThresholdClassifierCV(base_model, scoring=scorer)
>>> scorer(model.fit(X, y), X, y)
0.88
>>> # compare it with the internal score found by cross-validation
>>> model.best_score_
np.float64(0.86)

3.3.1.2. Важные замечания о внутренней перекрёстной проверке

По умолчанию TunedThresholdClassifierCV использует стратифицированную перекрёстную проверку с 5 блоками для настройки порога принятия решения. Параметр cv позволяет управлять стратегией перекрёстной проверки. Перекрёстную проверку можно отключить, задав cv="prefit" и передав обученный классификатор. В этом случае порог принятия решения настраивается на данных, переданных методу fit.

Однако при использовании этого параметра следует проявлять особую осторожность. Нельзя использовать одни и те же данные для обучения классификатора и настройки порога принятия решения из-за риска переобучения. Дополнительные сведения см. в следующем примере (ср. Замечание о повторном обучении модели и перекрёстной проверке). Если ресурсы ограничены, можно задать для cv число с плавающей точкой, чтобы использовать внутреннее однократное разделение на обучающую и тестовую выборки.

Параметр cv="prefit" следует использовать только в том случае, если переданный классификатор уже обучен и вам нужно лишь найти оптимальный порог принятия решения с помощью нового набора для валидации.

3.3.1.3. Визуализация порогов

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

3.3.1.4. Ручная настройка порога принятия решения

В предыдущих разделах обсуждались стратегии поиска оптимального порога принятия решения. Также можно задать порог принятия решения вручную с помощью класса FixedThresholdClassifier. Если вы не хотите повторно обучать модель при вызове fit, оберните свою базовую модель в FrozenEstimator и выполните FixedThresholdClassifier(FrozenEstimator(estimator), ...).

3.3.1.5. Примеры

  • См. пример Настройка точки отсечения функции принятия решения после обучения, чтобы узнать больше о настройке порога принятия решения после обучения.
  • См. пример Настройка порога принятия решения после обучения для учёта стоимости ошибок, чтобы узнать больше об обучении с учётом стоимости ошибок и настройке порога принятия решения.

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

Spec-Zone.ru

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