Machine Learning Academy · Oppitunti

K-kertainen ristivalidointi: jako ilman tietovuotoa

Oppijat toteuttavat 5-kertaisen ristivalidoinnin komennolla cross_val_score, ymmärtävät, miksi testiosaa ei koskaan käytetä koulutuksen aikana, ja tulkitsevat ristivalidointipisteiden keskiarvoa ja keskihajontaa.

Oppitunti 1/413 vaihetta

K-kertainen ristivalidointi: jako ilman tietovuotoa on ilmainen Machine Learning Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Machine Learning Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Machine Learning Academy-kurssilla on yhteensä 4 oppituntia.

Miksi yksi koulutus- ja testijako on riskialtis

Kun malli arvioidaan yhdellä erillisellä testiaineistolla, tulos riippuu suuresti siitä, mitkä esimerkit sattuvat päätymään testiaineistoon. Pienessä aineistossa 80 testiesimerkkiä voivat olla poikkeuksellisen helppoja tai vaikeita, jolloin tarkkuusarvio on harhaanjohtava. K-jakoinen ristiinvalidointi ratkaisee tämän laskemalla tarkkuuden keskiarvon useista testijaoista, jolloin saadaan luotettavampi arvio mallin toiminnasta uudella datalla. Menetelmä käyttää dataa myös tehokkaammin: jokaista esimerkkiä käytetään sekä koulutukseen että testaukseen eri jaoissa.

Miten K-jakoinen ristiinvalidointi toimii vaihe vaiheelta

K-jakoinen ristiinvalidointi jakaa aineiston k yhtä suureen osaan, joita kutsutaan jaoiksi. Jokaisella k kierroksella yhtä jakoa käytetään testijakona ja loput k-1 jakoa muodostavat koulutusaineiston. Malli koulutetaan alusta alkaen koulutusjaoilla ja arvioidaan testijaolla. Tätä toistetaan, kunnes jokainen jako on toiminut testijakona täsmälleen kerran. Lopullinen suorituskykyarvio on k tuloksen keskiarvo (ja keskihajonta). Tavallisia arvoja ovat k=5 ja k=10.

cross_val_score: ristiinvalidointi yhdellä rivillä

scikit-learnin cross_val_score hoitaa koko K-jakoisen silmukan: se luo jaot, kouluttaa mallin kullakin koulutusosalla, arvioi sen testijaolla ja palauttaa tulosarvotaulukon. cv-parametri määrittää jakojen määrän. scoring-parametri määrittää metriikan. Voit myös välittää arvon n_jobs=-1, jolloin kaikki jaot koulutetaan rinnakkain ja moniytimisten koneiden kokonaisaika lyhenee huomattavasti.

from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
model = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
scores = cross_val_score(model, X, y, cv=5, scoring='accuracy', n_jobs=-1)
print('Fold scores:', np.round(scores, 4))
print('Mean:', round(scores.mean(), 4), 'Std:', round(scores.std(), 4))

Testijakoa ei koskaan käytetä koulutuksessa

K-jakoisen ristiinvalidoinnin tärkein sääntö on, että testijako ei saa koskaan vaikuttaa malliin tai mihinkään esikäsittelyvaiheeseen. Tämä tarkoittaa, että skaalaaja on sovitettava vain koulutusjakoihin ja sen jälkeen käytettävä testijakoon — sitä ei saa koskaan sovittaa yhdistettyyn aineistoon. Pipeline-rakenteen käyttäminen yhdessä cross_val_score-funktion kanssa varmistaa tämän automaattisesti: scikit-learn kutsuu kussakin jaossa putkelle fit-metodia koulutusosalla ja predict-metodia testiosalla, mikä estää tietovuodon.

# WRONG: fitting scaler on all data before CV causes leakage
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)  # leaks test fold statistics!
wrong_score = cross_val_score(LogisticRegression(max_iter=1000), X_scaled, y, cv=5).mean()

# CORRECT: Pipeline ensures scaler is fitted only on training folds
from sklearn.pipeline import make_pipeline
correct_score = cross_val_score(make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000)), X, y, cv=5).mean()
print('Wrong (leaky):', round(wrong_score, 4))
print('Correct (no leak):', round(correct_score, 4))

Satunnaissiemenen asettaminen toistettavuutta varten

