← Назад к вопросам
Что будет, если на вход функции, вычисляющей ROC-AUC, дать бинарные предсказания?
1.0 Junior🔥 91 комментариев
#Машинное обучение#Метрики и оценка моделей
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
ROC-AUC с бинарными предсказаниями: что происходит
Это частая ошибка на практике. ROC-AUC требует вероятностей, но многие ошибочно передают бинарные (0/1) предсказания. Разберёмся что произойдёт.
Напоминание: ROC-AUC требует вероятности
ROC-AUC (Receiver Operating Characteristic - Area Under Curve) строится путём:
- Варьирования порога классификации
- Вычисления TPR и FPR для каждого порога
- Построения кривой
- Вычисления площади под кривой
Ключевой момент: для варьирования порога нужны вероятности p(y=1), а не бинарные предсказания.
Что произойдёт с бинарными предсказаниями
import numpy as np
from sklearn.metrics import roc_auc_score
from sklearn.datasets import make_classification
# Создаём синтетические данные
X, y = make_classification(n_samples=1000, n_features=10, random_state=42)
# Сценарий 1: Правильные вероятности (0.0-1.0)
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X, y)
y_proba = model.predict_proba(X)[:, 1] # Вероятности
auc_correct = roc_auc_score(y, y_proba)
print(f'Корректное ROC-AUC: {auc_correct:.4f}')
# Output: 0.9432
# Сценарий 2: Бинарные предсказания (0 или 1)
y_pred_binary = model.predict(X) # [0, 1, 1, 0, ...]
auc_binary = roc_auc_score(y, y_pred_binary)
print(f'ROC-AUC с бинарными предсказаниями: {auc_binary:.4f}')
# Output: 0.8923
Математика: что происходит
ROC-AUC вычисляет площадь под кривой, но когда у нас только 0 и 1:
Когда дан вектор вероятностей [0.3, 0.7, 0.2, 0.9]:
- Меняем порог от 0.0 до 1.0
- При каждом пороге считаем TPR и FPR
- Получаем 4 точки кривой (число уникальных значений + 2)
Когда дан вектор бинарных значений [0, 1, 0, 1]:
- Уникальные значения только 0 и 1
- Поэтому только 2-3 точки на ROC кривой
- Кривая становится очень грубой и неполной
Видимые эффекты
from sklearn.metrics import roc_curve
import matplotlib.pyplot as plt
# Вероятности
y_proba = model.predict_proba(X)[:, 1]
fpr_proba, tpr_proba, thresholds_proba = roc_curve(y, y_proba)
print(f'Количество точек ROC (вероятности): {len(fpr_proba)}')
# Output: 1001 (плавная кривая)
# Бинарные предсказания
y_pred_binary = model.predict(X)
fpr_binary, tpr_binary, thresholds_binary = roc_curve(y, y_pred_binary)
print(f'Количество точек ROC (бинарные): {len(fpr_binary)}')
# Output: 3 (только 3 точки!)
print(f'Пороги для вероятностей: {len(thresholds_proba)} значений')
print(f'Пороги для бинарных: {len(thresholds_binary)} значений')
print(f'Уникальные пороги для бинарных: {thresholds_binary}')
# Output: [2. 1. 0.] (только 3 порога возможно)
Практический пример
import numpy as np
from sklearn.metrics import roc_auc_score, roc_curve, confusion_matrix
# Истинные метки
y_true = np.array([0, 0, 1, 1, 1, 0, 1, 0, 1, 1])
# Вероятности (правильно)
y_proba = np.array([0.1, 0.2, 0.8, 0.9, 0.7, 0.3, 0.6, 0.15, 0.85, 0.95])
auc_proba = roc_auc_score(y_true, y_proba)
print(f'ROC-AUC (вероятности): {auc_proba:.4f}') # 0.9333
# Бинарные (порог = 0.5)
y_pred = (y_proba >= 0.5).astype(int)
print(f'Бинарные предсказания: {y_pred}')
# [0 0 1 1 1 0 1 0 1 1]
auc_binary = roc_auc_score(y_true, y_pred)
print(f'ROC-AUC (бинарные): {auc_binary:.4f}') # 0.8667
# Видим что ROC-AUC упал!
Почему ROC-AUC упадёт
Причины потери информации:
-
Потеря уверенности модели
Вероятность 0.51 → бинарное 1 Вероятность 0.99 → бинарное 1 Но это совершенно разные сценарии! -
Меньше точек для кривой
С вероятностями: 1000+ порогов С бинарным: только 3 порога (≤0, >0, >1) -
Потеря дискриминирующей способности
# Модель уверена в классе 1: 0.95 # Модель неуверена в классе 1: 0.51 # Оба становятся 1, и разница теряется
Граничные случаи
# Случай 1: Идеальные бинарные предсказания
y_true = np.array([0, 0, 1, 1])
y_pred_perfect = np.array([0, 0, 1, 1]) # Полностью совпадают
auc = roc_auc_score(y_true, y_pred_perfect)
print(f'Идеальные бинарные: {auc}') # 1.0 (можно быть 1.0)
# Случай 2: Случайные бинарные предсказания
y_pred_random = np.array([0, 1, 0, 1])
auc = roc_auc_score(y_true, y_pred_random)
print(f'Случайные бинарные: {auc}') # 0.5 (как случайный классификатор)
# Случай 3: Полностью неправильные бинарные
y_pred_wrong = np.array([1, 1, 0, 0])
auc = roc_auc_score(y_true, y_pred_wrong)
print(f'Полностью неправильные: {auc}') # 0.0
Интерпретация ROC-AUC при бинарных входах
Использование бинарных предсказаний вместо вероятностей означает:
1. Вы теряете способность к оптимизации порога
2. ROC-AUC становится мерой точности при фиксированном пороге (0.5)
3. Вы не измеряете истинную дискриминирующую способность модели
4. ROC-AUC становится зависит только от точности классификации
Демонстрация влияния
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
X, y = make_classification(n_samples=10000, n_features=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model = LogisticRegression()
model.fit(X_train, y_train)
# Правильно
y_proba = model.predict_proba(X_test)[:, 1]
auc_correct = roc_auc_score(y_test, y_proba)
# Неправильно
y_binary = model.predict(X_test)
auc_incorrect = roc_auc_score(y_test, y_binary)
print(f'ROC-AUC с вероятностями: {auc_correct:.4f}')
print(f'ROC-AUC с бинарными: {auc_incorrect:.4f}')
print(f'Разница: {auc_correct - auc_incorrect:.4f}')
# Output:
# ROC-AUC с вероятностями: 0.8934
# ROC-AUC с бинарными: 0.8765
# Разница: 0.0169
Что делать если у вас только бинарные предсказания
Вариант 1: Получить вероятности от модели
# Правильно
y_proba = model.predict_proba(X)[:, 1] # Вероятности
auc = roc_auc_score(y_true, y_proba)
Вариант 2: Использовать другие метрики для бинарных классов
# Если у вас только бинарные предсказания
from sklearn.metrics import accuracy_score, f1_score, cohen_kappa_score
accuracy = accuracy_score(y_true, y_pred_binary)
f1 = f1_score(y_true, y_pred_binary)
kappa = cohen_kappa_score(y_true, y_pred_binary)
print(f'Accuracy: {accuracy:.4f}')
print(f'F1-score: {f1:.4f}')
print(f'Cohen Kappa: {kappa:.4f}')
Вариант 3: Переучить модель чтобы получить вероятности
model = LogisticRegression() # Или любой другой classifier
model.fit(X_train, y_train)
y_proba = model.predict_proba(X_test)[:, 1] # Вероятности
auc = roc_auc_score(y_test, y_proba)
Заключение
Что произойдёт:
- ROC-AUC даст результат, но это будет неправильная метрика
- Она будет ниже чем с вероятностями
- Она будет отражать скорее точность классификации при фиксированном пороге
- Информация о уверенности модели теряется
Правило:
- Всегда используйте вероятности (0.0-1.0) для ROC-AUC
- Бинарные предсказания приводят к потере информации
- Если у вас есть только бинарные предсказания, используйте другие метрики (Accuracy, F1, Precision, Recall)