Как подобрать отсчеку при перехода с Presicion на Recall


Подбор отсечки (threshold) — это важнейший этап в задачах бинарной классификации, особенно в случае дисбаланса классов, когда метки предсказаний (0 или 1) получаются из вероятностей. Выбор порога напрямую влияет на то, как модель балансирует между precision (точность) и recall (полноту). Правильная настройка этого порога помогает достичь оптимального компромисса в зависимости от бизнес-целей.

🔹 Зачем нужен порог?

Большинство моделей бинарной классификации (логистическая регрессия, XGBoost, нейросети и др.) выдают вероятность принадлежности к положительному классу, например:

Объект A: 0.93

Объект B: 0.45

Объект C: 0.12

Чтобы преобразовать эти вероятности в метки классов (0 или 1), нужно выбрать порог (threshold) — например, 0.5. Все вероятности выше порога считаются положительным классом, остальные — отрицательным.

По умолчанию порог = 0.5, но он неоптимален при дисбалансе классов, так как может приводить к потере чувствительности к редкому классу или избытку ложных тревог.

🔹 Влияние порога на Precision и Recall

  • Если порог низкий (например, 0.1): модель чаще предсказывает "положительный" → увеличивается recall, но precision может сильно упасть из-за большого числа FP.

  • Если порог высокий (например, 0.9): модель становится осторожной → увеличивается precision, но recall падает, потому что много FN.

🔹 Как подобрать отсечку?

📌 1. Построение Precision-Recall кривой

  • Пошагово изменяйте порог от 0 до 1 с шагом 0.01.

  • Для каждого значения считайте:

    • Precision = TP / (TP + FP)

    • Recall = TP / (TP + FN)

  • Постройте график Precision vs Recall.

  • Выберите нужную точку в зависимости от приоритета (высокий precision или высокий recall).

Можно выбрать точку, где precision и recall сбалансированы, или где выполняется требуемое условие (например, Recall ≥ 0.85 при максимально возможном Precision).

📌 2. F1-оптимизация (или Fβ)

  • Для каждого порога рассчитывается F1-скор:
    F1=2⋅Precision⋅RecallPrecision+RecallF1 = 2 \cdot \frac{Precision \cdot Recall}{Precision + Recall}
  • Найти порог, при котором F1 достигает максимума.

  • Если нужен приоритет полноты — используйте F2 (Recall важнее).

  • Если важна точность — F0.5 (Precision важнее).

📌 3. Cоздание графика Precision / Recall / F1 по порогу

  • Отложите ось X: порог от 0 до 1;

  • По Y — значения Precision, Recall, F1.

  • Найдите точку:

    • где F1 максимален;

    • или где Precision > заданного уровня, а Recall — максимально возможен.

📌 4. С использованием ROC-кривой

ROC показывает, как меняются TPR (Recall) и FPR при разных порогах:

  • Если важна чувствительность (Recall) при контроле ложных срабатываний (FPR) — выберите точку на ROC с допустимым уровнем FPR.

  • Часто выбирают точку, где разность TPR – FPR максимальна (наибольший отрыв от случайной модели).

📌 5. Оптимизация под бизнес-метрику / стоимость ошибки

Иногда важно подобрать порог не по метрикам F1 или ROC, а с учетом затрат и последствий ошибок:

  • Каждая ошибка FN и FP имеет стоимость (например, упущенный churn = 100 у.е., ложный churn = 5 у.е.).

  • Можно ввести custom loss function, учитывающую эти стоимости:
    Total Cost=FN⋅CFN+FP⋅CFP\text{Total Cost} = FN \cdot C_{FN} + FP \cdot C_{FP}

  • Затем перебором порогов минимизировать эту функцию.

📌 6. Precision-Recall tradeoff в виде constraint-задачи

В реальных задачах порог подбирают, фиксируя одно значение, и максимизируя другое:

  • Fix Recall ≥ 90%, выбрать максимальный Precision.

  • Или: Precision ≥ 95%, максимизировать Recall.

Такие условия реализуются с помощью сканирования по сетке порогов и фильтрации нужных значений.

📌 7. Calibration curves (если модель плохо калибрована)

Если предсказанные вероятности не соответствуют реальности (например, модель часто говорит 0.9, но на деле это 60% вероятность), можно:

  • Построить калибровочную кривую;

  • Применить Platt Scaling или Isotonic Regression для калибровки вероятностей;

  • После этого заново подобрать порог.

📌 8. Порог как функция чувствительности

Если порог выбирается автоматически под ограничения (например, AUC > 0.85 и Recall > 80%), можно использовать:

  • Grid search по порогам;

  • Байесовскую оптимизацию;

  • Градиентный подход, если есть доступ к loss'у модели.

📌 9. Использование sklearn или других библиотек

В scikit-learn:

from sklearn.metrics import precision_recall_curve
prec, rec, thresholds = precision_recall_curve(y_true, y_scores)
f1_scores = 2 \* prec \* rec / (prec + rec)
best_threshold = thresholds\[np.argmax(f1_scores)\]

Это даёт наилучший порог по F1. Аналогично можно получить по другим условиям.

🔹 Практика: как применить в реальных задачах

  1. Прогноз оттока клиентов:

    • Маркетолог хочет 10 000 самых “уходящих” клиентов.

    • Выбираешь порог, при котором отобранных ~10 000 (или меньше) с наилучшей Precision@10k.

  2. Мошенничество:

    • Высокая цена ложноположительных → нужен высокий Precision.

    • Подбирается порог, при котором Precision ≥ 0.99 и Recall как можно выше.

  3. Медицина:

    • Нельзя упустить больного → Recall важнее.

    • Выбирается порог, при котором Recall ≥ 0.95.

🔹 Выводы по выбору порога:

  • Всегда подбирается от задачи и стоимости ошибок.

  • Не существует универсального порога — даже для одной модели он может меняться, если меняются приоритеты.

  • Лучший способ — визуализация tradeoff'ов и расчет метрик на реальных данных.