Как подобрать отсчеку при перехода с 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. Аналогично можно получить по другим условиям.
🔹 Практика: как применить в реальных задачах
-
Прогноз оттока клиентов:
-
Маркетолог хочет 10 000 самых “уходящих” клиентов.
-
Выбираешь порог, при котором отобранных ~10 000 (или меньше) с наилучшей Precision@10k.
-
-
Мошенничество:
-
Высокая цена ложноположительных → нужен высокий Precision.
-
Подбирается порог, при котором Precision ≥ 0.99 и Recall как можно выше.
-
-
Медицина:
-
Нельзя упустить больного → Recall важнее.
-
Выбирается порог, при котором Recall ≥ 0.95.
-
🔹 Выводы по выбору порога:
-
Всегда подбирается от задачи и стоимости ошибок.
-
Не существует универсального порога — даже для одной модели он может меняться, если меняются приоритеты.
-
Лучший способ — визуализация tradeoff'ов и расчет метрик на реальных данных.