ML Atlas

Kurs uczenia maszynowego od zera · Lekcja 2.6 · 13 z 33 gotowych lekcji · 12 min

Metryka i próg pod koszt pomyłek

W skrócie

Próg wybierasz pod ceny pomyłek, nie z przyzwyczajenia. Gdy przeoczenie kosztuje 10 razy więcej niż fałszywy alarm, najtańszy próg leży blisko 0,09, nie 0,5.

Rozgrzewka Dwa pytania z wcześniejszych lekcji. Minuta, a lekcji nie blokuje.
Z lekcji 2.5: Niezrównoważone klasy Wagi klas przy 8 złośliwych w nauce podnoszą czułość z 61,5% do 80,0%. Czego nie robią?

Pokaż odpowiedź

Poprawna odpowiedź: Nie dodają nowych przykładów, więc do pełnych danych wciąż czegoś brakuje

Wagi zmieniają tylko to, ile kosztuje pomyłka na każdej klasie. Pełne dane z wagami dają czułość 86,8%, więc przy 8 złośliwych brakuje 6,8 pkt proc.

Z lekcji 2.4: Kalibracja: czy 0,8 znaczy 80%? Co znaczy, że model jest skalibrowany?

Pokaż odpowiedź

Poprawna odpowiedź: Że wśród przypadków z wynikiem 0,8 około 80% to klasa pozytywna

Kalibracja dotyczy procentów, nie sortowania. Diagram niezawodności sprawdza to przedział po przedziale: model skalibrowany leży na przekątnej.

W lekcji 2.3 krzywe pokazały menu progów, a w lekcji 2.4 sprawdziłeś, kiedy liczby modelu są prawdziwymi procentami. Teraz wybierzesz z tego menu jeden próg. Nie z przyzwyczajenia (0,5) i nie pod ulubioną metrykę, tylko pod to, ile naprawdę kosztuje każda pomyłka.

Przewidź, potem sprawdź Przeoczenie guza złośliwego kosztuje 10 razy więcej niż fałszywy alarm. Model jest dobrze skalibrowany. Gdzie leży najtańszy próg decyzji?
Jak bardzo jesteś pewny(-a)?

Eksperyment

Ten interaktywny eksperyment działa w przeglądarce z włączonym JavaScriptem. Tekst wokół opisuje, co w nim widać.

Pokaż odpowiedź

Poprawna odpowiedź: Bliżej 0,1, bo alarm opłaca się już przy niewielkim ryzyku

Teoria decyzji: alarm opłaca się, gdy p · 10 > (1 − p) · 1, czyli p > 1/11 ≈ 0,09. W labie próg 0,09 kosztuje 125, a zwykłe 0,5 aż 254. Najtańszy próg na walidacji, 0,06, kosztuje 111, ale tylko na tych samych wynikach, na których go wybrano.

Spróbuj

  • Zostaw ceny 10 i 1 i przesuwaj próg z 0,5 w dół. Gdzie koszt jest najniższy? Ile jest wtedy przeoczeń, a ile fałszywych alarmów?
  • Ustaw oba koszty na 1. Gdzie jest teraz najtańszy próg? Porównaj go z progiem najlepszym dla F1.
  • Ustaw fałszywy alarm droższy od przeoczenia. Po której stronie 0,5 ląduje najtańszy próg?
  • Wróć do cen 10 i 1 i porównaj trzy koszty: najtańszego progu, uczciwego sprawdzianu i progu z teorii. Który wybór jest najtańszy na biopsjach, których nie użyto do wyboru?

Gdy już sprawdzisz to w labie, nazwijmy, co widzisz.

Pomysł w prostych słowach

Każda pomyłka ma cenę. Przeoczony guz złośliwy (FN) to choroba wykryta za późno. Fałszywy alarm (FP) to niepotrzebna biopsja i stres. Gdy znasz ceny, koszt progu to zwykła suma: przeoczenia razy cena przeoczenia plus fałszywe alarmy razy cena alarmu. Najlepszy próg to ten z najmniejszą sumą na danych walidacyjnych.

Przy cenach 10 i 1 próg 0,5 daje 24 przeoczenia i 14 fałszywych alarmów, czyli koszt 254. Najtańszy próg na walidacji to 0,06: 2 przeoczenia i 91 alarmów, koszt 111. Ta liczba jest jednak za optymistyczna, bo próg wybrano i wyceniono na tych samych wynikach (więcej w „Dlaczego to działa”). Dla porównania biopsja dla wszystkich kosztuje 357, a brak jakiejkolwiek biopsji 2120.

Jeśli model jest skalibrowany, próg da się też policzyć bez szukania. Biopsja ma prawdopodobieństwo złośliwości p. Alarm kosztuje wtedy średnio (1 − p) · 1, a brak alarmu p · 10. Alarm opłaca się, gdy p · 10 > (1 − p) · 1, czyli gdy p > 1/11 ≈ 0,09. Ogólnie próg to c_FP / (c_FP + c_FN). To wynik teorii decyzji, a nie pomiar: zakłada, że liczby modelu są prawdziwymi procentami (lekcja 2.4). Ten model jest dobrze skalibrowany (ECE 0,010). Próg 0,09 kosztuje w labie 125, mniej niż połowa kosztu progu 0,5, i nikt go nie stroił na tych danych.

Jak to policzono
  • Biopsje: Breast Cancer Wisconsin (Diagnostic), UCI, licencja CC BY 4.0. 569 biopsji (212 złośliwych, 357 łagodnych), 10 pomiarów „mean” każdej.
  • Wyniki z walidacji krzyżowej w 5 częściach (StratifiedKFold(5) w scikit-learn): każdą biopsję ocenia model, który jej nie widział.
  • Model: standaryzacja i regresja logistyczna (C = 1). Progi od 0,01 do 0,99 co 0,01.
  • Ceny pomyłek: przeoczenie 10, fałszywy alarm 1. To przykład, a nie wycena medyczna.

Dlaczego to działa

Lab i teoria prawie się zgadzają: najtańszy próg wychodzi 0,06, teoria mówi 0,09. Różnica bierze się stąd, że 569 biopsji to niedużo, a jedno przeoczenie waży tyle co 10 alarmów, więc krzywa kosztu skacze. Jej dno jest płaskie i postrzępione: próg 0,13 kosztuje tyle samo co 0,06 (111), a 0,09 kosztuje 125. Na 20 innych podziałach na części (kod niżej) najtańszy próg wypada od 0,04 do 0,13, średnio 0,08. Teoria trafia w środek tego przedziału, a lab pokazuje, jak szerokie jest dno.

Najtańszy próg ma jednak haczyk. Lab sprawdza 99 progów i wybiera ten, który na tych 569 biopsjach wypadł najlepiej, także dzięki przypadkowym trafieniom. Koszt 111 jest więc za optymistyczny: to ta sama klątwa zwycięzcy co przy strojeniu (lekcja 3.5). Uczciwy sprawdzian: wybierz próg na 4/5 biopsji i policz jego koszt na pozostałej 1/5, pięć razy. Tak wybrany próg kosztuje 141, więcej niż próg z teorii 0,09 (125), którego nikt nie stroił. Na 20 innych podziałach uczciwy koszt wybranego progu to od 106 do 153 (średnio 129), a próg z teorii kosztuje od 105 do 136 (średnio 117) i jest tańszy w 16 z 20. Wniosek: przy skalibrowanym modelu próg z teorii to mocny i tani punkt wyjścia, a strojenie progu na tych samych danych zawyża oszczędność.

Kierunek jest zawsze ten sam: im droższe przeoczenie, tym niższy próg, a im droższy fałszywy alarm, tym wyższy. Przy równych cenach najtańszy próg to 0,65 (koszt 33). Gdy alarm jest droższy od przeoczenia, najtańszy próg ląduje powyżej 0,5.

Częsty błąd

Prawda czy fałsz: „F1 to dobra metryka do wszystkiego”. Fałsz. F1 = 2·TP / (2·TP + FN + FP), więc F1 waży przeoczenie i fałszywy alarm tak samo, nawet gdy ich ceny są różne. W labie próg najlepszy dla F1 to 0,65 (F1 0,918). Przy cenach 10 i 1 kosztuje on 276: więcej niż zwykłe 0,5 (254) i prawie 2,5 raza więcej niż najtańszy próg (111). Na 20 innych podziałach próg najlepszy dla F1 kosztuje od 1,6 do 2,9 raza więcej niż najtańszy.

Nawet przy równych cenach F1 to nie to samo co koszt. W labie przy cenach 1 i 1 najtańszy próg wypada akurat tam, gdzie najlepsze F1 (0,65), ale to nie reguła. Koszt przy równych cenach to po prostu liczba pomyłek, a F1 to ułamek, w którym trafne „nie” (TN) w ogóle się nie liczą. Na 20 innych podziałach te dwa progi różnią się w 3.

Gdy znasz ceny pomyłek, licz koszt. Gdy ich nie znasz, zapytaj o nie, zanim wybierzesz metrykę: wybór metryki to też decyzja o cenach, tylko niewypowiedziana.

