Kurs uczenia maszynowego od zera · Lekcja 2.4 · 11 z 33 gotowych lekcji · 12 min
Kalibracja: czy 0,8 znaczy 80%?
W skrócie
Model może dobrze sortować, a źle podawać procenty. Naiwny Bayes deklaruje 98% pewności i trafia w 88%. Temperatura naprawia procenty bez zmiany decyzji.
Rozgrzewka Dwa pytania z wcześniejszych lekcji. Minuta, a lekcji nie blokuje.
W lekcji 2.3 krzywe ROC i PR sprawdzały, jak model sortuje biopsje. Nie pytały, czy liczby modelu są prawdziwe. Model mówi „0,8”. Czy to znaczy, że wśród takich biopsji 80% jest złośliwych? To pytanie o kalibrację. Dziś sprawdzisz je na dwóch modelach i zobaczysz, że czasem da się je naprawić jedną liczbą, bez zmiany żadnej decyzji.
Wybierz odpowiedź i pewność.
Odpowiedz, żeby odblokować lab.
Eksperyment
Ten interaktywny eksperyment działa w przeglądarce z włączonym JavaScriptem. Tekst wokół opisuje, co w nim widać.
Pokaż odpowiedź
Poprawna odpowiedź: Przy około 88%, czyli o 10 punktów rzadziej, niż obiecuje
Deklaruje średnio 98,3%, a trafia w 88,3%: różnica 10,0 punktu. 149 ze 171 biopsji dostaje pewność powyżej 99%, a 5 z nich to pomyłki. Temperatura T = 4,12 obniża Brier z 0,100 do 0,071 i nie zmienia ani jednej decyzji.
Spróbuj
- Zacznij od naiwnego Bayesa bez kalibracji. Gdzie leżą kółka względem przekątnej? Ile biopsji dostaje pewność powyżej 99% i ile z nich to pomyłki?
- Włącz temperaturę. Co dzieje się z kółkami, z Brierem i z ROC AUC? Ile decyzji się zmieniło?
- Przełącz na regresję logistyczną i porównaj ją bez kalibracji i z temperaturą. Czy ten model potrzebował poprawki?
Gdy już sprawdzisz to w labie, nazwijmy, co widzisz.
Pomysł w prostych słowach
Model jest skalibrowany, gdy jego liczby można brać dosłownie: wśród biopsji, którym daje 0,8, złośliwych jest mniej więcej 80%, a wśród tych z 0,1 około 10%. Sprawdza to diagram niezawodności. Biopsje dzielimy na przedziały według deklarowanego prawdopodobieństwa i w każdym liczymy, jaka część jest naprawdę złośliwa. Model skalibrowany leży na przekątnej. Kółka pod przekątną po prawej stronie to przesadna pewność.
Kalibracja to co innego niż sortowanie. ROC AUC z lekcji 2.3 pyta tylko, czy złośliwa biopsja dostaje wyższy wynik niż łagodna. Naiwny Bayes sortuje dobrze (ROC AUC 0,966, prawie jak regresja logistyczna z 0,969), ale jego procenty są przesadzone. Wśród 55 biopsji, którym daje co najmniej 0,9, deklaruje średnio 99,6%, a złośliwych jest 89,1%.
Obie rzeczy naraz mierzy Brier score: średni kwadrat różnicy między deklarowanym prawdopodobieństwem a tym, co się stało (1 dla złośliwej, 0 dla łagodnej). Im mniej, tym lepiej. ECE mówi, jak daleko średnio kółka leżą od przekątnej.
Jak to policzono
- Biopsje: Breast Cancer Wisconsin (Diagnostic), UCI, licencja CC BY 4.0. 569 biopsji, 10 pomiarów „mean” każdej.
- Podział warstwowy: 171 biopsji walidacyjnych (30%), a z reszty 266 do nauki i 132 do dopasowania kalibracji. Ani model, ani kalibracja nie widzą biopsji walidacyjnych.
- Modele: naiwny Bayes z rozkładem normalnym (
GaussianNB) oraz standaryzacja i regresja logistyczna (C = 1). - Temperatura: jedna liczba T dobrana na 132 biopsjach kalibracyjnych tak, żeby log-loss była najmniejsza. Diagram i ECE: 10 przedziałów po 0,1.
Dlaczego to działa
Naiwny Bayes zakłada, że pomiary guza są od siebie niezależne. W tych danych nie są: promień, obwód i pole guza mówią prawie to samo. Model liczy więc ten sam dowód kilka razy i dokłada go do wyniku, aż pewność dochodzi do 99% i wyżej. Kolejność biopsji zostaje sensowna, bo większy guz nadal dostaje wyższy wynik, ale procenty rosną za szybko.
Temperatura dzieli wynik modelu przed sigmoidą przez jedną liczbę T. Dla naiwnego Bayesa T = 4,12, więc każdy wynik maleje ponad cztery razy. Dzielenie przez dodatnią liczbę nie zmienia znaku wyniku ani kolejności biopsji. Żadna decyzja przy progu 0,5 się nie zmienia, a ROC AUC zostaje 0,966. Zmieniają się tylko procenty: średnia pewność spada z 98,3% do 91,1%, Brier z 0,100 do 0,071, a ECE z 0,101 do 0,055. Pewność powyżej 99% dostają teraz 34 biopsje i żadna z nich nie jest pomyłką.
Regresja logistyczna jest skalibrowana prawie od razu: deklaruje 92,5%, a trafia w 91,2%. Jej temperatura wychodzi T = 0,93, blisko 1, a Brier zostaje 0,063. To nie przypadek: regresja logistyczna uczy się, zmniejszając log-loss, czyli karę właśnie za źle podane procenty.
To nie jest przypadek jednego podziału. W kodzie niżej ten sam eksperyment idzie na 50 innych podziałach: naiwny Bayes deklaruje średnio 98,5% i trafia w 91,2%, a temperatura obniża jego Brier za każdym razem. Regresji logistycznej temperatura prawie nic nie zmienia.
Częsty błąd
Prawda czy fałsz: „wynik 0,8 z modelu to 80% szansy”. Fałsz, dopóki tego nie sprawdzisz. Model podaje liczbę od 0 do 1, ale nic nie gwarantuje, że to prawdopodobieństwo w zwykłym sensie. W labie naiwny Bayes daje 149 ze 171 biopsji pewność powyżej 99%, a 5 z nich to pomyłki. Gdyby te procenty były prawdziwe, pomyłek byłoby wśród nich mniej niż dwie. Wynik modelu czytaj jako szansę dopiero po sprawdzeniu diagramu niezawodności na danych, których model nie widział.
Uwaga w drugą stronę: kalibracja nie poprawia sortowania. Temperatura nie zmienia ROC AUC ani trafności, a dobrze skalibrowanemu modelowi nic nie daje: Brier regresji logistycznej zostaje 0,063. Kalibracja jest potrzebna wtedy, gdy liczby z modelu idą dalej: do progu pod koszt pomyłek (lekcja 2.6), do sumowania ryzyka, do rozmowy z pacjentem.
Quiz
Trzy pytania na sprawdzenie się. Wybierz odpowiedź albo rozwiń odpowiedź pod pytaniem. Z klawiatury: strzałki wybierają, Enter albo spacja zatwierdza.
Najważniejsze wnioski
- Kalibracja to pytanie, czy procenty modelu są prawdziwe; sortowanie (ROC AUC) to inne pytanie.
- Kalibrację sprawdzasz diagramem niezawodności i Brier score na danych, których model nie widział.
- Naiwny Bayes jest przesadnie pewny, bo kilka razy liczy ten sam dowód z powiązanych pomiarów.
- Temperatura poprawia procenty jedną liczbą i nie zmienia żadnej decyzji ani ROC AUC.
Głębiej: wzór, kod, praktyka
Matematyka
Diagram niezawodności: w przedziale B deklarowanych prawdopodobieństw porównujesz średnią deklarację conf(B) z odsetkiem pozytywnych acc(B). Model skalibrowany spełnia P(y = 1 | p) = p.
Brier = (1/n) · Σ (pᵢ − yᵢ)², a ECE = Σ_B (|B| / n) · |acc(B) − conf(B)|.
Temperatura: model daje wynik z (logit), a prawdopodobieństwo to p = σ(z / T), gdzie σ(z) = 1 / (1 + e^(−z)). T dobierasz na osobnej części danych, zmniejszając log-loss. Gdy T > 1, procenty się spłaszczają. Znak z / T jest taki sam jak znak z, więc decyzja p ≥ 0,5 (czyli z ≥ 0) się nie zmienia.
Platt: p = σ(a · z + b), czyli dwie liczby zamiast jednej. Przesunięcie b może zmienić decyzje: w labie dla naiwnego Bayesa zmienia 2.
W kodzie (Python)
Ten sam eksperyment w scikit-learn na 50 losowych podziałach (266 biopsji do nauki, 132 do kalibracji, 171 do oceny): średnia pewność, trafność i Brier przed temperaturą i po niej.
import numpy as np
from scipy.optimize import minimize_scalar
from scipy.special import expit
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import brier_score_loss
X, y = load_breast_cancer(return_X_y=True)
X, y = X[:, :10], 1 - y # 10 pomiarów „mean”, jak w labie; 1 = złośliwy
def score(m, rows): # wynik modelu przed sigmoidą: log P(złośliwy) - log P(łagodny)
lp = m.predict_log_proba(X[rows])
return lp[:, 1] - lp[:, 0]
def run(model, seed): # 266 do nauki, 132 do kalibracji, 171 do oceny (walidacja)
rest, va = train_test_split(np.arange(len(y)), test_size=0.3, stratify=y, random_state=seed)
tr, ca = train_test_split(rest, test_size=1 / 3, stratify=y[rest], random_state=seed)
m = model.fit(X[tr], y[tr])
zc, zv = score(m, ca), score(m, va)
loss = lambda T: np.mean(np.logaddexp(0, -zc / T) * y[ca] + np.logaddexp(0, zc / T) * (1 - y[ca]))
T = minimize_scalar(loss, bounds=(0.05, 20), method="bounded").x # temperatura: jedna liczba dobrana na części kalibracyjnej
p0, p1 = expit(zv), expit(zv / T)
conf, acc = np.maximum(p0, 1 - p0).mean(), ((p0 >= 0.5) == y[va]).mean()
same = ((p0 >= 0.5) == (p1 >= 0.5)).all() # dzielenie przez T nigdy nie zmienia decyzji
return conf, acc, brier_score_loss(y[va], p0), brier_score_loss(y[va], p1), T, same
for name, model in (("naive Bayes", GaussianNB()), ("logistic regression", make_pipeline(StandardScaler(), LogisticRegression()))):
r = np.array([run(model, s) for s in range(50)])
print(f"{name}, 50 splits: declares {r[:, 0].mean():.1%}, accuracy {r[:, 1].mean():.1%}; Brier {r[:, 2].mean():.3f} -> {r[:, 3].mean():.3f} with T = {r[:, 4].mean():.2f}; lower in {(r[:, 3] < r[:, 2]).sum()} of 50, decisions kept in {int(r[:, 5].sum())} of 50")
Wynik
naive Bayes, 50 splits: declares 98.5%, accuracy 91.2%; Brier 0.077 -> 0.061 with T = 3.86; lower in 50 of 50, decisions kept in 50 of 50
logistic regression, 50 splits: declares 93.4%, accuracy 93.5%; Brier 0.047 -> 0.047 with T = 0.94; lower in 17 of 50, decisions kept in 50 of 50
Podziały są inne niż w labie, więc liczby też są inne: naiwny Bayes deklaruje średnio 98,5% i trafia w 91,2%. Obraz jest ten sam. Temperatura obniża jego Brier w 50 podziałach z 50 i nie zmienia żadnej decyzji, a regresji logistycznej prawie nic nie daje: Brier 0,047 przed i po.
Pobierz notebook (.ipynb). Otwórz go w Jupyterze albo wgraj do Google Colab; brakujące dane pobierze sam.
Dla praktyka
- W scikit-learn kalibrację sprawdzają
calibration_curve,CalibrationDisplayibrier_score_loss, zawsze na danych, których model nie widział. - Poprawia ją
CalibratedClassifierCV(method="sigmoid"to Platt,"isotonic"to regresja izotoniczna); temperaturę łatwo dopisać samemu. Regresja izotoniczna potrzebuje więcej danych, bo dopasowuje całą funkcję schodkową. - Kalibrację dopasowuj na osobnej części danych albo w walidacji krzyżowej, nigdy na danych, na których model się uczył: tam model wygląda lepiej, niż jest.
- Skalibrowane procenty są potrzebne, gdy liczba idzie dalej: do progu pod koszt pomyłek (lekcja 2.6), do sumowania ryzyka, do rozmowy z pacjentem. Gdy liczy się tylko kolejność, wystarczy ROC AUC.
Czy to było pomocne?
Dzięki! To pomaga nam poprawiać Atlas.
Więcej w Atlasie
Hasła encyklopedii o pojęciach z tej lekcji: