🔴 Сложный ⏱️ 45 минут

Метрики качества

📋 Содержание урока

Метрики качества ⚖️

Представь: ты построил модель, которая по анализам определяет, болен ли пациент редкой болезнью — ею страдает всего 1% населения. Модель докладывает: accuracy 99%! Заказчик в восторге, ты готовишь презентацию для инвесторов. А теперь открой код модели и посмотри, что она реально делает: она всегда предсказывает «здоров», не глядя ни на один анализ. Ровно 99% пациентов действительно здоровы, значит она права в 99% случаев — и при этом не находит вообще ни одного больного. Модель, которая пропускает каждого без исключения заболевшего, формально показывает одну из лучших метрик, какие ты вообще видел в жизни.

Это не гипотетическая страшилка, а классический и один из самых важных уроков во всём машинном обучении: высокая точность (accuracy) ничего не говорит о том, полезна ли модель, если классы в данных распределены неравномерно. И дисбаланс классов — это не редкое исключение, а норма для огромного числа реальных задач: мошеннические транзакции (обычно доли процента от всех платежей), поломки оборудования, клики по рекламе, редкие заболевания, дефекты на производственной линии. Везде, где «положительный» класс редок, наивная модель, которая просто всегда говорит «нет», получает обманчиво высокий процент правильных ответов — и остаётся абсолютно бесполезной.

Чтобы не попадаться в эту ловушку, инженеры машинного обучения используют набор метрик, которые смотрят на ошибки модели не одним усреднённым числом, а раздельно, по типам. Confusion matrix (матрица ошибок) раскладывает предсказания модели на четыре категории — какие ответы были верными, а какие ошибочными и в какую именно сторону. Из этой матрицы выводятся precision (точность предсказаний) и recall (полнота) — две метрики, которые отвечают на принципиально разные вопросы и почти всегда противоречат друг другу. А F1-score сводит их в единое число тогда, когда компромисс между ними нужно зафиксировать одной цифрой.

Освоить этот урок — значит перестать бездумно писать model.score() и вместо этого научиться спрашивать: а какая ошибка здесь дороже — пропустить больного или напугать здорового? Заблокировать спам или потерять важное письмо? Ответ на этот вопрос определяет, какую метрику ты будешь оптимизировать — и именно этому посвящён весь урок.

История: откуда взялись эти метрики

Confusion matrix и связанные с ней метрики родились не в машинном обучении, а гораздо раньше — в статистике проверки гипотез и радиолокации середины XX века. Во время Второй мировой войны операторы радаров сталкивались с задачей, знакомой любому современному ML-инженеру: радар пищит «цель обнаружена» — но это действительно вражеский самолёт, или просто стая птиц, или помехи? Аналитики того времени систематизировали четыре возможных исхода такого сигнала — верное обнаружение, верный пропуск, ложная тревога и пропуск цели — и это по сути и есть четыре ячейки современной confusion matrix, только под другими именами.

Термины precision и recall пришли из другой области — информационного поиска (information retrieval), то есть из систем, которые ищут документы по запросу, задолго до появления привычного нам веб-поиска. Когда в 1960–70-х годах библиотечные и патентные системы начали автоматически искать релевантные документы среди тысяч записей, исследователям понадобилось честно отвечать на два разных вопроса: «из того, что система нашла, сколько документов действительно релевантны?» — это и есть precision, и «из всех релевантных документов, сколько система вообще нашла?» — это recall. Эти формулировки почти дословно перекочевали в машинное обучение и сегодня применяются далеко за пределами поиска документов — в детекции объектов на изображениях, в антиспаме, в медицинской диагностике, в кредитном скоринге.

F1-score как гармоническое среднее precision и recall стал стандартом заметно позже, вместе с ростом задач классификации текста и информационного поиска в 1990-х, а сегодня это одна из первых метрик, которую выводит sklearn.metrics.classification_report для любой модели классификации — наравне с precision и recall по каждому классу. Именно из-за повсеместности всех этих метрик в промышленном ML критически важно понимать не формулы наизусть, а то, какую именно ошибку каждая из них штрафует.

Accuracy и почему она опасна при дисбалансе классов

Интуиция

Accuracy (точность, доля верных предсказаний) — самая простая и самая интуитивно понятная метрика классификации: она просто считает, какую долю всех объектов модель классифицировала правильно, не различая, на объектах какого класса она ошиблась. Это ровно тот вопрос, который первым приходит в голову: «как часто модель вообще права?» Проблема в том, что этот вопрос молчаливо предполагает, что все объекты одинаково важны и что классы примерно поровну представлены в данных — а в реальных задачах это почти никогда не так.

Формула

Accuracy.

$$\text{Accuracy} = \frac{\text{число верных предсказаний}}{\text{общее число предсказаний}} = \frac{TP + TN}{TP + TN + FP + FN}$$

где $TP$, $TN$, $FP$, $FN$ — четыре ячейки confusion matrix, которые подробно разбираются в следующем разделе.

Пример 1: детекция мошеннических транзакций

Банк тестирует модель, которая должна находить мошеннические платежи среди 10 000 транзакций за день. Мошеннических транзакций среди них всего 50 — то есть 0.5% датасета, классический сильный дисбаланс.

Предположим, кто-то в спешке задеплоил модель-заглушку, которая на каждый запрос просто отвечает «легитимная транзакция», ничего не анализируя. Посчитаем её accuracy:

Всего транзакций:        10 000
Реально мошеннических:       50
Реально легитимных:       9 950

Предсказано моделью:  "легитимная" для всех 10 000
Верно предсказано:     9 950 (все легитимные транзакции)
Неверно предсказано:      50 (все мошеннические пропущены)
$$\text{Accuracy} = \frac{9950}{10000} = 0{,}995 = 99{,}5\%$$

