04 · Ocena · 4 min czytania · Interaktywne · aktualizacja
Na czym polega walidacja krzyżowa (cross-validation) i po co się ją stosuje?
W skrócie
Walidacja krzyżowa dzieli dane na k części i każdą z nich po kolei traktuje jako zbiór walidacyjny. Daje stabilniejszą ocenę modelu niż jeden podział.
Co to jest
Walidacja krzyżowa (cross-validation, CV) to metoda szacowania, jak dobrze model będzie działał na nowych danych, w której dane dzieli się na k równych części (foldów), a następnie k razy trenuje model na k − 1 częściach i ocenia na pozostałej. Końcowy wynik to średnia z k ocen, a ich rozrzut mówi, jak bardzo wynik zależy od podziału.
Intuicja: pojedynczy podział na trening i walidację to jak ocena ucznia na podstawie jednej kartkówki — może trafić na łatwe albo trudne pytania. Walidacja krzyżowa to pięć kartkówek z różnych działów: każdy przykład raz trafia do „egzaminu”, a średnia jest znacznie mniej przypadkowa.
Najczęściej używa się k = 5 lub k = 10. Przypadek skrajny, k równe liczbie przykładów, to walidacja leave-one-out.
Mechanizm — dlaczego tak działa
Wynik na pojedynczym zbiorze walidacyjnym ma dwa źródła niepewności: losowość tego, które przykłady trafiły do walidacji, i to, że walidacja jest mała. Walidacja krzyżowa atakuje oba problemy naraz. Każdy przykład zostaje użyty do oceny dokładnie raz, więc ocena opiera się na wszystkich n przykładach, a nie na 20% z nich. Uśrednienie k wyników zmniejsza wpływ szczęśliwego lub pechowego podziału.
Jest też koszt i subtelność. Każdy z k modeli trenuje się na (k − 1)/k danych, czyli na nieco mniejszym zbiorze niż model końcowy. Dlatego CV ma lekkie obciążenie pesymistyczne — model trenowany na wszystkich danych będzie zwykle trochę lepszy. Im większe k, tym mniejsze to obciążenie, ale tym większy koszt obliczeń i tym bardziej podobne do siebie są zbiory treningowe, co może zwiększać wariancję oszacowania. Wartości 5–10 to empiryczny kompromis opisany m.in. przez Kohaviego.
Ważne zastrzeżenie: odchylenie standardowe wyników z k foldów nie jest poprawnym błędem standardowym średniej. Foldy dzielą większość danych treningowych, więc ich wyniki są skorelowane, a prosty wzór s/√k zaniża niepewność. Traktuj rozrzut foldów jako orientacyjny sygnał stabilności, nie jako przedział ufności.
Walidacja krzyżowa zakłada, że przykłady są wymienne — że każdy podział jest tak samo „uczciwy”. Gdy dane mają strukturę (kolejność w czasie, grupy pacjentów, posortowane klasy), zwykłe losowe foldy dają zawyżone lub zaniżone wyniki i trzeba użyć odpowiedniego wariantu. Wreszcie: jeśli na podstawie CV wybieramy najlepszy model spośród wielu, wynik zwycięzcy jest znowu optymistyczny — uczciwą ocenę daje wtedy zagnieżdżona walidacja krzyżowa albo osobny test.
Na przykładzie
Na zbiorze Wine (178 win, 3 odmiany) porównałem dwie procedury oceny tego samego drzewa decyzyjnego (DecisionTreeClassifier(random_state=0)). Najpierw 100 pojedynczych podziałów 80/20 z różnymi random_state od 0 do 99: trafność testowa wahała się od 75% do 100%, średnio 90,9%, z odchyleniem standardowym 4,8 punktu. Zależnie od losowania ten sam model można by więc opisać jako „przeciętny” albo „bezbłędny”.
Następnie 100 powtórzeń 5-krotnej warstwowej walidacji krzyżowej (StratifiedKFold(5, shuffle=True) z różnymi ziarnami): średnie z pięciu foldów wahały się już tylko od 86,5% do 94,4%, z odchyleniem 1,6 punktu — trzy razy mniej. Średnia oszacowania pozostała ta sama (około 90,9%), zniknęła tylko większość przypadkowości. Dla jednego przebiegu z random_state=0 wyniki foldów to 91,7%, 83,3%, 97,2%, 97,1% i 94,3% (średnio 92,7%) — widać, jak bardzo różnią się same foldy.
Dane: Wine (wina z Piemontu)
W praktyce
- Najprostsze wywołanie:
cross_val_score(model, X, y, cv=5); dla klasyfikacji scikit-learn domyślnie użyjeStratifiedKFold. cross_validate(..., scoring=['accuracy', 'f1_macro'], return_train_score=True)zwraca kilka metryk naraz i wynik treningowy do diagnozy przeuczenia.- Zawsze przekazuj cały
Pipeline(skalowanie, imputacja, model), nie wstępnie przetworzoneX— inaczej statystyki z foldów walidacyjnych przeciekną do treningu. - Gdy dane mogą być posortowane, ustaw
shuffle=Trueirandom_state; dla grup użyjGroupKFold, dla szeregów czasowychTimeSeriesSplit. - Przy bardzo małych danych rozważ
RepeatedStratifiedKFold, by uśrednić także losowość podziału na foldy. - Typowy błąd: wybór cech na całych danych, a dopiero potem CV — wynik bywa zawyżony o dziesiątki punktów.
Najczęstsze pytania
- Jakie k wybrać?
- Domyślnie 5 albo 10. Przy dużych zbiorach wystarczy 3–5, bo każdy fold i tak jest duży, a koszt trenowania rośnie liniowo z k. Przy bardzo małych zbiorach lepsza jest powtarzana 5- lub 10-krotna CV niż leave-one-out, które bywa niestabilne.
- Który z k modeli wybrać na końcu?
- Żaden. Walidacja krzyżowa ocenia procedurę uczenia, a nie konkretny egzemplarz modelu. Po wyborze ustawień trenuje się jeden model na wszystkich dostępnych danych treningowych.
- Czy walidacja krzyżowa zastępuje zbiór testowy?
- Do szacowania jakości jednego, z góry ustalonego modelu — tak. Gdy używasz CV do strojenia lub wyboru spośród wielu modeli, wynik najlepszego jest optymistyczny i potrzebny jest osobny test albo zagnieżdżona CV.
Źródła
- James G., Witten D., Hastie T., Tibshirani R. „An Introduction to Statistical Learning”, 2nd ed., Springer 2021, rozdz. 5.1 (Cross-Validation).
- Hastie T., Tibshirani R., Friedman J. „The Elements of Statistical Learning”, 2nd ed., Springer 2009, rozdz. 7.10 (Cross-Validation).
- Stone M. (1974). Cross-Validatory Choice and Assessment of Statistical Predictions. Journal of the Royal Statistical Society, Series B, 36(2).
- Kohavi R. (1995). A Study of Cross-Validation and Bootstrap for Accuracy Estimation and Model Selection. Proceedings of IJCAI 1995.
- Dokumentacja scikit-learn: Cross-validation: evaluating estimator performance — https://scikit-learn.org/stable/modules/cross_validation.html