Quiz

Trzy pytania na sprawdzenie się. Wybierz odpowiedź albo rozwiń odpowiedź pod pytaniem. Z klawiatury: strzałki wybierają, Enter albo spacja zatwierdza.

1. Przeoczenie kosztuje 10, fałszywy alarm 1, a model jest skalibrowany. Jaki próg wynika z teorii decyzji?
Pokaż odpowiedź

Poprawna odpowiedź: 1 / (1 + 10) ≈ 0,09, bo alarm opłaca się już przy małym ryzyku

Alarm opłaca się, gdy p · 10 > (1 − p) · 1, czyli p > 1/11. W labie próg 0,09 kosztuje 125. Najtańszy próg 0,06 kosztuje 111 tylko na wynikach, na których go wybrano.

2. Filtr spamu: dobry mail w spamie kosztuje 5 razy więcej niż spam w skrzynce. Gdzie postawić próg na P(spam)?
Pokaż odpowiedź

Poprawna odpowiedź: Wysoko, około 5 / (5 + 1) ≈ 0,83: do spamu tylko pewne przypadki

Tu droższy jest fałszywy alarm, więc próg idzie w górę: c_FP / (c_FP + c_FN) = 5/6 ≈ 0,83, jeśli model jest skalibrowany. W labie droższy alarm też przesuwa najtańszy próg powyżej 0,5.

3. Model ma najlepsze F1 przy progu 0,65. Przeoczenie kosztuje 10, alarm 1. Co z tym progiem?
Pokaż odpowiedź

Poprawna odpowiedź: Jest drogi: kosztuje 276, a najtańszy próg 0,06 tylko 111

F1 waży przeoczenie i fałszywy alarm tak samo. Gdy przeoczenie jest 10 razy droższe, próg najlepszy dla F1 kosztuje więcej nawet niż zwykłe 0,5 (254).

Najważniejsze wnioski

  • Próg wybierasz pod ceny pomyłek: koszt to przeoczenia razy ich cena plus fałszywe alarmy razy ich cena, liczony na walidacji.
  • Dla skalibrowanego modelu teoria daje próg c_FP / (c_FP + c_FN); przy cenach 10 i 1 to około 0,09. To mocny punkt wyjścia: próg strojony na tych samych danych wygląda taniej, niż jest.
  • Droższe przeoczenia obniżają próg, a droższe fałszywe alarmy go podnoszą.
  • F1 waży oba błędy tak samo i pomija trafne „nie”; gdy znasz ceny, licz koszt.

Głębiej: wzór, kod, praktyka

Matematyka

Koszt progu t: K(t) = c_FN · FN(t) + c_FP · FP(t). Najtańszy próg na walidacji to t = argmin K(t). Koszt K(t) liczony na tych samych danych jest za optymistyczny; uczciwy koszt liczysz na danych, których nie użyto do wyboru t*.

Biopsja ma prawdopodobieństwo złośliwości p. Alarm kosztuje średnio (1 − p) · c_FP, a brak alarmu p · c_FN. Alarm opłaca się, gdy p · c_FN > (1 − p) · c_FP, czyli p > c_FP / (c_FP + c_FN). Dla c_FN = 10 i c_FP = 1 to 1 / 11 ≈ 0,09.

F1 = 2·TP / (2·TP + FN + FP): FN i FP mają w mianowniku tę samą wagę 1.

W kodzie (Python)

Ten sam eksperyment w scikit-learn: wyniki z walidacji krzyżowej, koszt każdego progu od 0,01 do 0,99, uczciwy koszt wybranego progu, a potem to samo na 20 innych podziałach na części.

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import StratifiedKFold, cross_val_predict
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score

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
model = make_pipeline(StandardScaler(), LogisticRegression())
t = np.arange(1, 100) / 100  # progi 0.01 ... 0.99, jak w labie
def costs(p, i=slice(None), c_fn=10, c_fp=1):  # przeoczenie kosztuje 10, fałszywy alarm 1; i = które biopsje
    return np.array([c_fn * ((p[i] < s) & (y[i] == 1)).sum() + c_fp * ((p[i] >= s) & (y[i] == 0)).sum() for s in t])
def scores(cv):  # każdą biopsję ocenia model, który jej nie widział
    return cross_val_predict(model, X, y, cv=cv, method="predict_proba")[:, 1]
def held_out(p, cv):  # najtańszy próg wybrany na 4/5 biopsji, koszt liczony na pozostałej 1/5, pięć razy
    return sum(costs(p, b)[costs(p, a).argmin()] for a, b in cv.split(X, y))