Модель показывает accuracy 99.5% — цифра, с которой можно смело идти к руководству. При этом она пропустила абсолютно все 50 случаев мошенничества за день, не поймав ни одного. Для банка это означает прямые финансовые потери на каждой такой транзакции — модель полностью провалила единственную задачу, ради которой её строили, оставаясь при этом «отличницей» по accuracy.

Пример 2: скрининг редкого заболевания

Похожая ситуация, только в медицине. Из 2 000 пациентов на скрининге редкое заболевание есть у 40 человек (2%). Наивная модель «все здоровы»:

Всего пациентов:    2 000
Реально больны:        40
Реально здоровы:    1 960

Предсказано:  "здоров" для всех 2 000
$$\text{Accuracy} = \frac{1960}{2000} = 0{,}98 = 98\%$$

98% accuracy звучит как отличный результат для медицинского теста — но модель не выявила ни одного больного человека. Если её реально внедрить вместо диагностики, все 40 пациентов не получат лечения вовремя. Чем реже встречается интересующий нас класс, тем ближе accuracy наивной модели-заглушки подбирается к 100% — и тем меньше эта цифра говорит о реальной пользе модели.

Пример 3: когда accuracy действительно работает

Чтобы не создать впечатление, будто accuracy бесполезна в принципе — рассмотрим противоположный случай. Модель отличает фотографии кошек от фотографий собак, датасет сбалансирован: 5 000 кошек и 5 000 собак. Модель правильно классифицировала 9 200 из 10 000 изображений.

$$\text{Accuracy} = \frac{9200}{10000} = 0{,}92 = 92\%$$

Здесь accuracy — вполне разумная и информативная метрика: классы представлены поровну, и модель не может «жульничать», предсказывая только один класс — если бы она всегда говорила «кошка», её accuracy упала бы до 50%, что сразу выдало бы бесполезность. Accuracy становится опасной метрикой ровно тогда, когда один класс сильно преобладает над другим, а не сама по себе.

Почему это важно

Правило простое и его стоит запомнить дословно: чем сильнее дисбаланс классов, тем меньше accuracy отражает реальное качество модели, и тем больше accuracy склонна маскировать провал именно на редком, часто самом важном классе. В индустрии сильный дисбаланс — это норма, а не исключение, поэтому accuracy почти никогда не должна быть единственной метрикой, на которую смотрит ML-инженер перед тем, как задеплоить модель в продакшен. Дальше в уроке разберём, какие метрики раскладывают ошибку по типам и не дают наивной модели спрятаться за красивым процентом.

Confusion matrix: матрица ошибок

Интуиция

Confusion matrix (матрица ошибок) — это таблица, которая показывает не одно усреднённое число, а раскладывает предсказания модели на четыре категории отдельно: сколько раз модель была права на положительном классе, сколько раз права на отрицательном, и — что важнее всего — сколько раз и в какую сторону она ошиблась. Вместо вопроса «как часто модель права?» confusion matrix отвечает на более полезный вопрос: «как именно модель ошибается, и на каком классе?»

Формула (структура матрицы)

Confusion matrix для бинарной классификации.

$$ > \begin{array}{c|cc} > & \text{Предсказано: Positive} & \text{Предсказано: Negative} \\ > \hline > \text{Реально: Positive} & TP & FN \\ > \text{Реально: Negative} & FP & TN \\ > \end{array} > $$

где:

  • $TP$ (True Positive, истинно положительный) — объект реально положительный, и модель верно предсказала «положительный»;
  • $TN$ (True Negative, истинно отрицательный) — объект реально отрицательный, и модель верно предсказала «отрицательный»;
  • $FP$ (False Positive, ложноположительный, «ложная тревога») — объект реально отрицательный, а модель ошибочно предсказала «положительный»;
  • $FN$ (False Negative, ложноотрицательный, «пропуск цели») — объект реально положительный, а модель ошибочно предсказала «отрицательный».

Разбор каждой ячейки на одном сквозном примере

Возьмём модель, которая по анализу крови определяет, болен ли пациент («положительный» класс — болен, «отрицательный» — здоров), и один конкретный пациент на каждую ячейку:

TP — пациент реально болен, модель сказала "болен"     → верная тревога, лечение начнётся вовремя
TN — пациент реально здоров, модель сказала "здоров"    → верный пропуск, никого не тревожим зря
FP — пациент реально здоров, модель сказала "болен"     → ложная тревога, лишнее обследование, стресс, деньги
FN — пациент реально болен, модель сказала "здоров"     → самая опасная ошибка: болезнь прогрессирует без лечения

Обрати внимание: $TP$ и $TN$ — это два разных вида успеха модели, а $FP$ и $FN$ — это два разных вида ошибки, и цена этих ошибок в жизни почти никогда не совпадает. Для диагностики рака цена $FN$ (пропустить больного) обычно намного выше цены $FP$ (лишний раз перепроверить здорового), а для спам-фильтра — ровно наоборот, как будет подробно разобрано в разделе про F1-score.

Пример 1: отток клиентов телеком-оператора

Оператор связи обучил модель предсказывать отток (churn) — уйдёт ли клиент к конкуренту в следующем месяце — чтобы заранее предложить ему скидку. Протестировали модель на 2 000 клиентах, из которых реально ушли 200.

                     Предсказано: уйдёт   Предсказано: останется
Реально: уйдёт             TP = 150             FN = 50
Реально: останется         FP = 110             TN = 1690

Проверим согласованность чисел: реально ушедших $TP+FN=150+50=200$ ✓, реально оставшихся $FP+TN=110+1690=1800$, а всего клиентов $150+50+110+1690=2000$ ✓.

