Все материалы
MLгайдсредний

Precision, recall, F1 и ROC-AUC: как выбрать метрику для ML-модели

Разбираем precision, recall, F1, ROC-AUC и PR-AUC на одной задаче: как цена ошибки, дисбаланс классов и порог решения меняют вывод о качестве модели.

КейсПрактика18 августа 2026 г.обновлено 15 сентября 2026 г.12 мин

У вопроса «какая метрика лучше?» нет ответа вне контекста. Для антифрода пропущенная мошенническая транзакция может стоить дорого, а для службы поддержки слишком много false positive быстро превратит модель в источник лишней работы. Поэтому качество классификатора нужно читать через матрицу ошибок, цену решения и выбранный порог, а не через одну красивую цифру.

Коротко

Precision отвечает на вопрос «какая доля найденных моделью позитивных объектов действительно позитивна», recall — «какую долю всех позитивных объектов модель нашла». F1 объединяет их в одно гармоническое среднее. ROC-AUC показывает, насколько хорошо модель ранжирует позитивные объекты выше негативных по всем порогам, но при сильном дисбалансе PR-AUC часто лучше отражает полезное качество.

  • Начните с определения positive class и стоимости false positive/false negative.
  • Не выбирайте порог по умолчанию 0.5 без проверки бизнес-сценария.
  • Смотрите на precision и recall вместе: рост одного часто покупается падением другого.
  • Для редкого positive class добавьте PR-AUC и таблицу качества по сегментам.
  • Разделяйте discrimination модели и calibration вероятностей.

Матрица ошибок — общий словарь

Любая бинарная классификация начинается с четырёх исходов. True positive — модель нашла объект нужного класса. False positive — модель сработала, но ошиблась. False negative — важный объект пропущен. True negative — негативный объект правильно оставлен без действия. Пока эти четыре клетки не названы, обсуждение метрик будет расплывчатым.

Базовое правило
positive class + threshold + cost of error

Одна и та же модель может иметь разное практическое качество при разных positive class и порогах.

Что произошло после решения модели
Факт / прогнозПозитивный прогнозНегативный прогноз
Позитивный фактTP · нашли нужный объектFN · пропустили объект
Негативный фактFP · ложная тревогаTN · корректно не сработали

Precision и recall отвечают на разные вопросы

Precision = TP / (TP + FP). Он важен, когда каждое срабатывание запускает дорогую ручную проверку, блокирует клиента или отправляет сообщение, которому нельзя часто ошибаться. Высокий precision означает, что среди найденных моделью объектов мало ложных тревог.

Recall = TP / (TP + FN). Он нужен, когда пропуск позитивного объекта опаснее лишней проверки. В антифроде это может быть пропущенная мошенническая операция, в медицинском скрининге — пропущенный риск, а в поиске документов — не найденный релевантный материал.

Обычно нельзя максимизировать обе метрики одновременно. Если снизить порог, модель начнёт находить больше позитивных объектов: recall вырастет, но вместе с ним может вырасти число FP и упасть precision. Поэтому правильный вопрос звучит не «какая метрика выше», а «какой компромисс выдерживает процесс».

Пример trade-off при изменении порога

Иллюстративные значения: порог выбирается после оценки стоимости ошибок и пропускной способности процесса.

precisionrecall

F1 полезен, когда нужен баланс

F1 = 2 × precision × recall / (precision + recall). Это гармоническое среднее, поэтому одна очень низкая компонента заметно тянет итог вниз. F1 удобен как компактная метрика для сравнения моделей при сопоставимом positive class и одинаковой стратегии выбора порога.

Но F1 не знает, какая ошибка дороже. Он одинаково относится к FP и FN. Если пропуск в пять раз опаснее ложной тревоги, лучше задать минимальный recall, а среди подходящих порогов выбрать вариант с лучшим precision или считать взвешенную F-бету. Не превращайте F1 в универсальный KPI только потому, что его легко показать в таблице.

pythonСравнить несколько порогов на отложенной выборке
from sklearn.metrics import precision_score, recall_score, f1_score

for threshold in (0.2, 0.4, 0.6, 0.8):
    predicted = (proba >= threshold).astype(int)
    print({
        'threshold': threshold,
        'precision': precision_score(y_true, predicted),
        'recall': recall_score(y_true, predicted),
        'f1': f1_score(y_true, predicted),
    })

ROC-AUC: качество ранжирования, а не готового решения

ROC-AUC измеряет, насколько часто случайный positive получает от модели больший score, чем случайный negative. Порог не фиксирован: график проходит по возможным уровням чувствительности и false positive rate. Это делает ROC-AUC удобным для сравнения способности моделей разделять классы до выбора операционного порога.

Высокий ROC-AUC не гарантирует, что выбранный порог даст приемлемые precision и recall. Модель может хорошо ранжировать объекты, но быть плохо откалибрована или давать слишком много ложных срабатываний при редком positive class. Для редких событий посмотрите PR-кривую: она напрямую показывает precision и recall по порогам.

Как читать набор метрик
МетрикаЧто показываетЧего не показывает
Precisionточность найденных позитивных объектовсколько позитивов пропущено
Recallдолю найденных позитивных объектовсколько ложных тревог внутри найденных
F1сбалансированное сочетание precision и recallразную стоимость FP и FN
ROC-AUCспособность ранжировать классыкачество конкретного порога
PR-AUCкачество precision-recall при дисбалансекалибровку вероятностей

Средняя калибровка скрывает противоположные ошибки сегментов

Если антифрод выдаёт вероятность 0,20, среди большого числа похожих прогнозов ожидается около 20% подтверждённых позитивных исходов. Исход отдельной операции бинарный. Разбейте прогнозы на интервалы, для каждого посчитайте среднюю вероятность, фактическую долю фрода и число операций. Слишком узкий интервал даёт мало наблюдений; слишком широкий может скрыть локальное смещение. Границы и размеры групп должны быть видны рядом с кривой калибровки.

Учебный пример: есть два сегмента по 100 операций, всем присвоено 0,20. В первом подтверждено 10 случаев фрода, во втором — 30. В общей группе получилось ровно 40 / 200 = 20%, и средняя проверка выглядит идеальной. В первом сегменте риск завышен вдвое, во втором занижен. Это не доказательство системного дефекта на таких маленьких данных, но ясная причина не ограничиваться общей диаграммой.

Сегменты выбирайте по процессу: новые и возвращающиеся клиенты, способ оплаты, платформа. Для каждого покажите поддержку классов и матрицу ошибок на одном рабочем пороге. Если позитивов нет, recall не получится оценить; условный ноль из настройки библиотеки не означает, что модель пропускает все случаи. Малые группы лучше сопровождать диапазоном неопределённости и накоплением данных, чем уверенно ранжировать по нескольким исходам.

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

Обнаруженное смещение не означает, что нужно немедленно назначать каждому сегменту свой порог. Сначала проверьте разметку, зрелость исходов и достаточность наблюдений. Затем сравните общий и сегментный варианты по стоимости ошибок и ограничениям процесса на отложенных данных. В model card запишите, для каких групп оценки устойчивы, где пока неизвестны и когда их пересмотрят. Это связывает проверку вероятностей с конкретным действием антифрода.

Порог выбирается после модели

Порог — это часть продукта, а не случайная настройка в ноутбуке. Сначала получите score или вероятность на валидационной выборке, затем посмотрите кривые и стоимость решений. Если у команды есть ограничение «не больше 500 проверок в день», threshold можно подобрать под этот бюджет. Если есть SLA для recall, сначала зафиксируйте минимальный recall, а потом оптимизируйте precision.

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

ROC-AUC не заменяет анализ порога

AUC помогает сравнить ranking, но решение всегда живёт в конкретной точке кривой. Покажите эту точку и её бизнес-последствия.

  • Определите, какое действие запускает позитивный прогноз.
  • Назовите допустимое число false positive и false negative.
  • Подберите threshold на validation, финально проверьте на test.
  • Проверьте стабильность precision и recall по сегментам.
  • Зафиксируйте порог и причину его выбора в model card.

Порог с меньшими потерями может не поместиться в очередь проверок

Продолжим антифрод из начала статьи. Для учебного расчёта возьмём 1 000 транзакций, из которых 20 подтверждены как мошеннические. Вариант порога A находит 16 таких операций и ошибочно отправляет на проверку 40 нормальных. Вариант B находит 12 мошеннических и даёт 10 ложных тревог. A и B — условные рабочие точки одной модели.

Пусть пропуск мошеннической операции стоит 5 000 ₽, ложная тревога — 200 ₽, а обработка любого срабатывания дополнительно стоит 50 ₽. Для A получаем 4 × 5 000 + 40 × 200 + 56 × 50 = 30 800 ₽. Для B — 8 × 5 000 + 10 × 200 + 22 × 50 = 43 100 ₽. Precision у B выше, но при этих ценах суммарные потери ниже у A.

При лимите 30 проверок за период A не подходит, а B укладывается в очередь, хотя дороже по функции потерь. Теперь можно искать промежуточный порог или увеличить мощность проверки. Минимум стоимости недостижим, если часть очереди остаётся необработанной.

