Какой порог (threshold) у ROC-AUC?

«Какой порог (threshold) у ROC-AUC?» — вопрос из категории Метрики и функции потерь, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

ROC-AUC сама по себе не имеет фиксированного порога. Это метрика, которая оценивает качество бинарного классификатора на всех возможных порогах классификации.

Пояснение:

  1. ROC-кривая (Receiver Operating Characteristic) строится путем последовательного перебора порогов от 0 до 1 для вероятности положительного класса, предсказанной моделью.
  2. Для каждого порога вычисляются True Positive Rate (TPR = Recall) и False Positive Rate (FPR).
  3. Кривая отображает компромисс (trade-off) между TPR и FPR.
  4. AUC (Area Under Curve) — это площадь под ROC-кривой. Значение 0.5 соответствует случайному угадыванию, 1.0 — идеальному разделителю.

Пример выбора оптимального порога на практике: Часто после построения модели и вычисления ROC-AUC мы выбираем конкретный порог для развертывания, исходя из бизнес-требований.

import numpy as np
from sklearn.metrics import roc_curve

# y_true - истинные метки, y_pred_proba - предсказанные вероятности положительного класса
fpr, tpr, thresholds = roc_curve(y_true, y_pred_proba)

# 1. Выбор порога, максимизирующего разность TPR - FPR (индекс Йодена)
optimal_idx = np.argmax(tpr - fpr)
optimal_threshold_j = thresholds[optimal_idx]
print(f"Optimal threshold (Youden's J): {optimal_threshold_j:.3f}")

# 2. Выбор порога для целевого значения Precision или Recall
# Например, нам критически важно иметь Recall не ниже 0.9
target_recall = 0.9
idx_for_recall = np.where(tpr >= target_recall)[0][0]
threshold_for_recall = thresholds[idx_for_recall]
print(f"Threshold for Recall >= 0.9: {threshold_for_recall:.3f}")

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