Krzywa ROC jak ją wykreślić i zinterpretować

Krzywa ROC (Receiver Operating Characteristic) pozwala na graficzną wizualizację jakości klasyfikatora przy zmieniającym się poziomie odcięcia dla klas. W tym tutorialu pokażę Ci sposób jej wyznaczania oraz przedstawię intuicję jak ją wykorzystać do interpretacji twojego modelu.

Ze wpisu dowiesz się:

  • jak teoretycznie wykreślić krzywą ROC (Receiver Operating Characteristic)
  • jak ją interpretować i jak na jej podstawie ocenić, który model jest lepszy
  • kiedy stosować i czym różni się od krzywej precision-recall
  • jak praktycznie ją wykreślić w scikit-learn

Artykuł ten jest częścią serii o mierzeniu jakości klasyfikacji. Dotychczas powstały:

  1. Precision, recall i F1 – miary oceny klasyfikatora
  2. Krzywa Precision-Recall jak ją wykreślić i zinterpretować
  3. Krzywa ROC (ten wpis)

Co to jest krzywa ROC i dlaczego powstała – intuicje

Tłumacząc „Receiver Operating Characteristic” otrzymamy „charakterystyka działania odbiornika”, ale o co kaman? Skąd ta nazwa.

Aby zrozumieć ideę powstania krzywej ROC, cofnijmy się do czasów drugiej wojny światowej. Wyobraźcie sobie, że jesteście operatorem radaru w łodzi podwodnej. Cała załoga na was polega, waszym zadaniem jest poinformowanie ich na czas o zbliżającym się okręcie nieprzyjaciela (możecie sobie wybrać stronę, po której się opowiadacie: Alianci, Niemcy).

Jak wygląda wasza praca? Siedzicie przy radarze i całymi godzinami wsłuchujecie i wpatrujecie się w ekran. Często słyszycie sam szum, czasami zwierzęta, czasami inne statki (rybackie, pasażerskie itp.). Bardzo rzadko inny okręt nieprzyjaciela. Jak zmierzyć waszą skuteczność? Bo z jednej strony musicie poinformować z dużą skutecznością o wrogim statku, zanim wystrzeli torpedy. Z drugiej strony nie możecie co chwilę wszczynać fałszywych alarmów (kapitan i załoga szybko nakarmiliby wami rekiny).

Dobry operator odbiornika (radaru) musi mieć wysoką skuteczność (precyzję) oraz rzadko wszczynać fałszywe alarmy. Omówmy sobie to już bardziej szczegółowo.

Jak powstaje krzywa ROC – wytłumaczenie teoretyczne krok po kroku

Krzywa ROC prezentuje pewien profil (moc) klasyfikatora w sposób wizualny. Tworzona jest na podstawie dwóch miar True Positive Rate (TPR) oraz False Positive Rate (FPR) obliczanych na różnych poziomach odcięcia klasyfikatora i odkładanych na wykresie. Krzywą tworzy się podobnie jak w krzywą precision-recall z tym że odkładamy inne wartości.

No dobra, ale co to znaczy TPR i FPR i co to są te różne poziomy odcięcia klasyfikatora?

Zacznijmy od wyjaśnienia miar TPR i FPR (zachęcam do zapoznania się z artykułem o miarach precision i recall).

Przyjmijmy, że rozważamy klasyfikator binarny, który rozpoznaje dwie klasy „A” i „B”. Niech klasa A będzie klasą pozytywną (np. że mail to spam, lub pacjent jest chory, lub że zdjęcie przedstawia kota), klasa „B” będzie klasą negatywną (zaprzeczeniem klasy A). Gdy uruchomimy nasz wytrenowany klasyfikator i chcemy ocenić jego skuteczność na zbiorze testowym to pojawiają się 4 przypadki, które możemy wpisać do tzw. „confusion matrix”

  1. True Positive Rate (TPR), znany również jako czułość (sensitivity) lub recall: TPR = TP / (TP + FN)Gdzie:
    • TP (True Positives) – liczba poprawnie sklasyfikowanych przypadków pozytywnych
    • FN (False Negatives) – liczba przypadków pozytywnych błędnie sklasyfikowanych jako negatywne
  2. False Positive Rate (FPR): FPR = FP / (FP + TN)Gdzie:
    • FP (False Positives) – liczba przypadków negatywnych błędnie sklasyfikowanych jako pozytywne
    • TN (True Negatives) – liczba poprawnie sklasyfikowanych przypadków negatywnych

Krzywa ROC powstaje przez zmianę progu decyzyjnego klasyfikatora i obliczanie TPR i FPR dla każdego progu. Następnie punkty (FPR, TPR) są nanoszone na wykres, tworząc krzywą.

Interpretacja krzywej ROC

  1. Idealna krzywa ROC przechodzi przez punkt (0,1), co oznacza 100% TPR i 0% FPR.
  2. Linia przekątna (y = x) reprezentuje przypadkowy klasyfikator.
  3. Im bliżej lewego górnego rogu znajduje się krzywa, tym lepszy jest klasyfikator.

Często zamiast samym wykresem posuługujemy się polem pod wykresem tej krzywej (Area Under Curve ROC) jako zagregowaną miarą. AUC-ROC (Area Under the Curve ROC) to pojedyncza liczba reprezentująca wydajność klasyfikatora:

  • AUC = 1.0: idealny klasyfikator (raczej rzadki przypadek, ale im bliżej 1 tym lepiej)
  • AUC = 0.5: klasyfikator losowy
  • AUC < 0.5: klasyfikator gorszy niż losowy (często może to być spowodowane złym kodowaniem klas, gdy zamienisz klasy nagle masz dobry klasyfikator)

Jak wykreślić krzywą ROC w scikit-learn

Poniżej przykład implementacji krzywej ROC w scikit-learn:

  • standardowe importy (linie
  • zaczynamy od wygenerowania przykładowy danych (linia 9)
  • dokunujemy podziału na zbiory testowe i treningowe (linia 12)
  • trenuje model regresji logistycznej (linie 15-16)
  • robimy predykcję i obliczamy fpr i tpr (linia 19 i 22 )
  • wyznaczamy krzywą ROC i wyświetla ją na wykresie z wykorzystaniem matplotlib (linie)

Przygotowałem dla ciebie środowisko w replit https://replit.com/@ksopyla/Krzywa-ROC-scikit-learn?v=1

import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification

# Generowanie przykładowych danych
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.7, 0.3], random_state=42)

# Podział na zbiór treningowy i testowy
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Trenowanie modelu (np. regresja logistyczna)
model = LogisticRegression()
model.fit(X_train, y_train)

# Predykcja
y_pred_proba = model.predict_proba(X_test)[:, 1]

# Obliczanie FPR, TPR i progów
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)

# Obliczanie AUC
roc_auc = auc(fpr, tpr)

# Rysowanie krzywej ROC
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC) Curve')
plt.legend(loc="lower right")
plt.show()

W wyniku otrzymamy wykres podobny do poniższego

Materiały dodatkowe

Ps. Obraz wyróżniający wygenerowany przy pomocy Dalle3 prompt: „Proszę wygeneruj mi obraz wyróżniający do wpisu o tytule „Krzywa ROC: Klucz do oceny klasyfikatorów” obrazek ma łączyć kluczowe elementy wpisu: wykres krzywej ROC, nawiązanie do historycznego kontekstu oraz aspekty analizy danych i uczenia maszynowego.”

Ciekawe, wartościowe, podziel się proszę opinią!

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.