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:
- Precision, recall i F1 – miary oceny klasyfikatora
- Krzywa Precision-Recall jak ją wykreślić i zinterpretować
- 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”
- 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
- 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
- Idealna krzywa ROC przechodzi przez punkt (0,1), co oznacza 100% TPR i 0% FPR.
- Linia przekątna (y = x) reprezentuje przypadkowy klasyfikator.
- 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
- https://classeval.wordpress.com/introduction/introduction-to-the-roc-receiver-operating-characteristics-plot/
- https://machinelearningmastery.com/roc-curves-and-precision-recall-curves-for-classification-in-python/ – [en] wpis wyjaśniający czym są krzywe ROC oraz precision/recall
- https://acutecaretesting.org/en/articles/precision-recall-curves-what-are-they-and-how-are-they-used
- https://www.datascienceblog.net/post/machine-learning/interpreting-roc-curves-auc/
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.”