Oletusarvoisesti KFold ei sekoita dataa, vaan luo samalle aineistolle aina samat jaot, joten tulokset ovat toistettavia. Jos asetat arvon shuffle=True, välitä random_state-parametrille kokonaisluku, jotta sekoitus on deterministinen: KFold(n_splits=5, shuffle=True, random_state=42). Sekoittamista suositellaan, jos aineisto on järjestetty luokan tai ajan mukaan, sillä peräkkäiset jaot muodostaisivat hyvin epäedustavia osia. Dokumentoi kokeissa aina satunnaistila toistettavuuden varmistamiseksi.

from sklearn.model_selection import KFold, cross_val_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
import numpy as np

X, y = load_iris(return_X_y=True)
kf = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(DecisionTreeClassifier(random_state=42), X, y, cv=kf)
print('Shuffled 5-fold scores:', np.round(scores, 4))
print('Mean:', round(scores.mean(), 4))

Keskiarvon ja keskihajonnan tulkitseminen

Ristiinvalidoinnin tuloksen keskiarvo arvioi mallin odotettua suorituskykyä uudella datalla. Keskihajonta kertoo, kuinka vakaa suorituskyky on. Keskiarvo 0.93 ja keskihajonta 0.01 on paljon luotettavampi kuin keskiarvo 0.93 ja keskihajonta 0.08. Suuri keskihajonta kertoo, että mallin suorituskyky riippuu herkästi siitä, mitkä esimerkit ovat koulutusaineistossa — tämä voi viitata pieneen aineistoon, mallin suureen varianssiin tai epäedustavaan datan jakoon. Kun kahta mallia verrataan, pienemmän varianssin mallia (pienempi keskihajonta) suositaan usein, vaikka sen keskiarvo olisi hieman pienempi.

K-arvon valitseminen: 5-jakoinen, 10-jakoinen vai LOOCV

k-arvon valintaan liittyy harha–varianssi-kompromissi myös itse ristiinvalidoinnin arviolle. k=5: kukin koulutusaineisto sisältää 80 % datasta, laskenta on nopeaa ja harha hieman suurempi. k=10: kukin koulutusaineisto sisältää 90 % datasta, arvio on parempi ja laskenta vaatii enemmän aikaa. Leave-One-Out CV (LOOCV): k=n, harha on lähes olematon, mutta menetelmä on suurilla aineistoilla erittäin hidas ja jakojen välinen varianssi on suuri. Tavallinen suositus on k=5 tai k=10. Hyvin pienillä aineistoilla (<100 esimerkkiä) LOOCV tuottaa dataa tehokkaimmin hyödyntävän arvion.

from sklearn.model_selection import cross_val_score, LeaveOneOut
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
import numpy as np

X, y = load_iris(return_X_y=True)
knn = KNeighborsClassifier(n_neighbors=5)
for k in [5, 10]:
    scores = cross_val_score(knn, X, y, cv=k)
    print(f'{k}-fold CV: mean={scores.mean():.4f}, std={scores.std():.4f}')
# LOOCV is slow for large datasets; feasible here
loo_scores = cross_val_score(knn, X, y, cv=LeaveOneOut())
print(f'LOOCV: mean={loo_scores.mean():.4f}, std={loo_scores.std():.4f}')

cross_validate: useita metriikoita kerralla

cross_validate on tehokkaampi muunnelma, joka voi laskea samanaikaisesti useita metriikoita sekä palauttaa koulutustulokset ja sovitus- ja arviointiajat. Tämä on hyödyllistä verrattaessa koulutus- ja testituloksia (ylisovittamisen havaitsemiseksi) tai laskettaessa useita metriikoita (tarkkuus, F1, AUC) yhdellä ristiinvalidointiajolla sen sijaan, että ristiinvalidointi suoritettaisiin erikseen kullekin metriikalle.

from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
rf = RandomForestClassifier(n_estimators=100, random_state=42)
results = cross_validate(rf, X, y, cv=5,
                          scoring=['accuracy', 'f1', 'roc_auc'],
                          return_train_score=True)
for metric in ['test_accuracy', 'test_f1', 'test_roc_auc']:
    vals = results[metric]
    print(f'{metric}: {vals.mean():.4f} (+/- {vals.std():.4f})')

Milloin K-jakoinen ristiinvalidointi voi johtaa harhaan

