← Назад к вопросам

В чем разница между PR-AUC и ROC-AUC?

1.7 Middle🔥 241 комментариев
#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между PR-AUC и ROC-AUC

Определения

ROC-AUC (Receiver Operating Characteristic):

  • X-ось: False Positive Rate (FPR) = FP / (FP + TN)
  • Y-ось: True Positive Rate (TPR) = TP / (TP + FN)

PR-AUC (Precision-Recall):

  • X-ось: Recall = TP / (TP + FN)
  • Y-ось: Precision = TP / (TP + FP)

Визуальное сравнение

from sklearn.metrics import roc_curve, auc, precision_recall_curve
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt

# Генерируем дисбалансированные данные
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2,
                           weights=[0.9, 0.1], random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

model = LogisticRegression()
model.fit(X_train, y_train)
y_proba = model.predict_proba(X_test)[:, 1]

# ROC кривая
fpr, tpr, _ = roc_curve(y_test, y_proba)
roc_auc = auc(fpr, tpr)

# PR кривая
precision, recall, _ = precision_recall_curve(y_test, y_proba)
pr_auc = auc(recall, precision)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# ROC
ax1.plot(fpr, tpr, label=f'ROC (AUC={roc_auc:.2f})')
ax1.plot([0, 1], [0, 1], 'k--')
ax1.set_xlabel('False Positive Rate')
ax1.set_ylabel('True Positive Rate')
ax1.set_title('ROC Curve')
ax1.legend()

# PR
ax2.plot(recall, precision, label=f'PR (AUC={pr_auc:.2f})')
ax2.set_xlabel('Recall')
ax2.set_ylabel('Precision')
ax2.set_title('Precision-Recall Curve')
ax2.legend()

plt.show()

print(f"ROC-AUC: {roc_auc:.4f}")
print(f"PR-AUC:  {pr_auc:.4f}")

Ключевые отличия

АспектROC-AUCPR-AUC
X-осьFPRRecall
Y-осьTPRPrecision
Использование TNДаНет
При дисбалансеМожет быть высокойБолее чувствительна
ИнтерпретацияВероятность правильного ранжированияБаланс Precision-Recall
Идеальная кривая(0,1) точка(1,1) точка

Почему это важно: пример дисбалансированных данных

import numpy as np
from sklearn.metrics import roc_auc_score, auc, precision_recall_curve

# Дисбалансированный датасет: 99% негативных, 1% позитивных
y_true = np.array([0]*990 + [1]*10)

# Наивная модель: предсказывает все как 0
y_pred_naive = np.array([0.1]*990 + [0.1]*10)

# Хорошая модель: различает классы
y_pred_good = np.array([0.1]*990 + [0.9]*10)

print("НАИВНАЯ МОДЕЛЬ (всегда 0.1):")
roc_auc_naive = roc_auc_score(y_true, y_pred_naive)
print(f"ROC-AUC: {roc_auc_naive:.4f}")  # 0.5 (случайно!)

precision, recall, _ = precision_recall_curve(y_true, y_pred_naive)
pr_auc_naive = auc(recall, precision)
print(f"PR-AUC:  {pr_auc_naive:.4f}")  # 0.01 (показывает что модель плохая)

print("\nХОРОШАЯ МОДЕЛЬ:")
roc_auc_good = roc_auc_score(y_true, y_pred_good)
print(f"ROC-AUC: {roc_auc_good:.4f}")  # 1.0 (идеально)

precision, recall, _ = precision_recall_curve(y_true, y_pred_good)
pr_auc_good = auc(recall, precision)
print(f"PR-AUC:  {pr_auc_good:.4f}")  # 1.0 (идеально)

Результат:

НАИВНАЯ МОДЕЛЬ:
ROC-AUC: 0.5000  <- выглядит как случайность
PR-AUC:  0.0091  <- явно показывает, что модель плохая!

ROC-AUC скрывает плохость модели на дисбалансированных данных, потому что TN (истинные негативные) велики.

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

Используй ROC-AUC, если:

  • Данные относительно сбалансированы
  • Важны оба типа ошибок (FP и FN одинаково дорогие)
  • Хочешь стандартную метрику для сравнения моделей

Используй PR-AUC, если:

  • Данные сильно дисбалансированы (положительный класс редкий)
  • Положительный класс важнее негативного
  • Нужна метрика чувствительная к меньшинству
  • Работаешь с fraud detection, anomaly detection, редкими заболеваниями

Практический пример: дисбаланс 99:1

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_auc_score, auc, precision_recall_curve

# 990 негативных + 10 позитивных
X = np.random.normal(0, 1, (1000, 10))
y = np.array([0]*990 + [1]*10)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

model = RandomForestClassifier(random_state=42)
model.fit(X_train, y_train)
y_proba = model.predict_proba(X_test)[:, 1]

roc_auc = roc_auc_score(y_test, y_proba)
precision, recall, _ = precision_recall_curve(y_test, y_proba)
pr_auc = auc(recall, precision)

print(f"ROC-AUC: {roc_auc:.3f}  <- может быть высоким даже если модель слаба на позитивах")
print(f"PR-AUC:  {pr_auc:.3f}  <- точнее отражает качество на редком классе")

Выводы

  1. ROC-AUC — универсальная метрика для сбалансированных данных
  2. PR-AUC — лучше для дисбалансированных данных, особенно когда позитивный класс редкий
  3. При дисбалансе ROC-AUC может быть обманчиво высокой, PR-AUC более честна
  4. Для продакшена с дисбалансом рекомендуется использовать PR-AUC или оба показателя
  5. Всегда смотри на обе метрики — они дают разную информацию