Ответ
Каждая точка на ROC-кривой (Receiver Operating Characteristic) соответствует паре значений (FPR, TPR) при определенном пороге классификации.
Математически:
- TPR (True Positive Rate, чувствительность) = TP / (TP + FN)
- FPR (False Positive Rate) = FP / (FP + TN)
Как это работает на практике:
- Модель выдает вероятности принадлежности к положительному классу
- Мы перебираем пороги от 0 до 1 (или сортируем вероятности)
- Для каждого порога вычисляем TPR и FPR
- Получаем набор точек, которые образуют кривую
Пример построения в Python:
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
import numpy as np
# Пример данных
y_true = np.array([0, 0, 1, 1, 1, 0, 1, 0, 1, 1])
y_scores = np.array([0.1, 0.3, 0.35, 0.4, 0.6, 0.55, 0.8, 0.7, 0.9, 0.95])
# Вычисляем точки ROC-кривой
fpr, tpr, thresholds = roc_curve(y_true, y_scores)
roc_auc = auc(fpr, tpr)
# Выводим первые 5 точек с порогами
print("Порог | FPR | TPR")
print("-" * 25)
for i in range(min(5, len(thresholds))):
print(f"{thresholds[i]:.2f} | {fpr[i]:.3f} | {tpr[i]:.3f}")
# Визуализация
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--', label='Случайный классификатор')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC-кривая')
plt.legend()
plt.show()
Интерпретация точек:
- Левый верхний угол (0, 1) — идеальный классификатор (все положительные правильно, нет ложных срабатываний)
- Диагональ (0,0)-(1,1) — случайное угадывание
- Чем ближе кривая к верхнему левому углу, тем лучше модель отделяет классы
AUC (Area Under Curve) — интегральная метрика, показывающая вероятность того, что случайно выбранный положительный пример будет иметь более высокий скор, чем случайно выбранный отрицательный.