Интерпретация ячеек:

  • $TP=150$ — этим клиентам вовремя предложили скидку и, возможно, удержали;
  • $FN=50$ — эти 50 клиентов ушли, а модель их «не увидела» — упущенная выручка;
  • $FP=110$ — этим клиентам предложили скидку зря, они и так бы остались — прямые издержки на ненужные скидки;
  • $TN=1690$ — этим клиентам ничего не предложили, и правильно, они остались сами.
$$\text{Accuracy} = \frac{150+1690}{2000} = \frac{1840}{2000} = 0{,}92 = 92\%$$

92% accuracy здесь звучит убедительно, но она скрывает, что из 200 реально уходящих клиентов модель пропустила 50, то есть четверть — компания продолжит терять именно тех клиентов, ради которых модель и строилась.

Пример 2: детектор дефектов на производственной линии

Завод внедрил компьютерное зрение для поиска бракованных деталей на конвейере. За смену прошло 5 000 деталей, реально бракованных — 100.

                     Предсказано: брак   Предсказано: норма
Реально: брак             TP = 85             FN = 15
Реально: норма             FP = 60             TN = 4840

Проверка: $85+15=100$ ✓ (реально бракованных), $60+4840=4900$ (реально нормальных), всего $85+15+60+4840=5000$ ✓.

Здесь $FN=15$ означает, что 15 бракованных деталей уехали к клиенту непроверенными — потенциальный репутационный и юридический удар. $FP=60$ означает, что 60 нормальных деталей были забракованы зря — лишние затраты на повторную проверку, но никакого риска для конечного потребителя. На большинстве производственных линий цена $FN$ здесь тоже выше цены $FP$, хотя и не так драматично, как в медицине.

Пример 3: рекомендательная система

Стриминговый сервис проверяет модель, которая помечает фильмы как «тебе понравится». Протестировано на 1 000 показов, реально понравившихся фильмов (по факту досмотра до конца) — 300.

                       Предсказано: понравится   Предсказано: не понравится
Реально: понравился            TP = 210                  FN = 90
Реально: не понравился          FP = 180                  TN = 520

Проверка: $210+90=300$ ✓, $180+520=700$, всего $210+90+180+520=1000$ ✓. Здесь цена ошибок несимметрична в обратную сторону, чем в медицине: $FP$ (порекомендовали фильм, который не понравился) стоит сервису лишь немного доверия пользователя, а $FN$ (не порекомендовали фильм, который бы понравился) означает упущенную возможность вовлечь пользователя — обе ошибки относительно недороги, и здесь как раз можно балансировать метрики свободнее, чем в задачах с высокой ценой ошибки.

Почему это важно

Confusion matrix — это не промежуточный технический шаг, а самостоятельный диагностический инструмент: посмотрев на неё, ты сразу видишь, в какую сторону ошибается модель, а не просто «насколько часто». Ровно из четырёх её ячеек строятся все метрики, разобранные дальше в этом уроке, — и любая метрика классификации, с которой ты столкнёшься в карьере, в конечном счёте сводится к какой-то комбинации $TP$, $TN$, $FP$ и $FN$.

Precision и recall: две стороны одной ошибки

Интуиция

Confusion matrix показывает четыре числа сразу, но для быстрого сравнения моделей нужны метрики, сжимающие эту информацию до одного-двух чисел — не теряя главного. Precision и recall делают это, но отвечают на принципиально разные вопросы.

Precision (точность предсказаний) отвечает на вопрос: «из всех объектов, которые модель пометила как положительные, какая доля реально положительна?» Это метрика доверия к положительным предсказаниям модели — высокий precision означает, что если модель сказала «да», то она почти наверняка права.

Recall (полнота) отвечает на другой вопрос: «из всех объектов, которые реально положительны, какую долю модель нашла?» Это метрика полноты охвата — высокий recall означает, что модель не пропускает положительные случаи, даже ценой лишних ложных тревог.

Формулы

Precision и recall.

$$\text{Precision} = \frac{TP}{TP + FP}$$

$$\text{Recall} = \frac{TP}{TP + FN}$$

Обрати внимание на знаменатели: у precision в знаменателе стоит всё, что модель предсказала положительным ($TP+FP$), а у recall в знаменателе — всё, что реально положительно ($TP+FN$). Это разные множества объектов, и именно поэтому precision и recall почти никогда не равны друг другу.

Компромисс между precision и recall

Precision и recall связаны через порог классификации (classification threshold) — значение вероятности, начиная с которого модель решает выдать «положительный» ответ. Большинство моделей классификации на выходе выдают не жёсткое «да/нет», а вероятность от 0 до 1, и именно порог (по умолчанию обычно 0.5) превращает эту вероятность в конкретное предсказание.

Если понизить порог (например, помечать «положительным» уже при вероятности 0.3), модель начинает предсказывать «положительный» чаще — она находит больше реальных положительных случаев (recall растёт), но заодно чаще ошибочно помечает отрицательные объекты как положительные (precision падает). Если поднять порог (например, до 0.8), происходит обратное: модель становится осторожнее, реже ошибается на положительных предсказаниях (precision растёт), но при этом пропускает больше реальных положительных случаев (recall падает). Именно поэтому нельзя одновременно максимизировать и precision, и recall — рост одной метрики почти всегда идёт за счёт другой, и выбор порога — это осознанный компромисс, а не поиск «идеальной» точки, которая устраивает всех.

Пример 1: спам-фильтр (полный расчёт с приоритетом precision)

Почтовый сервис протестировал спам-фильтр на 5 000 писем, из которых реально спам — 500.

                     Предсказано: спам   Предсказано: не спам
Реально: спам             TP = 400             FN = 100
Реально: не спам           FP = 50              TN = 4450

