Метрики классификации: accuracy, precision, recall, F1

Метрики классификации: accuracy, precision, recall, F1 Scikit-learn

Привет! Ты уже научился обучать модели классификации — например, логистическую регрессию для определения, болен пациент или нет. Но как понять, насколько хороша твоя модель? Просто посчитать процент правильных ответов? В реальных задачах этого часто недостаточно.

В этой статье мы разберём четыре ключевые метрики для классификации:

  • Accuracy — общая точность
  • Precision — точность (качество положительных предсказаний)
  • Recall — полнота (способность находить все положительные объекты)
  • F1-score — гармоническое среднее precision и recall

Узнаем, когда какая метрика важна и почему accuracy может обманывать.

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный scikit-learn (pip install scikit-learn)
  • Базовое понимание классификации
  • Знание логистической регрессии из предыдущих статей

Совет: Выбор метрики — это не просто технический шаг. Он зависит от бизнес-задачи. Если ты пропустишь опасную болезнь — это хуже, чем ошибочно вылечить здорового. Понимание метрик поможет тебе выбирать правильную модель.

Основная часть

Матрица ошибок (Confusion Matrix)

Все метрики классификации строятся на основе матрицы ошибок. Это таблица, которая показывает, сколько объектов модель классифицировала правильно, а сколько — нет.

Предсказано: Да (1)Предсказано: Нет (0)
Факт: Да (1)TP (True Positive)FN (False Negative)
Факт: Нет (0)FP (False Positive)TN (True Negative)

Расшифровка:

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

Совет: В задачах медицины: FN (пропуск болезни) опаснее, чем FP (ложная тревога). В задачах спам-фильтра: FP (пометка хорошего письма как спама) хуже, чем FN (пропуск спама).

Accuracy (Общая точность)

Accuracy — это доля всех правильных ответов.

Формула:Accuracy=TP+TNTP+TN+FP+FNAccuracy=TP+TN+FP+FNTP+TN

Когда использовать:

  • Когда классы сбалансированы (примерно поровну).
  • Когда цена ошибки примерно одинакова для всех классов.

Проблема: Accuracy может вводить в заблуждение при несбалансированных данных. Если у тебя 99% объектов класса 0 и 1% класса 1, модель, которая всегда предсказывает 0, получит accuracy = 99%, но при этом она бесполезна.

Совет: Смотри на accuracy вместе с другими метриками. Никогда не полагайся только на неё в задачах с несбалансированными классами.

Precision (Точность)

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

Формула:Precision=TPTP+FPPrecision=TP+FPTP

Когда важна precision:

  • Когда ложные срабатывания (FP) стоят дорого. Например, в спам-фильтре: если обычное письмо попало в спам — это плохо.
  • Высокая precision = мало ложных срабатываний.

Совет: Precision отвечает на вопрос: «Когда модель говорит, что объект положительный, можно ли ей верить?». Высокая precision означает, что модель редко ошибается, когда говорит «да».

Recall (Полнота)

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

Формула:Recall=TPTP+FNRecall=TP+FNTP

Когда важен recall:

  • Когда пропуск цели (FN) стоит дорого. Например, в медицине: пропустить болезнь — это опасно.
  • Высокий recall = мало пропущенных положительных объектов.

Совет: Recall отвечает на вопрос: «Модель нашла все положительные объекты или что-то пропустила?». Высокий recall означает, что модель почти ничего не пропускает.

F1-score (F1-мера)

F1-score — это гармоническое среднее precision и recall. Он даёт одну метрику, которая балансирует между ними.

Формула:F1=2×Precision×RecallPrecision+RecallF1=2×Precision+RecallPrecision×Recall

Когда использовать F1:

  • Когда важны и precision, и recall.
  • Когда нужно найти баланс между ними.
  • При несбалансированных данных.

Совет: F1-score — это «золотая середина». Если ты не знаешь, какую метрику выбрать, начни с F1. Он не даст модели «уйти в крайность».

Сравнение метрик

МетрикаЧто измеряетЛучшее значениеКогда важна
AccuracyДоля всех правильных ответов1.0Сбалансированные данные
PrecisionДоля правильных положительных предсказаний1.0Важны ложные срабатывания (FP)
RecallДоля найденных положительных объектов1.0Важны пропуски (FN)
F1Гармоническое среднее precision и recall1.0Нужен баланс между precision и recall

Совет: Выбор метрики зависит от бизнес-задачи. Не бывает «лучшей» метрики — бывает подходящая.

Реализация на Python с scikit-learn

import numpy as np
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix

# Пример данных
y_true = np.array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0])
y_pred = np.array([1, 0, 1, 1, 0, 0, 1, 0, 1, 0])

# 1. Матрица ошибок
cm = confusion_matrix(y_true, y_pred)
print("Матрица ошибок:")
print(cm)

# 2. Метрики
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)

print(f"\nAccuracy:  {accuracy:.2f}")
print(f"Precision: {precision:.2f}")
print(f"Recall:    {recall:.2f}")
print(f"F1-score:  {f1:.2f}")

Результат:

Матрица ошибок:
[[4 1]
 [1 4]]

Accuracy:  0.80
Precision: 0.80
Recall:    0.80
F1-score:  0.80

Совет: Всегда сначала смотри на матрицу ошибок. Это самый наглядный способ понять, где модель ошибается.

Полный пример: датасет рака молочной железы

import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, classification_report

# 1. Загружаем данные
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target

# 2. Делим на train/test
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 3. Масштабируем
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 4. Обучаем модель
model = LogisticRegression(random_state=42, max_iter=1000)
model.fit(X_train_scaled, y_train)

# 5. Предсказываем
y_pred = model.predict(X_test_scaled)

# 6. Метрики
print("=== Матрица ошибок ===")
print(confusion_matrix(y_test, y_pred))

print("\n=== Метрики ===")
print(f"Accuracy:  {accuracy_score(y_test, y_pred):.2%}")
print(f"Precision: {precision_score(y_test, y_pred):.2%}")
print(f"Recall:    {recall_score(y_test, y_pred):.2%}")
print(f"F1-score:  {f1_score(y_test, y_pred):.2%}")

print("\n=== Полный отчёт ===")
print(classification_report(y_test, y_pred, target_names=cancer.target_names))

Результат (примерный):

=== Матрица ошибок ===
[[40  2]
 [ 1 71]]

=== Метрики ===
Accuracy:  97.37%
Precision: 97.26%
Recall:    98.61%
F1-score:  97.93%

=== Полный отчёт ===
              precision    recall  f1-score   support
   malignant       0.98      0.95      0.96        42
     benign       0.97      0.99      0.98        72

    accuracy                           0.97       114
   macro avg       0.97      0.97      0.97       114
weighted avg       0.97      0.97      0.97       114

Что мы видим:

  • Accuracy = 97.37% — модель правильно классифицирует почти все объекты.
  • Precision = 97.26% — когда модель говорит «злокачественная опухоль», она права в 97.26% случаев.
  • Recall = 98.61% — модель находит 98.61% всех злокачественных опухолей.
  • F1-score = 97.93% — хороший баланс.

Совет: Для медицинских задач критичен Recall — чтобы не пропустить болезнь. Здесь recall = 98.61%, что очень хорошо.

Когда accuracy обманывает

from sklearn.datasets import make_classification
import numpy as np

# Создаём несбалансированный датасет (90% класса 0, 10% класса 1)
X, y = make_classification(n_samples=1000, weights=[0.9, 0.1], random_state=42)

# Модель, которая всегда предсказывает 0
class AlwaysZero:
    def predict(self, X):
        return np.zeros(X.shape[0])

model = AlwaysZero()
y_pred = model.predict(X)

# Метрики
accuracy = accuracy_score(y, y_pred)
precision = precision_score(y, y_pred)
recall = recall_score(y, y_pred)
f1 = f1_score(y, y_pred)

print(f"Accuracy:  {accuracy:.2%}")
print(f"Precision: {precision:.2%}")
print(f"Recall:    {recall:.2%}")
print(f"F1-score:  {f1:.2%}")

Результат:

Accuracy:  90.00%
Precision: 0.00%
Recall:    0.00%
F1-score:  0.00

Важное открытие: Accuracy = 90%, но модель бесполезна! Precision, Recall и F1 = 0.

Совет: Всегда смотри на precision, recall и F1, особенно при несбалансированных данных. Accuracy может обмануть!

Выбор метрики в зависимости от задачи

ЗадачаКакая метрика важнееПочему
Медицина (диагностика)RecallПропуск болезни (FN) опасен
Спам-фильтрPrecisionВажно не потерять хорошие письма (FP)
Банковский скорингPrecisionВажно не выдать кредит мошеннику (FP)
Поиск террористовRecallВажно не пропустить (FN)
Общий случайF1Когда важны и precision, и recall

Задачи для закрепления

Задача 1. Вычисли precision, recall и F1 для TP=40, FP=10, TN=30, FN=20.

Задача 2. В какой задаче важнее recall, чем precision?

Задача 3. Напиши код для вычисления accuracy, precision, recall и F1 с помощью scikit-learn.

Задача 4. Почему accuracy может быть плохой метрикой для несбалансированных данных?

Задача 5. Что означает F1-score = 0.85?

Ответы:

Задача 1.

TP = 40; FP = 10; TN = 30; FN = 20

precision = TP / (TP + FP)  # 40/50 = 0.80
recall = TP / (TP + FN)     # 40/60 = 0.67
f1 = 2 * precision * recall / (precision + recall)  # 0.73

Задача 2.

В задачах, где пропуск положительного объекта опаснее, чем ложное срабатывание. Например, медицина (диагностика рака), поиск террористов.

Задача 3.

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)

Задача 4.

Accuracy обманчива, когда классы несбалансированы. Например, 90% объектов класса 0 и 10% класса 1. Модель, всегда предсказывающая 0, получит accuracy = 90%, но будет бесполезна для нахождения класса 1.

Задача 5.

F1-score = 0.85 означает хороший баланс между precision и recall. Модель находит 85% положительных объектов и при этом выдаёт 85% правильных положительных предсказаний.

Нюансы и подводные камни

Микро- и макро-усреднение

Для многоклассовой классификации используются разные способы усреднения:

  • macro — среднее по классам (каждый класс важен одинаково)
  • weighted — среднее с учётом поддержки классов (размер класса)
  • micro — общие TP/FP/FN по всем классам
precision_macro = precision_score(y_true, y_pred, average='macro')
precision_weighted = precision_score(y_true, y_pred, average='weighted')

Выбор порога

Метрики зависят от порога классификации (по умолчанию 0.5). Для настройки порога используй кривые ROC или PR.

Частые ошибки и как их избежать

Ошибка 1: Использование accuracy на несбалансированных данных

# Accuracy может быть высокой, но модель бесполезна
accuracy = accuracy_score(y_true, y_pred)

# Смотри precision, recall, F1
print(classification_report(y_true, y_pred))

Ошибка 2: Путаница между precision и recall

Запомни:

  • Precision = «Когда модель сказала ‘да’, ей можно верить?»
  • Recall = «Модель нашла все ‘да’?»

Ошибка 3: Использование accuracy для многоклассовой классификации

В многоклассовой классификации смотри также макро- и микро-метрики.

Шпаргалка

Что нужноКак пишется
Accuracyaccuracy_score(y_true, y_pred)
Precisionprecision_score(y_true, y_pred)
Recallrecall_score(y_true, y_pred)
F1f1_score(y_true, y_pred)
Матрица ошибокconfusion_matrix(y_true, y_pred)
Полный отчётclassification_report(y_true, y_pred)
Для многоклассовыхaverage='macro' или 'weighted'

Заключение

Сегодня мы узнали:

  • Что такое матрица ошибок (TP, TN, FP, FN)
  • Accuracy — доля правильных ответов
  • Precision — точность положительных предсказаний
  • Recall — полнота (способность находить все положительные объекты)
  • F1-score — гармоническое среднее precision и recall
  • Почему accuracy может обманывать

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×