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

Как изменится метрика ROC AUC, если к предсказанным вероятностям положительного класса применить логарифм?

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

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

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

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

Как логарифм влияет на ROC-AUC

Коротко: ROC-AUC не изменится. Это инвариант монотонного преобразования.

Почему ROC-AUC не изменяется

ROC-AUC базируется на ранжировании, а не на абсолютных значениях вероятностей. Монотонное преобразование сохраняет порядок.

Понимание ROC-AUC

ROC-AUC отвечает на вопрос: "Какова вероятность того, что случайный положительный пример получит больший скор, чем случайный отрицательный пример?"

Исходные вероятности:
Объект 1 (положительный): 0.9
Объект 2 (отрицательный): 0.4

Объект 1 > Объект 2? ДА ✓

После применения логарифма:
Объект 1: log(0.9) = -0.105
Объект 2: log(0.4) = -0.916

Объект 1 > Объект 2? ДА ✓ (тот же порядок!)

Монотонность логарифма

Логарифм — строго монотонно возрастающая функция для положительных чисел.

Это значит:

  • Если a > b, то log(a) > log(b)
  • Порядок сохраняется
import numpy as np
import matplotlib.pyplot as plt

# Демонстрация
x = np.array([0.1, 0.3, 0.5, 0.7, 0.9])
y = np.log(x)

print("Исходный порядок:", x)
print("После логарифма:", y)
print("Порядок сохранён?", np.all(np.argsort(x) == np.argsort(y)))
# Output: Порядок сохранён? True

plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.scatter(range(len(x)), x, s=100)
plt.title('Исходные вероятности')
plt.ylabel('p')
plt.grid(True)

plt.subplot(1, 2, 2)
plt.scatter(range(len(y)), y, s=100)
plt.title('После логарифма')
plt.ylabel('log(p)')
plt.grid(True)
plt.tight_layout()
plt.show()

Математическое доказательство

ROC-AUC вычисляется как:

ROC-AUC = P(score(положительный) > score(отрицательный))
        = количество пар, где положительный выше / всего пар

Пусть y_true = [1, 0], y_pred = [0.9, 0.4]

Исходные предсказания:
  score1 = 0.9 (положительный)
  score0 = 0.4 (отрицательный)
  score1 > score0? ДА → +1 пара
  ROC-AUC = 1/1 = 1.0

После log():
  log_score1 = log(0.9) = -0.105
  log_score0 = log(0.4) = -0.916
  log_score1 > log_score0? ДА → +1 пара
  ROC-AUC = 1/1 = 1.0

Практический пример на реальных данных

from sklearn.metrics import roc_auc_score, roc_curve
from sklearn.datasets import make_classification
import numpy as np

# Генерируем данные
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)

# Простая модель
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(random_state=42)
model.fit(X, y)

# Получаем вероятности
y_proba = model.predict_proba(X)[:, 1]

# ROC-AUC исходных вероятностей
roc_auc_original = roc_auc_score(y, y_proba)
print(f"ROC-AUC (исходные): {roc_auc_original:.4f}")

# Применяем логарифм
y_proba_log = np.log(y_proba)

# ROC-AUC после логарифма
roc_auc_log = roc_auc_score(y, y_proba_log)
print(f"ROC-AUC (log): {roc_auc_log:.4f}")

# Сравнение
print(f"Разница: {abs(roc_auc_original - roc_auc_log):.6f}")
# Output:
# ROC-AUC (исходные): 0.8754
# ROC-AUC (log): 0.8754
# Разница: 0.000000 ✓

# Визуализация ROC-кривых
fpr_orig, tpr_orig, _ = roc_curve(y, y_proba)
fpr_log, tpr_log, _ = roc_curve(y, y_proba_log)

plt.figure(figsize=(8, 6))
plt.plot(fpr_orig, tpr_orig, label=f'Исходные (AUC={roc_auc_original:.4f})', linewidth=2)
plt.plot(fpr_log, tpr_log, label=f'После log (AUC={roc_auc_log:.4f})', 
         linestyle='--', linewidth=2)
plt.plot([0, 1], [0, 1], 'k--', alpha=0.3)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.legend()
plt.title('ROC-кривые совпадают несмотря на преобразование')
plt.grid(True, alpha=0.3)
plt.show()

Какие метрики НЕ инвариантны к монотонным преобразованиям

Метрики, которые ИЗМЕНЯЮТСЯ

  1. Accuracy — зависит от абсолютного порога

    threshold = 0.5
    pred = (y_proba > threshold).astype(int)
    # После log: log(y_proba) может быть отрицательным!
    pred_log = (y_proba_log > 0.5).astype(int)  # Результат другой
    
  2. Precision, Recall — зависят от порога

    # При threshold=0.5 на исходных вероятностях
    # Положительный класс: > 0.5
    
    # При threshold=0.5 на логарифме
    # log(x) > 0.5 → x > e^0.5 = 1.65 → невозможно для вероятностей!
    
  3. Log Loss (Binary Crossentropy) — чувствителен к значениям

    # Log Loss = -1/n * Σ(y*log(p) + (1-y)*log(1-p))
    # Если применить log к уже логарифмическому значению:
    # log(log(p)) → совсем другая функция потерь!
    

Метрики, которые НЕ изменяются

  1. ROC-AUC — зависит только от ранжирования
  2. PR-AUC (Area Under Precision-Recall) — тоже зависит от ранжирования
  3. Spearman/Kendall корреляция — метрики ранжирования
from scipy.stats import spearmanr, kendalltau

# Спирмен остаётся неизменным
spear_orig = spearmanr(y, y_proba)[0]
spear_log = spearmanr(y, y_proba_log)[0]
print(f"Спирмен (исходные): {spear_orig:.4f}")
print(f"Спирмен (log): {spear_log:.4f}")
# Совпадают!

ВАЖНОЕ ЗАМЕЧАНИЕ

Логарифм отрицательной функции (от вероятностей в диапазоне [0, 1]):

  • log(0.1) = -2.30
  • log(0.5) = -0.69
  • log(0.9) = -0.11

Все значения отрицательные!

Потенциальные проблемы

  1. Интерпретация — отрицательные скоры сложнее интерпретировать

    # Вероятность 0.9 → интерпретируется как "очень высокая"
    # log(0.9) = -0.105 → менее очевидно что это хорошо
    
  2. Инженерные ошибки — если код ожидает неотрицательные скоры

    # Некорректно
    if y_pred > 0:  # Логирифмированные скоры часто < 0
    

Практический совет

Для классификации используй:

  • Вероятности [0, 1] → интерпретируемо, удобно
  • Log-odds = log(p/(1-p)) → если нужно для линейности
  • Log(p) → редко, только если специфический случай
# Хороший подход: сохраняй исходные вероятности
y_pred_proba = model.predict_proba(X)[:, 1]  # [0, 1]

# Если нужны log-odds для интерпретации коэффициентов
log_odds = np.log(y_pred_proba / (1 - y_pred_proba))

# ROC-AUC останется неизменным
roc_auc_score(y_test, y_pred_proba)
roc_auc_score(y_test, log_odds)  # Будет то же значение

Вывод

  • ROC-AUC инвариантен к монотонным преобразованиям (в том числе логарифму)
  • Причина: ROC-AUC основана на ранжировании, а не на абсолютных значениях
  • Но: Accuracy, Precision, Recall, Log Loss будут изменяться
  • Практика: используй исходные вероятности для удобства интерпретации
Как изменится метрика ROC AUC, если к предсказанным вероятностям положительного класса применить логарифм? | PrepBro