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

Что будет, если на вход функции, вычисляющей 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) строится путём:

  1. Варьирования порога классификации
  2. Вычисления TPR и FPR для каждого порога
  3. Построения кривой
  4. Вычисления площади под кривой

Ключевой момент: для варьирования порога нужны вероятности 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 упадёт

Причины потери информации:

  1. Потеря уверенности модели

    Вероятность 0.51 → бинарное 1
    Вероятность 0.99 → бинарное 1
    
    Но это совершенно разные сценарии!
    
  2. Меньше точек для кривой

    С вероятностями: 1000+ порогов
    С бинарным: только 3 порога (≤0, >0, >1)
    
  3. Потеря дискриминирующей способности

    # Модель уверена в классе 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)