Zkratka procross-validationcross-validation: kros validejšnTakék-fold, k-násobná křížová validace, CVPokročilý
Definice
Křížová validace je postup hodnocení modelu strojového učení, při kterém se data opakovaně rozdělí na trénovací a testovací část a model se vyhodnotí na každé části zvlášť. Výsledné metriky se zprůměrují, takže odhad výkonu méně závisí na jednom náhodném rozdělení dat a lépe odhalí přeučení.
Proč jedno rozdělení dat nestačí
Když se data rozdělí jen jednou na trénovací a testovací sadu, výsledná přesnost závisí na tom, které řádky náhodně padly do testu. U malých datasetů se rozdíl mezi dvěma různými rozděleními běžně pohybuje v jednotkách procentních bodů, což stačí na to, aby vývojář vybral horší model a myslel si, že vybral lepší. Křížová validace tenhle šum snižuje tím, že roli testovací sady postupně dostane každý řádek.
Průběh k-násobné varianty
Dataset se rozdělí na k zhruba stejně velkých dílů (foldů). Model se natrénuje k-krát: pokaždé slouží jeden fold jako testovací a zbylých k-1 jako trénovací. Vznikne k hodnot metriky, ze kterých se počítá průměr a směrodatná odchylka. Odchylka je stejně důležitá jako průměr: vysoký rozptyl mezi foldy znamená, že model je citlivý na složení dat a jeho reportovanému skóre se nedá věřit.
Obvyklá volba je k = 5 nebo k = 10. Vyšší k dává méně zkreslený odhad, protože každý model vidí víc trénovacích dat, ale stojí odpovídajícím násobkem výpočetního času. Krajní případ k = n se nazývá leave-one-out.
Stratifikace u klasifikace
U klasifikace s nevyváženými třídami se používá stratifikovaná varianta, která v každém foldu zachová stejný poměr tříd jako v celém datasetu. Bez ní se může stát, že se v testovacím foldu ocitne jen hrstka pozitivních případů a metrika se rozhoupe do nesmyslných hodnot.
Data se závislostí v čase
Časové řady se náhodně míchat nesmí. Pokud model trénuje na datech z budoucnosti a testuje se na minulosti, dojde k úniku informace a výsledek je nerealisticky dobrý. Používá se proto rozšiřující se okno: první fold trénuje na lednu a testuje na únoru, druhý trénuje na lednu až únoru a testuje na březnu a tak dále.
Co se ladí a co se měří
Křížová validace se nejčastěji používá k ladění hyperparametrů, tedy k výběru hloubky stromu, míry regularizace nebo počtu neuronů. Tady je ale past: jakmile se podle výsledků CV vybere konfigurace, přestává být tohle skóre nestranným odhadem výkonu na nových datech, protože se podle něj rozhodovalo. Poctivý postup drží stranou samostatnou testovací sadu, které se nikdo během vývoje nedotkne, případně použije vnořenou (nested) křížovou validaci: vnitřní smyčka ladí, vnější měří.
Stejný princip platí pro předzpracování. Škálování, imputace chybějících hodnot nebo výběr rysů se musí počítat uvnitř každého foldu z trénovací části, ne jednou nad celým datasetem. Jinak se do trénování protáhne informace z testu a odhad se posune nahoru. Právě proto knihovny nabízejí pipeline, která celý řetězec zabalí do jednoho objektu.
Křížová validace je nástroj pro odhad chyby a odhalení přeučení, ne pro vylepšení modelu samotného. Kvalita trénovacích dat a jejich reprezentativnost zůstávají rozhodující: opakované rozdělování špatně nasbíraného vzorku dá jen spolehlivější odhad špatného výsledku.
Příklady z praxe
Pětinásobná CV při výběru modelu
Tým srovnává logistickou regresi a gradient boosting na datasetu 4 000 objednávek pro predikci storna. Na jednom náhodném rozdělení vychází boosting o 3 body lépe, ale pětinásobná křížová validace ukáže průměr 0,81 proti 0,80 se směrodatnou odchylkou 0,04. Rozdíl je menší než rozptyl mezi foldy, takže tým zvolí jednodušší a rychlejší model.
from sklearn.model_selection import cross_val_score, StratifiedKFold cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) skore = cross_val_score(model, X, y, cv=cv, scoring="roc_auc") print(skore.mean(), skore.std())Únik informace přes škálování
Analytik nejprve normalizuje všech 10 000 řádků najednou a teprve potom pustí křížovou validaci. Průměr a rozptyl použité k normalizaci se ale spočítaly i z testovacích foldů, takže model o nich nepřímo ví. Skóre vyjde o dva body vyšší než na produkčních datech. Řešením je zabalit škálování a model do pipeline, kterou CV trénuje uvnitř každého foldu zvlášť.
from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler pipe = make_pipeline(StandardScaler(), model) skore = cross_val_score(pipe, X, y, cv=5)
Časté omyly
- MýtusKdyž použiju křížovou validaci, samostatnou testovací sadu už nepotřebuju.
- Ve skutečnostiKřížová validace slouží k porovnávání a ladění, a jakmile se podle jejího skóre rozhoduje, přestává být nestranným odhadem. Pro finální číslo je potřeba data, která do rozhodování nevstoupila, nebo vnořená křížová validace.
- MýtusVyšší k je vždycky lepší, ideálně leave-one-out.
- Ve skutečnostiVyšší k snižuje zkreslení odhadu, ale zvyšuje jeho rozptyl a výpočetní náklady rostou lineárně s k. V praxi se k = 5 nebo 10 osvědčuje jako rozumný kompromis.
- MýtusKřížová validace zabrání přeučení.
- Ve skutečnostiKřížová validace přeučení pouze změří a zviditelní. Odstranit ho musí regularizace, jednodušší model, více dat nebo lepší rysy.
Časté dotazy
- Jaké k zvolit u křížové validace?
- Pro většinu úloh se u křížové validace volí k = 5 nebo k = 10. Nižší k trénuje rychleji, ale každý model vidí méně dat a odhad bývá pesimistický. Vyšší k dává méně zkreslený odhad za cenu úměrně delšího výpočtu a vyššího rozptylu mezi jednotlivými běhy. U velmi malých datasetů, řádově desítky vzorků, se sahá po leave-one-out, kde k odpovídá počtu řádků. U velkých datasetů a drahého trénování, například u neuronových sítí, se často vystačí s jedním pevným validačním rozdělením, protože šum odhadu je díky objemu dat malý.
- Který model se po křížové validaci nasadí do produkce?
- Po křížové validaci se do produkce nenasazuje žádný z k modelů natrénovaných během validace. Křížová validace slouží k výběru algoritmu a hyperparametrů; jakmile je konfigurace vybraná, model se natrénuje znovu, tentokrát na všech dostupných trénovacích datech. Výsledný model tak vidí víc příkladů než kterýkoli model z foldů a jeho očekávaný výkon je stejný nebo lepší. Alternativou je ponechat si všech k modelů a jejich předpovědi průměrovat jako ansámbl, což bývá o něco přesnější, ale znamená k-násobné náklady na inferenci.
- Jak dělat křížovou validaci u časových řad?
- U časových řad se křížová validace nesmí dělat náhodným zamícháním, protože model by trénoval na budoucnosti a testoval na minulosti. Používá se postup s rozšiřujícím se nebo klouzavým oknem: každý fold trénuje na datech do určitého okamžiku a testuje na následujícím úseku. Mezi trénovací a testovací část se často vkládá mezera odpovídající horizontu predikce, aby se zabránilo úniku informace přes autokorelaci. Knihovna scikit-learn tenhle režim nabízí jako TimeSeriesSplit. Stejná opatrnost platí u dat seskupených podle uživatele nebo pacienta, kde musí celá skupina zůstat v jednom foldu.
- Kdy křížová validace nedává smysl?
- Křížová validace nedává smysl tam, kde je trénování příliš drahé, například u velkých jazykových modelů nebo hlubokých sítí trénovaných desítky hodin; tam stačí jedno pevné validační rozdělení. Nevhodná je také u dat se silnou strukturou, kterou náhodné rozdělení poruší: duplicitní záznamy, více řádků od stejného uživatele nebo sezónní efekty vedou k úniku informace a příliš optimistickému odhadu. A konečně nepomůže, když trénovací data nereprezentují prostředí, kde model poběží, protože opakované vzorkování zkreslený vzorek nenapraví.
Zdroje
- Cross-validation (statistics)(otevře se v novém okně)
- A Study of Cross-Validation and Bootstrap for Accuracy Estimation and Model Selection(otevře se v novém okně)
- PyTorch Documentation(otevře se v novém okně)
- arXiv: Machine Learning (stat.ML)(otevře se v novém okně)