ML Atlas

Kurs uczenia maszynowego od zera · Lekcja 3.5 · 18 z 33 gotowych lekcji · 14 min

Strojenie hiperparametrów bez oszukiwania

W skrócie

Najlepsze z 9 ustawień drzewa ma w walidacji krzyżowej 93,7%, a na nowych biopsjach 88,3%. Wybór zwycięzcy zawyża wynik, tak samo jak wybór ziarna.

Rozgrzewka Dwa pytania z wcześniejszych lekcji. Minuta, a lekcji nie blokuje.
Z lekcji 3.4: Regularyzacja: ridge i lasso W labie lasso zostawia 3 cechy, a R² na teście spada z 0,470 do 0,386. Co to znaczy?

Pokaż odpowiedź

Poprawna odpowiedź: Że prostszy model kosztuje trochę trafności: trzeba ważyć oba cele

Mniej cech to model łatwiejszy w użyciu i wyjaśnieniu, ale tu wyjaśnia mniejszą część zmienności wyniku. Siłę kary wybiera się na walidacji, ważąc prostotę i trafność.

Z lekcji 3.3: Krzywe uczenia: więcej danych czy lepszy model? Dlaczego trafność na treningu spada, gdy danych do nauki przybywa?

Pokaż odpowiedź

Poprawna odpowiedź: Bo coraz trudniej zapamiętać wszystkie przykłady, więc model uogólnia

Przy 50 obrazach model trafia wszystkie, przy 1438 już 98,0%. Za to walidacja rośnie z 82,3% do 95,8%.

W lekcji 3.2 walidacja krzyżowa oceniała jedno ustawienie modelu. W praktyce sprawdzasz ich wiele i bierzesz najlepsze. To się nazywa strojenie. Ustawienia, które wybierasz przed treningiem (głębokość drzewa, siła kary α z lekcji 3.4), to hiperparametry: model nie uczy się ich z danych, wybierasz je ty. Dziś zobaczysz, że wynik zwycięzcy strojenia jest zbyt optymistyczny i dlaczego.

Przewidź, potem sprawdź Drzewo decyzyjne rozpoznaje złośliwe guzy na 398 biopsjach. Sprawdzasz 9 ustawień: 3 głębokości razy 3 minimalne liczby biopsji w liściu. Każde oceniasz w 5-krotnej walidacji krzyżowej. Zwycięzca ma 93,7%. Ile da na 171 nowych biopsjach, których w ogóle nie widział?
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ź: Mniej, na przykład 88,3%, bo wybraliśmy też korzystny szum

Na 171 biopsjach testowych zwycięzca ma 88,3%, czyli o 5,4 pkt proc. mniej niż w walidacji krzyżowej. Część to selekcja, część to mały test: jedna biopsja to 0,6 pkt proc. Wybór najlepszego z 20 ziaren podziału zawyża wynik o 2,7 pkt proc. Ten podział wypadł po pesymistycznej stronie: na 50 innych podziałach (kod niżej) zwycięzca traci średnio 1,4 pkt proc.

Spróbuj

  • Przy siatce przesuń budżet z 4 na 9. Jaki wynik ma zwycięzca w walidacji krzyżowej, a jaki na teście?
  • Przełącz na przeszukiwanie losowe i kliknij kilka razy „nowe losowanie”. Czy zwycięzca na teście jest kiedyś lepszy niż w walidacji?
  • W drugiej części przesuwaj suwak ziaren od 1 do 20. Jak rośnie najlepszy wynik i jak daleko odchodzi od średniej z 200 podziałów?

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

Pomysł w prostych słowach

Strojenie to porównanie wielu ustawień na danych walidacyjnych i wybór najlepszego. Przeszukiwanie siatki sprawdza wszystkie kombinacje kilku wartości. Przeszukiwanie losowe losuje kombinacje z całego zakresu. Przy tym samym budżecie siatka 3×3 sprawdza tylko 3 głębokości: 1, 6 i 12. Losowanie 9 prób widzi zwykle więcej różnych wartości każdego hiperparametru.

Każdy wynik walidacji to prawdziwa jakość ustawienia plus trochę szczęścia: które biopsje akurat trafiły do których części. Gdy wybierasz najlepszy wynik, wybierasz też to ustawienie, któremu szczęście najbardziej dopisało. Na nowych danych tego szczęścia już nie ma. To klątwa zwycięzcy. Działa tym mocniej, im więcej ustawień porównujesz i im mniejsze są dane.

To samo dzieje się, gdy szukasz najlepszego podziału danych. Ta sama regresja logistyczna w 200 losowych podziałach ma średnio 93,8% na teście. Gdy wypróbujesz ziarna 1–20 i zgłosisz najlepsze, wyjdzie 96,5%, czyli o 2,7 pkt proc. więcej. Kod jest ten sam, wybrałeś tylko szczęście.

Jak to policzono
  • Biopsje: Breast Cancer Wisconsin (Diagnostic), UCI, licencja CC BY 4.0. 569 biopsji, 10 pomiarów „mean” każdej.
  • Strojenie: podział warstwowy, 398 biopsji do strojenia i 171 testowych. Drzewo CART (Gini), 10 głębokości razy 11 minimalnych liczb biopsji w liściu, czyli 110 ustawień, każde w 5-krotnej walidacji krzyżowej na 398 biopsjach.
  • Zwycięzca: najlepsza średnia z 5 części; przy remisie prostsze drzewo. Na teście ocenia się drzewo uczone na wszystkich 398 biopsjach.
  • Ziarna: regresja logistyczna (C = 1) na standaryzowanych pomiarach, 200 losowych podziałów 70/30, w każdym 171 biopsji testowych.

Dlaczego to działa

Weźmy 9 ustawień o prawie tej samej prawdziwej jakości. Ich wyniki w walidacji różnią się głównie szumem. Najwyższy z 9 wyników to prawie zawsze ten, w którym szum był dodatni. W labie najlepsze CV ma 373 trafień na 398 biopsji, a kilka ustawień jest tylko o jedną, dwie biopsje gorszych. Tak małe różnice to w dużej części przypadek.

Selekcję widać w drugim trybie labu: przy 200 losowaniach 9 ustawień zwycięzca ma w walidacji więcej niż na teście w każdym z nich, średnio o 3,6 pkt proc. Test nie brał udziału w wyborze, więc nie ma w nim selekcji. Jest tylko zwykły szum skończonego zbioru. Wszystkie 200 losowań to jednak różne ustawienia na tym samym podziale danych, a ten wypadł po pesymistycznej stronie: nawet bez żadnego wyboru 110 ustawień ma w walidacji średnio o 0,6 pkt proc. więcej niż na teście. W kodzie niżej, na 50 różnych podziałach, zwycięzca traci średnio 1,4 pkt proc., a w 17 z 50 podziałów walidacja nie wypada wyżej niż test.

Dlatego testu nie można używać do wyboru. Gdyby wybrać ustawienie po wyniku testu, najlepsza komórka miałaby na teście 92,4%. To też byłaby liczba zawyżona, tylko trudniej to zauważyć, bo nie zostałyby już żadne dane do sprawdzenia.

Częsty błąd

Prawda czy fałsz: „wynik zwycięzcy strojenia to prognoza na nowe dane”. Fałsz. Wynik zwycięzcy w walidacji jest zawyżony, bo to maksimum z wielu zaszumionych liczb. W labie zwycięzca 9 ustawień ma 93,7% w walidacji i 88,3% na teście. W kodzie niżej, na 50 podziałach i 110 ustawieniach, zwycięzca ma w walidacji średnio 93,3%, a na odłożonym teście 91,9%.

Uczciwą prognozę dają dwie drogi. Pierwsza: odłożony test, którego nie używasz do żadnego wyboru i oglądasz raz, na końcu. Druga: zagnieżdżona walidacja krzyżowa, czyli całe strojenie powtórzone wewnątrz każdej części zewnętrznej walidacji. Na wszystkich 569 biopsjach zwycięzca ma w zwykłej walidacji 94,0%, a zagnieżdżona daje 91,9%. Ta druga liczba jest bliżej tego, co model zrobi jutro.

Quiz

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

1. Co to jest hiperparametr?
Pokaż odpowiedź

Poprawna odpowiedź: Ustawienie wybierane przed treningiem, którego model sam nie uczy się z danych

Hiperparametry, takie jak głębokość drzewa czy siła kary α, wybierasz ty, zwykle na walidacji. Wagi i progi w drzewie model uczy się sam.

2. Zwycięzca strojenia ma 93,7% w walidacji krzyżowej. Czego się spodziewać na nowych danych?
Pokaż odpowiedź

Poprawna odpowiedź: Raczej mniej, bo wybór najlepszego z wielu wyników wybiera też szczęście

To klątwa zwycięzcy. W labie zwycięzca 9 ustawień ma na teście 88,3%; w 200 losowaniach jego wynik w walidacji jest wyższy niż na teście za każdym razem.

3. Jak uczciwie ocenić model, którego hiperparametry dobrałeś walidacją krzyżową?
Pokaż odpowiedź

Poprawna odpowiedź: Sprawdzić go na odłożonym teście albo w zagnieżdżonej walidacji krzyżowej

Odłożony test i zagnieżdżona walidacja nie brały udziału w wyborze. W kodzie zwykła walidacja daje 94,0%, a zagnieżdżona 91,9%.

Najważniejsze wnioski

  • Hiperparametry wybierasz ty, przed treningiem; stroisz je na walidacji, nigdy na teście.
  • Wynik zwycięzcy strojenia jest zawyżony: wybierając najlepszy wynik, wybierasz też szczęście (klątwa zwycięzcy).
  • Wybór najlepszego ziarna podziału to też strojenie na zbiorze testowym.
  • Uczciwą prognozę daje odłożony test oglądany raz albo zagnieżdżona walidacja krzyżowa.

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

Matematyka

Niech prawdziwa jakość ustawienia k to μₖ, a wynik walidacji Ŝₖ = μₖ + εₖ, gdzie szum εₖ ma średnią 0. Dla jednego ustawienia E[Ŝₖ] = μₖ. Dla zwycięzcy k = argmaxₖ Ŝₖ średnio E[Ŝ_k] ≥ μ_k*: maksimum z kilku zaszumionych liczb jest średnio wyższe niż prawdziwa jakość wybranego. Przy m ustawieniach o tej samej jakości E[max εₖ] rośnie z m mniej więcej jak σ · √(2 · ln m).

Jedna biopsja testowa przy n = 171 to 1/171, czyli 0,6 pkt proc. Błąd standardowy trafności p na n przykładach: √(p(1 − p)/n).

Zagnieżdżona walidacja krzyżowa: zewnętrzna pętla dzieli dane na K części; dla każdej części całe strojenie (wewnętrzna walidacja krzyżowa) idzie tylko na pozostałych, a wybrany model ocenia się na odłożonej części.

W kodzie (Python)

Ten sam eksperyment w scikit-learn: klątwa zwycięzcy na 50 podziałach przy 110 ustawieniach drzewa, zwykła i zagnieżdżona walidacja krzyżowa na wszystkich biopsjach oraz najlepsze z 20 ziaren podziału.

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split, GridSearchCV, StratifiedKFold, cross_val_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

X, y = load_breast_cancer(return_X_y=True)
X = X[:, :10]  # 10 pomiarów „mean”, jak w labie
grid = {"max_depth": [1, 2, 3, 4, 5, 6, 7, 8, 10, 12], "min_samples_leaf": [1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48]}  # 110 ustawień z labu
tree = DecisionTreeClassifier(random_state=0)
r = []
for s in range(50):
    tr, te = train_test_split(np.arange(len(y)), test_size=0.3, stratify=y, random_state=s)
    search = GridSearchCV(tree, grid, cv=StratifiedKFold(5, shuffle=True, random_state=s)).fit(X[tr], y[tr])
    r.append((search.best_score_, search.score(X[te], y[te])))  # wynik zwycięzcy w CV, potem zwycięzca na odłożonym teście
r = np.array(r)
print(f"winner of 110 settings, 50 splits: CV {r[:, 0].mean():.1%}, held-out test {r[:, 1].mean():.1%}; CV higher in {(r[:, 0] > r[:, 1]).sum()} of 50")
outer = StratifiedKFold(5, shuffle=True, random_state=0)
flat = GridSearchCV(tree, grid, cv=outer).fit(X, y).best_score_  # wynik zwycięzcy na tych samych częściach, które go wybrały
nested = cross_val_score(GridSearchCV(tree, grid, cv=StratifiedKFold(5, shuffle=True, random_state=1)), X, y, cv=outer).mean()  # strojenie idzie wewnątrz każdej części zewnętrznej
print(f"all 569 biopsies: winner's CV {flat:.1%}, nested CV {nested:.1%}")
model = make_pipeline(StandardScaler(), LogisticRegression())
acc = []
for s in range(200):  # 200 losowych podziałów, 30% na test, jak w labie
    tr, te = train_test_split(np.arange(len(y)), test_size=0.3, random_state=s)
    acc.append(model.fit(X[tr], y[tr]).score(X[te], y[te]))
acc = np.array(acc)
best = acc.reshape(10, 20).max(axis=1)  # dziesięć osób, każda próbuje 20 ziaren i zgłasza najlepsze
print(f"logistic regression, 200 seeds: mean {acc.mean():.1%}; best of 20 seeds {best.mean():.1%} on average (+{(best.mean() - acc.mean()) * 100:.1f} points), higher in {(best > acc.mean()).sum()} of 10")

Wynik

winner of 110 settings, 50 splits: CV 93.3%, held-out test 91.9%; CV higher in 33 of 50
all 569 biopsies: winner's CV 94.0%, nested CV 91.9%
logistic regression, 200 seeds: mean 93.7%; best of 20 seeds 96.4% on average (+2.6 points), higher in 10 of 10

Podziały są inne niż w labie, więc liczby też są inne. Obraz jest ten sam: zwycięzca strojenia ma w walidacji średnio 93,3%, a na odłożonym teście 91,9%; walidacja jest wyższa w 33 podziałach z 50. Zagnieżdżona walidacja daje 91,9% zamiast 94,0%, a najlepsze z 20 ziaren zawyża wynik o 2,6 pkt proc., u każdej z 10 osób.

Dla praktyka
  • W scikit-learn: GridSearchCV i RandomizedSearchCV. Wynik best_score_ jest zawyżony z tego samego powodu co w labie; oceniaj zwycięzcę score na odłożonym teście.
  • Zagnieżdżona walidacja: cross_val_score(GridSearchCV(...), X, y, cv=...). Strojenie idzie wtedy wewnątrz każdej części zewnętrznej.
  • Przy wielu hiperparametrach, z których ważnych jest niewiele, przeszukiwanie losowe zwykle znajduje dobre ustawienie szybciej niż siatka (Bergstra i Bengio, 2012).
  • Ziarno losowania ustaw raz, przed eksperymentem, i zapisz. Podawaj średnią i rozrzut z kilku podziałów albo z walidacji krzyżowej, nie wynik najlepszego ziarna.

Więcej w Atlasie

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