Проверка: $400+100=500$ ✓, $50+4450=4500$, всего $400+100+50+4450=5000$ ✓.

$$\text{Precision} = \frac{400}{400+50} = \frac{400}{450} \approx 0{,}889 = 88{,}9\%$$$$\text{Recall} = \frac{400}{400+100} = \frac{400}{500} = 0{,}8 = 80\%$$$$\text{Accuracy} = \frac{400+4450}{5000} = \frac{4850}{5000} = 0{,}97 = 97\%$$

Здесь $FP=50$ означает, что 50 нормальных писем попали в спам — то есть 50 раз пользователь рискует не увидеть важное письмо (например, приглашение на собеседование или письмо от банка). Именно эту ошибку почтовый сервис старается минимизировать в первую очередь, соглашаясь на чуть более низкий recall: лучше пропустить в инбокс немного спама ($FN=100$, немного раздражает, но не критично), чем потерять важное письмо в спам-папке.

Пример 2: скрининг рака (полный расчёт с приоритетом recall)

Модель скрининга рака проверена на 2 000 пациентах, реально больных — 40.

                       Предсказано: болен   Предсказано: здоров
Реально: болен               TP = 32              FN = 8
Реально: здоров               FP = 200             TN = 1760

Проверка: $32+8=40$ ✓, $200+1760=1960$, всего $32+8+200+1760=2000$ ✓.

$$\text{Precision} = \frac{32}{32+200} = \frac{32}{232} \approx 0{,}138 = 13{,}8\%$$$$\text{Recall} = \frac{32}{32+8} = \frac{32}{40} = 0{,}8 = 80\%$$$$\text{Accuracy} = \frac{32+1760}{2000} = \frac{1792}{2000} = 0{,}896 = 89{,}6\%$$

Precision здесь драматически низкий — лишь 13.8% пациентов с положительным результатом теста реально больны, остальные 86.2% — ложные тревоги ($FP=200$). Казалось бы, это провальная модель. Но для первичного скрининга это абсолютно приемлемо: пациентов с положительным результатом просто направляют на более точное, но дорогое обследование, а ложная тревога стоит им лишь дополнительного визита к врачу. Куда важнее $FN=8$ — восемь реально больных пациентов, которых тест пропустил и которые не получат дальнейшего обследования вовсе. Именно поэтому для скрининга редких и опасных болезней recall почти всегда важнее precision, и модели специально настраивают на низкий порог классификации, чтобы recall был как можно ближе к 100%, даже ценой обвала precision.

Пример 3: как порог меняет precision и recall

Одна и та же модель кредитного скоринга (предсказывает, вернёт ли заёмщик кредит вовремя; «положительный» класс — «не вернёт», то есть дефолт) протестирована на 1 000 заявках с 100 реальными дефолтами при трёх разных порогах:

Порог 0.3 (осторожный банк, ловит почти всех):
TP=90, FN=10, FP=300, TN=600
Precision = 90/390 ≈ 23,1%     Recall = 90/100 = 90%

Порог 0.5 (стандартный):
TP=70, FN=30, FP=100, TN=800
Precision = 70/170 ≈ 41,2%     Recall = 70/100 = 70%

Порог 0.7 (уверенный, одобряет только «надёжным»):
TP=40, FN=60, FP=20, TN=900
Precision = 40/60 ≈ 66,7%      Recall = 40/100 = 40%

Картина видна невооружённым глазом: чем выше порог, тем выше precision и тем ниже recall — модель становится избирательнее в своих положительных предсказаниях, но пропускает всё больше реальных дефолтов. Банк, для которого пропущенный дефолт стоит очень дорого (потеря всей суммы кредита), выберет низкий порог ради высокого recall; банк, который боится необоснованно отказывать надёжным клиентам (и терять на этом комиссии), выберет более высокий порог ради высокого precision. Подробно техника выбора оптимального порога через ROC-кривую разбирается в следующем уроке.

Почему это важно

Precision и recall не заменяют друг друга и не сводятся к одному «правильному» числу — они измеряют две принципиально разные вещи: насколько можно доверять положительным предсказаниям модели и насколько полно модель находит всё, что должна найти. Инженер, который смотрит только на одну из этих метрик, рискует принять решение, которое хорошо выглядит на бумаге, но провально в реальном бизнес-контексте — именно поэтому следующий раздел показывает, как объединить обе метрики в одно число и как выбирать между ними осознанно.

F1-score и выбор метрики под бизнес-контекст

Интуиция

Когда нужно сравнить несколько моделей одним числом, а не парой чисел (precision, recall), возникает соблазн просто усреднить их арифметически. Но простое среднее арифметическое обманчиво: модель с precision 100% и recall 1% (предсказывает «положительный» только для одного объекта, зато угадывает его точно) получит арифметическое среднее $\frac{100+1}{2}=50{,}5\%$ — почти столько же, сколько сбалансированная модель с precision 60% и recall 60%. Но первая модель практически бесполезна (recall 1% означает, что она нашла один из ста положительных случаев), а вторая — вполне рабочая. F1-score решает эту проблему, используя не арифметическое, а гармоническое среднее, которое резко штрафует любой сильный перекос в сторону одной из двух метрик.

Формула

F1-score.

$$F_1 = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}} = \frac{2\,TP}{2\,TP + FP + FN}$$

Гармоническое среднее всегда меньше или равно арифметическому среднему тех же двух чисел, и тем сильнее отличается от него, чем больше разница между precision и recall. Если precision или recall равны нулю, F1 тоже равен нулю — в отличие от арифметического среднего, которое в этом случае осталось бы положительным.

Пример 1: почему F1 честнее среднего арифметического