p = scores(StratifiedKFold(5))
c, f1 = costs(p), np.array([f1_score(y, p >= s) for s in t])
print(f"cheapest threshold {t[c.argmin()]:.2f} (cost {c.min()}); theory 1/11 = {1 / 11:.2f} (cost {c[8]}); 0.5 costs {c[49]}; best F1 at {t[f1.argmax()]:.2f} costs {c[f1.argmax()]}")
print(f"picked on 4/5, priced on the other 1/5: {held_out(p, StratifiedKFold(5))}; theory 1/11: {c[8]}")
r = []
for s in range(20):  # 20 innych podziałów na 5 części
    cv = StratifiedKFold(5, shuffle=True, random_state=s)
    q = scores(cv)
    cq, fq = costs(q), np.array([f1_score(y, q >= u) for u in t])
    r.append((t[cq.argmin()], cq[fq.argmax()] / cq.min(), cq[49] / cq.min(), held_out(q, cv), cq[8], costs(q, c_fn=1).argmin() != fq.argmax()))
r = np.array(r)
print(f"20 other cuts: cheapest threshold {r[:, 0].min():.2f} to {r[:, 0].max():.2f} (mean {r[:, 0].mean():.2f}); best F1 costs {r[:, 1].min():.1f} to {r[:, 1].max():.1f} times the cheapest, 0.5 costs {r[:, 2].min():.1f} to {r[:, 2].max():.1f} times")
print(f"20 other cuts, held out: the picked threshold costs {r[:, 3].min():.0f} to {r[:, 3].max():.0f} (mean {r[:, 3].mean():.0f}), theory 1/11 costs {r[:, 4].min():.0f} to {r[:, 4].max():.0f} (mean {r[:, 4].mean():.0f}); theory is cheaper in {(r[:, 4] < r[:, 3]).sum():.0f} of 20; at equal prices the cheapest and the best-F1 threshold differ in {r[:, 5].sum():.0f} of 20")

Wynik

cheapest threshold 0.06 (cost 111); theory 1/11 = 0.09 (cost 125); 0.5 costs 254; best F1 at 0.65 costs 276
picked on 4/5, priced on the other 1/5: 141; theory 1/11: 125
20 other cuts: cheapest threshold 0.04 to 0.13 (mean 0.08); best F1 costs 1.6 to 2.9 times the cheapest, 0.5 costs 2.0 to 2.5 times
20 other cuts, held out: the picked threshold costs 106 to 153 (mean 129), theory 1/11 costs 105 to 136 (mean 117); theory is cheaper in 16 of 20; at equal prices the cheapest and the best-F1 threshold differ in 3 of 20

Przy podziale StratifiedKFold(5) liczby są takie same jak w labie: najtańszy próg 0,06 (koszt 111), teoria 0,09 (125), próg 0,5 kosztuje 254, a próg najlepszy dla F1 276. Na 20 innych podziałach najtańszy próg wypada od 0,04 do 0,13, średnio 0,08, a zwykłe 0,5 kosztuje od 2,0 do 2,5 raza więcej niż najtańszy. Próg wybrany na 4/5 biopsji i wyceniony na pozostałej 1/5 kosztuje 141, tak jak w labie. Na 20 innych podziałach taki wybór kosztuje od 106 do 153 (średnio 129), próg z teorii od 105 do 136 (średnio 117) i jest tańszy w 16 z 20. Przy równych cenach najtańszy próg i próg najlepszy dla F1 różnią się w 3 z 20 podziałów.

Dla praktyka
  • Ceny pomyłek ustal z ludźmi, którzy ponoszą ich skutki (lekarz, dział ryzyka), zanim zobaczysz wyniki modelu. Inaczej łatwo dobrać ceny pod próg, który już ci się podoba.
  • W scikit-learn próg pod koszt dobiera TunedThresholdClassifierCV z własnym scoring (np. przez make_scorer). Sam próg stosujesz tak: predict_proba(X)[:, 1] >= t.
  • Próg dobieraj na walidacji, a jego koszt sprawdzaj na danych, których nie użyłeś do wyboru (test albo odłożona część, jak w labie). Koszt podawaj obok dwóch prostych punktów odniesienia: „wszyscy na biopsję” i „nikt”.
  • Wzór c_FP / (c_FP + c_FN) stosuj tylko do skalibrowanego modelu (lekcja 2.4). Gdy model jest przesadnie pewny, szukaj progu na krzywej kosztu.

Więcej w Atlasie

Hasła encyklopedii o pojęciach z tej lekcji: