Метрики показывают, насколько хорошо модель делает предсказания. Без них невозможно понять, работает ли модель.
Confusion Matrix
Основа всех метрик. Для задачи бинарной классификации:
Predicted
Positive Negative
Actual
Positive TP FN
Negative FP TN
- TP — правильно нашли положительные
- TN — правильно нашли отрицательные
- FP — ложная тревога (нормальное посчитали позитивным)
- FN — пропуск (позитивное не нашли)
def confusion_matrix(predictions, actuals):
"""Вычислить TP/TN/FP/FN."""
tp = sum(1 for p, a in zip(predictions, actuals) if p == 1 and a == 1)
tn = sum(1 for p, a in zip(predictions, actuals) if p == 0 and a == 0)
fp = sum(1 for p, a in zip(predictions, actuals) if p == 1 and a == 0)
fn = sum(1 for p, a in zip(predictions, actuals) if p == 0 and a == 1)
return {"TP": tp, "TN": tn, "FP": fp, "FN": fn}
preds = [1, 0, 1, 1, 0, 1, 0, 0, 1, 1]
actuals = [1, 0, 0, 1, 0, 1, 1, 0, 1, 0]
print(confusion_matrix(preds, actuals))
# {'TP': 4, 'TN': 3, 'FP': 2, 'FN': 1}
Precision, Recall, F1
def precision(tp, fp):
"""Из всех «положительных» предсказаний, сколько правильных?"""
return tp / (tp + fp) if tp + fp else 0
def recall(tp, fn):
"""Из всех реальных «положительных», сколько нашли?"""
return tp / (tp + fn) if tp + fn else 0
def f1_score(prec, rec):
"""Гармоническое среднее Precision и Recall."""
return 2 * prec * rec / (prec + rec) if prec + rec else 0
# Пример
tp, fp, fn = 80, 20, 20
p = precision(tp, fp) # 0.80
r = recall(tp, fn) # 0.80
f = f1_score(p, r) # 0.80
print(f"Precision: {p:.2%}, Recall: {r:.2%}, F1: {f:.2%}")
Precision vs Recall — trade-off: строгая модель даёт высокий Precision (мало FP), но низкий Recall (много FN). Мягкая модель — наоборот. F1 балансирует оба.
Выбор метрики
| Задача | Метрика | Причина |
|---|---|---|
| Спам-фильтр | Precision | Нельзя удалять нормальные письма |
| Детекция болезней | Recall | Нельзя пропустить заболевание |
| Детекция мошенничества | Recall | Поймать все случаи |
| Рекомендации | F1-Score | Баланс точности и полноты |
| Сбалансированные классы | Accuracy | Классы равномерны |
Практический пример
m = confusion_matrix(preds, actuals)
p = precision(m["TP"], m["FP"])
r = recall(m["TP"], m["FN"])
f = f1_score(p, r)
total = sum(m.values())
acc = (m["TP"] + m["TN"]) / total
print(f"Accuracy: {acc:.2%}")
print(f"Precision: {p:.2%}")
print(f"Recall: {r:.2%}")
print(f"F1-Score: {f:.2%}")
Частые ошибки
Accuracy при несбалансированных классах — если 95% примеров отрицательные, модель «всегда говорит нет» и получает Accuracy 95%, но Recall = 0%. Используй F1.
Одна метрика для всех задач — выбирай метрику под контекст: медицина → Recall, спам → Precision.
💬 Комментарии (0)
Комментариев пока нет
Станьте первым, кто поделится мнением об этой статье!