Возьмём ту самую «вырожденную» модель: она находит только один реально положительный объект из 100 и угадывает его точно, не давая ни одного ложного срабатывания: $TP=1$, $FN=99$, $FP=0$.

$$\text{Precision} = \frac{1}{1+0} = 1{,}0 = 100\%, \qquad \text{Recall} = \frac{1}{1+99} = 0{,}01 = 1\%$$

Арифметическое среднее: $\frac{100\%+1\%}{2}=50{,}5\%$ — выглядит как «средняя» модель.

$$F_1 = 2\cdot\frac{1{,}0 \cdot 0{,}01}{1{,}0+0{,}01} = 2\cdot\frac{0{,}01}{1{,}01} \approx 0{,}0198 = 1{,}98\%$$

F1 честно показывает: модель почти бесполезна, потому что она находит лишь ничтожную долю реальных положительных случаев, несмотря на идеальный precision.

Пример 2: F1 при выборе между двумя моделями детекции мошенничества

Платёжная система сравнивает две модели на одном и том же тестовом наборе, где реально мошеннических транзакций — 150.

Модель A: TP=120, FP=15,  FN=30
Precision = 120/135 ≈ 88,9%    Recall = 120/150 = 80%
F1 = 2 · (0,889 · 0,80) / (0,889 + 0,80) ≈ 2 · 0,7112/1,689 ≈ 0,842 = 84,2%

Модель B: TP=135, FP=90,  FN=15
Precision = 135/225 = 60%      Recall = 135/150 = 90%
F1 = 2 · (0,60 · 0,90) / (0,60 + 0,90) = 2 · 0,54/1,50 = 0,72 = 72%

По F1 модель A выигрывает (84.2% против 72%) — она даёт более сбалансированный компромисс. Но если для этой платёжной системы пропущенное мошенничество ($FN$) стоит компании в среднем в 10 раз дороже, чем ручная проверка легитимной транзакции ($FP$), то оценивать модели нужно не по F1, а по ожидаемым деньгам: модель B пропускает всего 15 случаев мошенничества против 30 у модели A — при достаточно высокой цене $FN$ модель B, несмотря на более низкий F1, может оказаться выгоднее. Это ключевой момент: F1 — по-прежнему компромисс, и он предполагает, что цена FP и цена FN примерно равны; как только это не так, нужно либо взвешивать метрики (например, F2-score, придающий recall больший вес), либо явно считать бизнес-стоимость ошибок в деньгах, как показано в разборе ниже.

Пример 3: явный выбор метрики по бизнес-контексту

Сведём воедино две ситуации из предыдущих разделов и явно сформулируем правило выбора метрики:

Детекция рака (из примера в разделе про precision/recall: $TP=32$, $FN=8$, $FP=200$): цена $FN$ — не диагностированный рак, потенциально смертельно; цена $FP$ — лишнее, но не опасное обследование. Recall здесь однозначно важнее precision, и именно recall (в идеале — близкий к 100%) становится главной метрикой, по которой настраивается порог, а F1 в лучшем случае используется как вспомогательная величина для контроля, чтобы precision не упал совсем уж катастрофически низко.

Спам-фильтр (из примера: $TP=400$, $FP=50$, $FN=100$): цена $FP$ — пропущенное важное письмо, потенциально серьёзные последствия (провалить дедлайн, не увидеть приглашение на работу); цена $FN$ — немного спама в инбоксе, раздражает, но не критично. Precision здесь важнее recall, и именно его стараются держать максимально высоким, соглашаясь на то, что часть спама всё же проскочит в инбокс.

Общее правило: если цена пропущенного положительного случая ($FN$) высока — оптимизируй recall (медицина, безопасность, детекция мошенничества с крупными суммами). Если цена ложной тревоги ($FP$) высока — оптимизируй precision (спам-фильтры, блокировка аккаунтов, автоматические юридически значимые решения). Если обе ошибки примерно равноценны и нужен единый ориентир для сравнения моделей — используй F1-score.

Почему это важно

F1-score — не «главная» метрика классификации и не универсальный ответ на вопрос «какая модель лучше», а инструмент для случая, когда precision и recall одинаково важны и нужно свести их к одному числу для сравнения моделей или конфигураций. Выбор метрики — это не техническое, а продуктовое решение: прежде чем оптимизировать модель, ML-инженер обязан явно ответить на вопрос «что дороже — ложная тревога или пропуск?», и уже отталкиваясь от ответа, выбирать, что максимизировать — recall, precision, F1 или их взвешенный вариант.

Практика: 30 заданий

Базовые задания (1–10)

Задание 1: Модель дала следующие результаты на тестовой выборке из 100 объектов: $TP=40$, $TN=45$, $FP=10$, $FN=5$. Вычислить accuracy.


Задание 2: Для той же модели ($TP=40$, $TN=45$, $FP=10$, $FN=5$) вычислить precision.


Задание 3: Для той же модели ($TP=40$, $TN=45$, $FP=10$, $FN=5$) вычислить recall.


Задание 4: Используя precision = 80% и recall ≈ 88.9% из заданий 2 и 3, вычислить F1-score.


Задание 5: В датасете 100 000 транзакций, из них 100 мошеннических (0.1%). Модель-заглушка всегда предсказывает «легитимная». Вычислить её accuracy и объяснить, почему эта цифра вводит в заблуждение.


Задание 6: Модель определяет, является ли отзыв о товаре положительным. Проверили на 8 отзывах:

Отзыв 1: реально положительный, предсказано положительный
Отзыв 2: реально положительный, предсказано отрицательный
Отзыв 3: реально отрицательный, предсказано отрицательный
Отзыв 4: реально положительный, предсказано положительный
Отзыв 5: реально отрицательный, предсказано положительный
Отзыв 6: реально отрицательный, предсказано отрицательный
Отзыв 7: реально положительный, предсказано положительный
Отзыв 8: реально отрицательный, предсказано отрицательный

Построить confusion matrix (найти $TP$, $TN$, $FP$, $FN$).


Задание 7: Используя confusion matrix из задания 6 ($TP=3$, $TN=3$, $FP=1$, $FN=1$), вычислить accuracy, precision и recall.


Задание 8: Модель А получила precision = 90%, recall = 30%. Модель Б получила precision = 55%, recall = 60%. Не считая F1, объяснить только по определениям, какая модель реже «поднимает ложную тревогу», а какая реже «пропускает» реальный положительный случай.


Задание 9: Вычислить F1-score для обеих моделей из задания 8 и определить, какая из них лучше сбалансирована.


Задание 10: Ниже — фрагмент вывода sklearn.metrics.classification_report для модели, определяющей класс 1 («положительный») против класса 0:

              precision    recall  f1-score   support

           0       0.97      0.99      0.98      950
           1       0.72      0.45      0.55       50

Объяснить, для какого класса модель работает заметно хуже, и указать, какая именно метрика это показывает нагляднее всего.


Средние задания (11–20)

Задание 11: Интернет-магазин протестировал модель определения фальшивых отзывов на 3 000 отзывах, из которых реально фальшивых — 300. Confusion matrix: $TP=210$, $FN=90$, $FP=140$, $TN=2560$. Проверить согласованность чисел и вычислить accuracy, precision, recall, F1.


Задание 12: Страховая компания тестирует модель детекции мошеннических страховых заявок на 4 000 заявках, реально мошеннических — 80. Confusion matrix: $TP=60$, $FN=20$, $FP=300$, $TN=3620$. Вычислить precision, recall и F1, и объяснить одним предложением, почему такой низкий precision может быть приемлемым.


Задание 13: Сравнить две модели скрининга заболевания по recall: модель А — recall = 65%, модель Б — recall = 92%, при этом precision модели А = 80%, а модели Б = 35%. Какую модель выбрать для первичного скрининга, где пропуск больного намного дороже лишнего обследования?


Задание 14: Модель детекции возгораний по видеопотоку с камер протестирована на 10 000 кадрах, из них 20 кадров реально содержат начало возгорания. Модель дала 18 верных срабатываний на реальных возгораниях, пропустив 2, и ошибочно сработала на 45 кадрах без возгорания. Построить confusion matrix и вычислить accuracy, precision, recall.


Задание 15: Одна и та же модель кредитного скоринга при пороге 0.4 даёт $TP=85$, $FN=15$, $FP=250$, $TN=650$; при пороге 0.6 даёт $TP=55$, $FN=45$, $FP=80$, $TN=820$. Вычислить precision и recall для обоих порогов и описать словами, что произошло при повышении порога.


Задание 16: На сбалансированном датасете (500 котов, 500 собак) модель дала $TP=460$ (коты верно распознаны), $FN=40$, $FP=35$, $TN=465$ (класс «кот» считается положительным). Вычислить accuracy, precision, recall и объяснить, почему здесь accuracy — вполне информативная метрика.


Задание 17: Почтовый сервис сравнивает два спам-фильтра на одном тестовом наборе из 6 000 писем, реально спама — 600. Фильтр А: $TP=520$, $FP=20$, $FN=80$. Фильтр Б: $TP=580$, $FP=200$, $FN=20$. Вычислить precision и recall для обоих и определить, какой фильтр предпочесть, если для сервиса важнее всего не блокировать легитимные письма.


Задание 18: Дан фрагмент вывода sklearn.metrics.confusion_matrix() для модели определения дефолта по кредиту (строки — реальные классы, столбцы — предсказанные; класс 1 = «дефолт»):

[[860  40]
 [ 30  70]]

Определить $TP$, $TN$, $FP$, $FN$ и вычислить precision и recall для класса 1.


Задание 19: Две модели имеют одинаковую accuracy = 95% на датасете из 2 000 объектов, где реально положительных всего 40. Модель А: $TP=0$, $FN=40$, $FP=0$, $TN=1960$. Модель Б: $TP=20$, $FN=20$, $FP=80$, $TN=1880$. Проверить accuracy для обеих и показать, что recall выявляет принципиальную разницу между ними.


Задание 20: В датасете 90% объектов принадлежат классу 0 и 10% — классу 1. Вывести общую формулу accuracy наивной модели, которая всегда предсказывает класс 0, через долю класса 0 в данных, и вычислить её accuracy для этого конкретного датасета.


Продвинутые задания (21–30)

Задание 21: Интернет-магазин детектирует поддельные отзывы. Цена ложной тревоги (заблокировать честный отзыв, $FP$) — 50 рублей упущенной прибыли за потерю доверия покупателя. Цена пропуска ($FN$, поддельный отзыв остался) — 300 рублей репутационных потерь. Модель А: $FP=200$, $FN=40$. Модель Б: $FP=50$, $FN=90$. Посчитать общие ожидаемые издержки для обеих моделей и выбрать более выгодную, даже если её F1 ниже.


Задание 22: Доказать алгебраически, что формулу $F_1 = 2\cdot\dfrac{\text{Precision}\cdot\text{Recall}}{\text{Precision}+\text{Recall}}$ можно переписать как $F_1 = \dfrac{2\,TP}{2\,TP+FP+FN}$, подставив определения precision и recall.


Задание 23: Три модели детекции опухолей на снимках дали: модель 1 — precision 92%, recall 40%; модель 2 — precision 70%, recall 75%; модель 3 — precision 45%, recall 95%. Заказчик поставил условие: recall должен быть не ниже 90%. Из допустимых моделей выбрать лучшую по precision.


Задание 24: Показать на числовом примере, что F1-score всегда меньше или равен среднему арифметическому precision и recall, взяв precision = 100%, recall = 20%.


Задание 25: Модель распознавания лиц для системы контроля доступа протестирована при трёх порогах: порог 1 даёт $TP=95$, $FN=5$, $FP=120$; порог 2 даёт $TP=85$, $FN=15$, $FP=30$; порог 3 даёт $TP=70$, $FN=30$, $FP=5$ (всего реально «свой» — 100 попыток входа). Вычислить recall для всех трёх порогов и выбрать порог для системы, где пропуск «чужого» ($FN$ в терминах задачи «чужой опознан как свой» — иначе говоря, речь о безопасности, поэтому нужно определить, какая ошибка здесь опаснее) недопустим.


Задание 26: Известно, что accuracy модели на датасете из 5 000 объектов равна 96%, а среди объектов 4 800 принадлежат классу 0 и 200 — классу 1. Модель также известна тем, что $TN = 4750$. Восстановить остальные три ячейки confusion matrix ($TP$, $FP$, $FN$).


Задание 27: Детский сад использует модель определения возможных признаков заболевания у ребёнка по фото (для раннего оповещения родителей), где заболевание встречается у 1 из 500 детей. Модель-заглушка «здоров всегда» проверена на 5 000 детях. Вычислить её accuracy, recall и явно показать парадокс: почему одна и та же ситуация «выглядит» отлично по одной метрике и катастрофически по другой.


Задание 28: Дан фрагмент classification_report для модели определения токсичных комментариев:

              precision    recall  f1-score   support

  не токсичный   0.96      0.98      0.97      9500
     токсичный   0.62      0.41      0.49       500

Определить, для какого класса модель хуже справляется с обеими типами ошибок одновременно, и обосновать численно через F1.


Задание 29: Три модели детекции критических сбоев сервера должны обеспечивать recall не ниже 95% (пропущенный сбой стоит компании остановки сервиса). Модель 1: recall 96%, precision 20%. Модель 2: recall 98%, precision 12%. Модель 3: recall 93%, precision 55%. Выбрать допустимую модель с максимальным precision и объяснить, почему модель 3, несмотря на лучший precision, отклоняется.


Задание 30 (итоговое): Банк тестирует финальную модель детекции мошеннических переводов на 20 000 транзакциях, реально мошеннических — 400. Итоги: $TP=340$, $FN=60$, $FP=680$, $TN=18920$. Вычислить accuracy, precision, recall и F1, а затем сформулировать краткую рекомендацию банку: на какую метрику ориентироваться при принятии решения о внедрении модели и почему.

Частые ошибки

Ошибка 1: слепая вера в высокую accuracy. Самая опасная и самая распространённая ошибка новичка — увидеть accuracy 95–99% и сразу считать модель отличной, не проверив баланс классов. Как показано в разделе про accuracy, при сильном дисбалансе даже модель-заглушка, ничего не анализирующая, получает такую же или более высокую цифру. Перед тем как доверять accuracy, всегда сначала посмотри на распределение классов в данных.

Ошибка 2: путаница между precision и recall. Обе метрики звучат похоже и обе используют $TP$ в числителе, из-за чего их легко перепутать местами. Запоминай через сам вопрос, а не через формулу: precision отвечает «насколько я могу доверять положительным предсказаниям модели», recall — «сколько реальных положительных случаев модель нашла». Если сомневаешься — посмотри на знаменатель: у precision в знаменателе то, что предсказала модель, у recall — то, что реально есть в данных.

Ошибка 3: оптимизация F1 без понимания бизнес-контекста. F1-score удобен именно тем, что сводит всё к одному числу, но это же делает его соблазнительным для бездумной оптимизации. Если цена $FP$ и цена $FN$ в конкретной задаче сильно различаются (как в примерах с раком и спамом), оптимизация чистого F1 без учёта этой асимметрии может привести к модели, которая математически неплохо сбалансирована, но провальна с точки зрения бизнеса.

Ошибка 4: игнорирование метрик по отдельным классам в многоклассовых задачах. Общая accuracy или усреднённый F1 по всем классам легко маскируют то, что модель отлично работает на нескольких «лёгких» частых классах и почти бесполезна на редких — ровно как в заданиях 10, 26 и 28 этого урока. Всегда проверяй classification_report по каждому классу отдельно, а не только итоговую усреднённую строку.

Ошибка 5: сравнение моделей по разным метрикам. Если модель А выбрана по максимальному recall, а модель Б — по максимальному precision, их нельзя корректно сравнивать напрямую: одна оптимизирована под одну задачу, другая — под другую. Для честного сравнения нужно либо зафиксировать одну и ту же метрику для обеих, либо явно посчитать ожидаемую бизнес-стоимость ошибок для каждой, как в задании 21.

Ошибка 6: забывать, что порог классификации — это отдельная настройка, а не свойство модели. Precision и recall одной и той же обученной модели могут сильно отличаться в зависимости от выбранного порога (см. пример 3 в разделе про precision/recall и задание 15). Указывать precision или recall без упоминания порога, при котором они посчитаны, — неполная и потенциально вводящая в заблуждение информация.

Главное запомнить

  • Accuracy = $(TP+TN)/(TP+TN+FP+FN)$ — доля верных предсказаний; опасна при дисбалансе классов, потому что даже бесполезная модель-заглушка может показывать accuracy, близкую к доле класса большинства.

  • Confusion matrix (матрица ошибок) раскладывает предсказания на четыре ячейки — $TP$, $TN$, $FP$, $FN$ — и показывает не только «насколько модель права», но и «в какую сторону она ошибается».

  • $FP$ (ложноположительный) — модель ошибочно сказала «да» на реально отрицательном объекте; $FN$ (ложноотрицательный) — модель ошибочно сказала «нет» на реально положительном объекте. Цена этих двух ошибок в реальных задачах почти никогда не совпадает.

  • Precision = $TP/(TP+FP)$ — доверие к положительным предсказаниям модели; высокий precision означает мало ложных тревог.

  • Recall = $TP/(TP+FN)$ — полнота охвата реальных положительных случаев; высокий recall означает мало пропусков.

  • Precision и recall почти всегда противоречат друг другу и управляются через порог классификации: понижение порога повышает recall и понижает precision, повышение порога — наоборот.

  • F1-score — гармоническое среднее precision и recall, резко штрафующее сильный перекос в одну сторону; полезен, когда обе ошибки примерно равноценны и нужно одно число для сравнения моделей.

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

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

  • Всегда проверяй метрики по каждому классу отдельно в многоклассовых и несбалансированных задачах — общая усреднённая цифра systematically скрывает провал на редких классах.

Связь с темами курса

Этот урок напрямую продолжает урок 306 о кросс-валидации: там ты научился честно оценивать модель на нескольких разбиениях данных, а здесь — чем именно её оценивать, когда речь идёт о классификации. Confusion matrix, precision, recall и F1-score из этого урока — это ровно те метрики, которые усредняются по фолдам при кросс-валидации, если задача связана с классификацией, а не с регрессией.

Всё, что разобрано здесь, построено вокруг одного фиксированного порога классификации — обычно 0.5. Но что, если посмотреть, как precision и recall меняются сразу для всех возможных порогов, не выбирая один конкретный заранее? Именно этому посвящён следующий урок 308 — ROC-кривая и AUC: там ты увидишь, как визуализировать весь спектр компромиссов между recall (там он называется True Positive Rate) и ложными тревогами при любом пороге разом, и как одним числом (площадью под кривой) сравнивать модели независимо от выбора конкретного порога.

Дальше по курсу метрики этого урока станут рабочим инструментом при разборе конкретных алгоритмов классификации — логистической регрессии, решающих деревьев, случайного леса, градиентного бустинга и нейронных сетей: качество каждого из них будет оцениваться именно через precision, recall и F1, а не через одну лишь accuracy.

Интересные факты

  • В радиолокации, откуда исторически пришла идея confusion matrix, термин «false alarm rate» (частота ложных тревог) используется до сих пор — это прямой аналог $1-\text{Specificity}$, метрики, тесно связанной с precision и recall и особенно важной в задачах безопасности.

  • В соревнованиях Kaggle организаторы почти никогда не используют голую accuracy как метрику оценки — подавляющее большинство задач классификации там сбалансированы через F1-score, log loss или AUC именно потому, что реальные датасеты почти всегда имеют дисбаланс классов той или иной степени.

  • Название «recall» в информационном поиске исторически связано с идеей «вспомнить» (recall) все релевантные документы из памяти системы — метафора восходит к экспериментам по человеческой памяти в психологии XIX века, где recall тоже означал долю вспомненных фактов из общего числа предъявленных.

  • Существует целое семейство метрик $F_\beta$, обобщающих F1: при $\beta>1$ метрика придаёт больший вес recall (используется, например, в медицинской диагностике), а при $\beta<1$ — больший вес precision (например, в задачах модерации контента, где важнее не заблокировать легитимный материал).

Лайфхаки

  • Прежде чем смотреть на любую метрику, первым делом проверь долю каждого класса в данных — команда y.value_counts(normalize=True) в pandas за одну строку покажет, стоит ли вообще доверять accuracy в этой задаче.

  • Держи в голове простое правило-мнемонику: precision — про предсказания модели («из того, что предсказано положительным»), recall — про реальность («из того, что реально положительно»). Совпадение первых букв «предсказания» и «precision» помогает не путать их на собеседовании или в спешке.

  • Используй sklearn.metrics.classification_report(y_true, y_pred) как стандартный первый шаг оценки любой модели классификации — он сразу выводит precision, recall, F1 и support (число объектов) по каждому классу, избавляя от необходимости считать confusion matrix вручную.

  • Если задача явно требует определённого минимума по одной метрике (например, «recall должен быть не ниже 95%» для медицинского скрининга, как в задании 29), сначала отфильтруй модели или пороги по этому жёсткому ограничению, и только потом сравнивай прошедшие отбор варианты по второй метрике.

  • Когда цена ошибок известна в деньгах или другом измеримом эквиваленте (как в задании 21), не ограничивайся стандартными метриками — построй явную формулу ожидаемых издержек через $FP$ и $FN$ и оптимизируй её напрямую: это почти всегда даёт более точный бизнес-результат, чем оптимизация абстрактного F1.

  • Не выбирай метрику один раз и навсегда для всего проекта — держи в голове, что порог классификации можно и нужно донастраивать под конкретную цель уже после обучения модели, не переобучая её заново; следующий урок про ROC-кривую даст для этого точный инструмент.

Освоив этот урок, ты умеешь не просто запускать model.score(), а по-настоящему задавать модели правильный вопрос: не «как часто ты права», а «какую именно ошибку ты совершаешь, и сколько она стоит бизнесу». Это ровно тот навык, который отличает инженера, слепо доверяющего одной цифре, от специалиста, способного осознанно выбрать метрику под задачу — а значит, ты готов к следующему шагу: разбору ROC-кривой и AUC, которые покажут всю картину компромисса между precision и recall сразу, для любого порога.

Понял тему? Закрепи в боте! 🚀

Попрактикуйся на задачах и получи персональные рекомендации от AI

💪 Начать тренировку
💬 Есть вопрос? Спроси бота!