Условие
Модель определяет, является ли транзакция мошеннической. Аналитик может настраивать порог threshold. Какую метрику оптимизировать: precision, recall, F1? Обоснуйте на бизнес-аргументах.
Решение
Определения через confusion matrix
| Pred = 1 | Pred = 0 | |
|---|---|---|
| True = 1 | TP | FN |
| True = 0 | FP | TN |
- Precision = TP / (TP + FP) — «среди тех, кого назвали fraud, какая доля реально fraud». Цена FP высока.
- Recall = TP / (TP + FN) — «какую долю реальных fraud мы поймали». Цена FN высока.
- F1 = 2 · P · R / (P + R) — гармоническое среднее. Балансирует, штрафует за дисбаланс.
- F-beta =
(1 + β²) · P · R / (β² · P + R). β > 1 — приоритет recall; β < 1 — приоритет precision.
Антифрод-кейс
В классическом антифроде структура такая:
- FN (пропустили fraud) — банк теряет деньги (от тысяч до миллионов рублей).
- FP (ложно заблокировали хорошую транзакцию) — расстроенный клиент, support-call, репутационные потери, иногда отток.
В бизнес-логике: 1 FN стоит, скажем, ₽5000 в среднем; 1 FP — ₽500 (стоимость call + risk оттока). Тогда:
Cost = 5000 · FN + 500 · FP
Это expected cost — её и нужно минимизировать. Это часто не F1, не «balanced» порог, а специфический threshold под бизнес.
Как выбирать порог
import numpy as np
scores = model.predict_proba(X_val)[:, 1]
y_true = y_val.values
thresholds = np.linspace(0.01, 0.99, 99)
costs = []
for t in thresholds:
pred = scores > t
tp = ((pred == 1) & (y_true == 1)).sum()
fp = ((pred == 1) & (y_true == 0)).sum()
fn = ((pred == 0) & (y_true == 1)).sum()
cost = 5000 * fn + 500 * fp
costs.append(cost)
best_t = thresholds[np.argmin(costs)]Не только threshold
- Каскад моделей. «Очень уверенно fraud → блок; средне уверенно → ручная проверка; иначе → пропускаем».
- Сегментация. Разные пороги для разных сумм/каналов/новых клиентов.
- Тестирование операционных метрик. «Сколько call-center’ов выдерживает текущий FP-объём?»
Когда F1 уместен
- Когда относительная цена FP и FN сопоставима (обычно никогда в реальном бизнесе);
- Для отчётности в академических работах;
- В fast-iteration: F1 — простой single-number summary.
В реальном антифроде чаще оптимизируют Recall at fixed Precision (например, «при precision ≥ 80% максимизировать recall») или непосредственно expected cost.
Подводные камни
- Оптимизировать accuracy в задаче с 0.1% fraud — модель «всё нормально» даёт 99.9% accuracy и нулевую пользу.
- F1 не учитывает реальные стоимости ошибок. Используйте F-beta или expected cost.
- Threshold выбирается на test set, отчётность — на нём же. Это утечка. Делите данные: train / val (для threshold) / test (для окончательной отчётности).
- Calibration важна. Threshold = 0.5 на некалиброванной модели бессмыслен.
- Drift операционной среды. Доля мошенников и поведение non-fraud меняются — пороги нужно переоценивать.
Эталонный ответ
В антифроде оптимизируйте expected cost (5000·FN + 500·FP в примере), а не F1. F1 уместен, когда FP и FN equally costly — это редкий случай в проде. Практически: ищите argmin_t Cost(t) на валидационной выборке, фиксируйте threshold, валидируйте на test.