Цены ошибок редко известны точно. Повторите расчёт для нескольких согласованных значений и покажите, при каких допущениях меняется решение. Если сумма транзакции сильно различается, один средний штраф за FN скрывает наиболее дорогие пропуски. Тогда оценивайте ожидаемую потерю по операции и проверяйте результат на уровне всего потока. Задержки подтверждения фрода тоже важны: недавние ещё не размеченные операции нельзя автоматически записать в TN.

Для упрощённой задачи со строго откалиброванной вероятностью, нулевой стоимостью верного решения и только постоянными ценами FP и FN граница равна C_FP / (C_FP + C_FN). Дополнительная стоимость проверки и лимит очереди меняют эту постановку. Поэтому подбирай рабочую точку по явно описанному процессу на validation, а окончательную цену оценивайте на отдельном test после фиксации порога.

Условные рабочие точки на одной тысяче операций
ПорогTP / FP / FN / TNПроверокПотери
A16 / 40 / 4 / 9405630 800 ₽
B12 / 10 / 8 / 9702243 100 ₽

Дисбаланс классов меняет интерпретацию

При positive class в 1% даже 99% accuracy может означать, что модель всегда отвечает «нет» и не находит ни одного нужного объекта. Поэтому accuracy почти никогда не должна быть единственной метрикой для редкого события. Добавьте baseline, confusion matrix, precision, recall и PR-AUC.

Сравнивайте модели на одинаковом временном срезе и одинаковом positive class. Если поменялся sampling, class weight или правило разметки, числа могут стать несопоставимыми. В отчёте рядом с метрикой покажите support: сколько фактических positive и negative вошло в проверку.

Минимальный отчёт классификатора
support + confusion matrix + precision/recall + threshold

Без размера классов и порога одна метрика не даёт достаточного контекста.

Одинаковые TPR и FPR дают разный precision при разной частоте фрода

Допустим, рабочая точка антифрода сохраняет TPR = 80% и FPR = 1%. На 10 000 транзакций при доле фрода 1% есть 100 позитивных и 9 900 негативных. Модель найдёт 80 мошеннических и поднимет 99 ложных тревог. Precision равен 80 / 179 ≈ 44,7%. Низкий false positive rate выглядит безобидно на ROC, пока не переведёте его в абсолютное число нормальных операций.

Теперь оставим те же условные TPR и FPR, но изменим долю фрода на 10%. Среди 1 000 позитивных найдётся 800, среди 9 000 негативных появится 90 ложных тревог. Precision станет 800 / 890 ≈ 89,9%. Рабочая точка на ROC не сдвинулась, а доля полезных срабатываний почти удвоилась. Это расчёт при неизменных условных характеристиках; в реальности вместе с составом потока может измениться и качество ранжирования.

PR-кривая делает цену лишних тревог заметнее, поскольку одна из осей — precision. Но сравнивать её площадь на двух выборках с разной распространённостью positive без оговорки тоже нельзя. Если тест специально собрали поровну из фрода и нормальных операций, precision на нём не соответствует обычному потоку. Верните репрезентативный состав или используйте корректные веса и обязательно укажите способ построения проверочной выборки.

Под названием PR-AUC встречаются разные расчёты. Average precision в scikit-learn суммирует precision с весами по приросту recall; это не трапецеидальная площадь с линейной интерполяцией. Запишите функцию, которой получено число, и используйте её же при сравнении. При редких позитивах различие особенно заметно на короткой ступенчатой кривой. Назовите этот показатель AP.

В отчёте оставьте обе кривые для диагностики ранжирования и отдельно выдели выбранный порог: количество проверок, TP, FP и пропуски за рабочий период. Если метрика изменилась после запуска, сначала сравните долю подтверждённого фрода и задержку разметки. Это помогает отличить смену состава потока от ухудшения модели и понять, нужно ли пересматривать порог или сначала дождаться зрелых исходов.

Как ответить на ML-кейс на собеседовании

Сильный ответ начинается с уточняющего вопроса: что считается positive и какое действие следует за прогнозом. Затем назовите стоимость FP и FN, предложите набор метрик и объясните, как выберете threshold. Наконец, добавьте проверку по сегментам и план мониторинга после запуска. Такой ответ показывает, что вы понимаете не только формулы, но и место модели в процессе.

Не говорите «возьмём ROC-AUC, потому что это стандарт». Скажите, что ROC-AUC полезен для сравнения ranking, но для принятия решения нужны precision/recall на выбранном пороге, PR-AUC при дисбалансе и проверка calibration, если score интерпретируется как вероятность.

Продолжить чтение
Вся библиотека