Почему ROC-AUC так любят и так часто неправильно понимают
ROC-AUC — одна из самых популярных метрик в задачах бинарной классификации. Ее любят за то, что она не требует фиксировать порог заранее и показывает способность модели ранжировать объекты: давать более высокий score положительным примерам, чем отрицательным. Но именно в этом же и источник путаницы. Люди часто думают, что высокая ROC-AUC автоматически означает хороший продуктовый результат. Это не всегда так.
ROC-AUC отвечает на вопрос про порядок ранжирования, а не про качество решения на конкретном пороге. Поэтому в одних задачах она очень полезна, а в других ее недостаточно и нужно дополнительно смотреть precision, recall, PR-AUC или бизнесовую стоимость ошибок.
Что именно измеряет ROC-AUC
$$ ROC\\text{-}AUC = P(s(x^+) > s(x^-)) $$Интуитивно эта метрика показывает вероятность того, что случайный положительный объект получит score выше, чем случайный отрицательный.
ROC\\text{-}AUC— площадь под ROC-кривойP— вероятность событияs(x^+)— score положительного объектаs(x^-)— score отрицательного объекта
Это очень сильная идея, потому что она отрывает нас от конкретного порога. Модель хороша не только тогда, когда на одном threshold получилось красивое качество, а тогда, когда она в целом умеет правильно упорядочивать объекты по вероятности положительного класса.
Когда ROC-AUC действительно полезна
Она хороша в ранжирующих задачах и как общий индикатор силы модели на раннем этапе сравнения. Если ты выбираешь между несколькими baseline-моделями и хочешь понять, какая лучше сортирует объекты, ROC-AUC очень удобна. Она также полезна там, где финальный порог будет настраиваться позже, уже под конкретную цену ошибки.
Но если бизнес живет на одном рабочем пороге, ROC-AUC может быть недостаточно. Модель с хорошим ранжированием все еще может давать неудобный precision при выбранном threshold. Поэтому метрика не отменяет последующего анализа решения на практике.
from sklearn.metrics import roc_auc_score # считаем метрику ранжирования без фиксации порога
y_true = [1, 0, 1, 1, 0, 0, 1, 0] # реальные классы объектов
y_score = [0.92, 0.10, 0.81, 0.67, 0.33, 0.21, 0.78, 0.40] # вероятности или скор модели
auc = roc_auc_score(y_true, y_score) # измеряем, насколько хорошо модель упорядочивает положительные и отрицательные объекты
print(round(auc, 3)) # выводим итоговую ROC-AUCВ этом и состоит главный смысл метрики: она оценивает не конкретный бинарный ответ, а качество порядка. Именно поэтому ROC-AUC стоит читать как инструмент сравнения ранжирования, а не как универсальный приговор модели.