K-jakoinen ristiinvalidointi tuottaa harhaanjohtavia arvioita useissa tilanteissa: (1) Aikasarjadata — sekoittaminen ja jakaminen ohittavat ajallisen järjestyksen, jolloin syntyy tietovuoto, jossa tuleva data kouluttaa malleja menneisyyden ennustamiseen; (2) Ryhmädata — jos useat rivit kuuluvat samalle potilaalle tai käyttäjälle, niiden jakaminen eri osiin vuotaa ryhmätason malleja; (3) Erittäin epätasapainoiset luokat — satunnaisissa jaoissa kaikki positiiviset esimerkit voivat päätyä koulutusaineistoon. Käytä näissä tapauksissa erikoistuneita ristiinvalidointimuunnelmia: TimeSeriesSplit, GroupKFold ja StratifiedKFold.

Ristiinvalidointi on arviointia, ei koulutusta

Yleinen väärinkäsitys on, että K-jakoinen ristiinvalidointi tuottaa käyttöön otettavan mallin. Jokainen k mallin sovitus hylätään arvioinnin jälkeen. Ristiinvalidoinnin ainoa tarkoitus on arvioida, miten valituilla hyperparametreilla ja putkella koulutettu malli suoriutuu näkemättömästä datasta. Kun olet tyytyväinen ristiinvalidoinnin arvioon, kouluta lopullinen malli uudelleen koko koulutusaineistolla (kaikki jaot yhdistettyinä) käyttäen kyseisiä hyperparametreja ja ota tämä malli käyttöön. Ristiinvalidoinnin tulos on rehellinen arvio mallin odotetusta suorituskyvystä.

Ristiinvalidointitulosten raportointi: keskiarvo ja luottamusväli

Raportoi ristiinvalidoinnin tuloksista aina sekä keskiarvo että keskihajonta: 0.932 ± 0.012. Näin ilmoitetaan suorituskyvyn lisäksi myös vakaus. Julkaisua tai sidosryhmäraporttia varten voit laskea myös 95 %:n luottamusvälin: mean ± 1.96 × std / sqrt(k). Kun vertailet kahta mallia, tarkista, menevätkö niiden luottamusvälit päällekkäin — päällekkäiset välit viittaavat siihen, ettei ero ole tilastollisesti merkittävä ja että se saattaa johtua vain datan jaon satunnaisesta vaihtelusta.

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
scores = cross_val_score(RandomForestClassifier(n_estimators=100, random_state=42), X, y, cv=10)
mean, std = scores.mean(), scores.std()
ci95 = 1.96 * std / np.sqrt(len(scores))
print(f'CV Mean: {mean:.4f}')
print(f'CV Std:  {std:.4f}')
print(f'95% CI:  [{mean-ci95:.4f}, {mean+ci95:.4f}]')

Pikatarkistus

Testaa tässä oppitunnissa oppimasi K-jakoista ristiinvalidointia koskevat asiat.

Oppitunnin yhteenveto

Tässä oppitunnissa opitte: K-Fold-CV arvioi yleistymistä laskemalla keskiarvon k toisistaan riippumattoman testiföldin tuloksista, käyttäkää aina Pipelinea estääksenne esikäsittelyä vuotamasta testiföldin tilastotietoja opetusdataan ja CV on arviointityökalu — kouluttakaa malli uudelleen koko datalla hyperparametrien valinnan jälkeen. Seuraavaksi tutustumme erikoistuneille datatyypeille tarkoitettuihin ositettuun ja aikasarjojen ristiinvalidointiin.

Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”K-kertainen ristivalidointi: jako ilman tietovuotoa” ilmainen?

Kyllä – oppitunnin ”K-kertainen ristivalidointi: jako ilman tietovuotoa” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Machine Learning Academy-kurssin, päivitä CoddyKit PROhon. Machine Learning Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”K-kertainen ristivalidointi: jako ilman tietovuotoa”?

Oppijat toteuttavat 5-kertaisen ristivalidoinnin komennolla cross_val_score, ymmärtävät, miksi testiosaa ei koskaan käytetä koulutuksen aikana, ja tulkitsevat ristivalidointipisteiden keskiarvoa ja k… Harjoittelet Machine Learning Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Machine Learning Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Machine Learning Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.

Kuinka kauan ”K-kertainen ristivalidointi: jako ilman tietovuotoa”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Machine Learning Academy-oppitunnilla?

Kyllä. Jokainen Machine Learning Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. K-kertainen ristivalidointi: jako ilman tietovuotoa
  2. Ositett u ja aikasarjojen ristivalidointi
  3. Ruudukkohaku vai satunnaishaku
  4. Sisäkkäinen ristivalidointi: valinta ja arviointi samanaikaisesti
← Takaisin: Machine Learning Academy