Ответ
Если передать бинарные предсказания (жесткие классы 0/1) вместо вероятностей или оценок, ROC-AUC вырождается и становится равной accuracy (доле правильных ответов). Это происходит потому, что ROC-кривая строится для различных пороговых значений, а при бинарных предсказаниях существует только один эффективный порог, разделяющий 0 и 1.
Техническая причина: Кривая будет состоять всего из двух точек: (0,0) и (1,1), и площадь под ней (AUC) будет равна 0.5, если модель не идеальна. Фактически, roc_auc_score(y_true, y_pred_binary) вычисляет площадь под кривой, построенной по единственной точке (FPR, TPR), что эквивалентно accuracy.
Пример и вывод:
from sklearn.metrics import roc_auc_score, accuracy_score
y_true = [0, 1, 0, 1]
y_pred_binary = [0, 1, 1, 0] # Бинарные предсказания
auc = roc_auc_score(y_true, y_pred_binary)
acc = accuracy_score(y_true, y_pred_binary)
print(f'ROC-AUC: {auc}') # 0.5
print(f'Accuracy: {acc}') # 0.5
print('ROC-AUC равна Accuracy?', auc == acc) # True
Практический совет: Для оценки бинарного классификатора используйте accuracy_score, precision_score, recall_score или f1_score. ROC-AUC теряет смысл, если модель не выдает вероятности или скоринговые оценки.
Ответ 18+ 🔞
А, слушай, вот тут интересная штука, про которую многие наступают на одни и те же грабли. Есть у людей любимая метрика — ROC-AUC, все её тыкают куда ни попадя, а потом охуевают, когда она нихуя не работает. Так вот, если ты на выходе модели даёшь не вероятности, а тупо бинарные предсказания — нолики и единички — то эта твоя ROC-AUC накрывается медным тазом и превращается в обычную accuracy. Да-да, в ту самую долю правильных ответов, которую все так ругают.
А почему так, спросишь? Всё просто, ёпта. ROC-кривая же строится для кучи разных порогов. Ты как бы двигаешь порог отсечения и смотришь, как меняются TPR и FPR. А если у тебя на выходе уже готовые классы? Какой нахуй порог? Там всего один эффективный порог существует, который уже разделил твои 0 и 1. Кривая получается из двух точек: начало координат (0,0) и конец (1,1). И площадь под такой прямой, если модель не идеальна, будет ровно 0.5. По сути, roc_auc_score в этом случае посчитает площадь под кривой, построенной по одной-единственной точке (FPR, TPR), и это значение будет в точности равно accuracy. Сам от себя охуеешь, когда это увидишь.
Вот смотри, накидал примерчик, чтобы совсем понятно было:
from sklearn.metrics import roc_auc_score, accuracy_score
y_true = [0, 1, 0, 1]
y_pred_binary = [0, 1, 1, 0] # Бинарные предсказания
auc = roc_auc_score(y_true, y_pred_binary)
acc = accuracy_score(y_true, y_pred_binary)
print(f'ROC-AUC: {auc}') # 0.5
print(f'Accuracy: {acc}') # 0.5
print('ROC-AUC равна Accuracy?', auc == acc) # True
Видишь? Обе метрики — 0.5. Пиздец, да? ROC-AUC равна Accuracy. Так что практический совет, чтобы не выглядеть как манда с ушами: если твоя модель не выдаёт вероятности или скоринговые оценки, то забудь про ROC-AUC. Она тебе нихуя не скажет. Используй тогда accuracy_score, precision_score, recall_score или f1_score. А ROC-AUC оставь для тех случаев, когда у тебя есть эти самые оценки, по которым можно пороги двигать. Иначе волнение ебать, а толку — ноль.