Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Train-Test Split en Crossvalidatie | Sectie
Practice
Projects
Quizzes & Challenges
Quizzen
Challenges
/
Essentiële Supervised Learning

bookTrain-Test Split en Crossvalidatie

In de vorige hoofdstukken hebben we de modellen gebouwd en nieuwe waarden voorspeld. Maar we weten niet hoe goed het model presteert en of deze voorspellingen betrouwbaar zijn.

Train-test split

Om de prestaties van het model te meten, hebben we een subset van gelabelde data nodig die het model nog niet heeft gezien. Daarom splitsen we alle gelabelde data willekeurig in een trainingsset en een testset.

Dit is mogelijk met de functie train_test_split() van sklearn.

Argumenten:

  • X — een array met kenmerkwaarden;
  • y — een array met doelwaarden;
  • test_size — het aandeel van de testset;

Retourneert:

  • X_train, X_test, y_train, y_test — arrays van hetzelfde datatype als X, y.

Gewoonlijk wordt het model gesplitst in ongeveer 70-90% voor de trainingsset en 10-30% voor de testset.

Note
Opmerking

Wanneer je dataset miljoenen instanties bevat, is het gebruik van slechts enkele duizenden voor testen meestal ruim voldoende. In dergelijke gevallen kun je zelfs minder dan 10% van de data reserveren voor testen.

Nu kunnen we het model trainen met de trainingsset en de nauwkeurigheid evalueren op de testset.

123456789101112131415161718192021
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] # Splitting the data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) knn = KNeighborsClassifier(n_neighbors=3).fit(X_train_scaled, y_train) # Printing the accuracy on the test set print(knn.score(X_test_scaled, y_test))
copy

Maar deze aanpak heeft enkele nadelen:

  • We gebruiken niet alle beschikbare data voor training, wat het model zou kunnen verbeteren;
  • Omdat we de nauwkeurigheid van het model evalueren op een klein deel van de data (testset), kan deze nauwkeurigheidsscore onbetrouwbaar zijn bij kleinere datasets. Je kunt de bovenstaande code meerdere keren uitvoeren en zien hoe de nauwkeurigheid verandert telkens wanneer er een nieuwe testset wordt gesampled.

Kruisvalidering

Kruisvalidering is ontworpen om het probleem van overfitting aan te pakken en om ervoor te zorgen dat het model goed kan generaliseren naar nieuwe, ongeziene data. Zie het als klastraining voor je model — het helpt het model op een meer gebalanceerde manier te leren voordat het de echte eindtest ondergaat.

Het idee is om de gehele dataset te schudden en te verdelen in n gelijke delen, zogenaamde folds. Vervolgens doorloopt het model n iteraties. In elke iteratie worden n-1 folds gebruikt voor training en 1 fold voor validatie. Op deze manier wordt elk deel van de data één keer gebruikt voor validatie en krijgen we een betrouwbaardere schatting van de prestaties van het model.

Houd er rekening mee dat kruisvalidering niet bedoeld is als vervanging van de testset. Nadat je kruisvalidering hebt gebruikt om je model te kiezen en te optimaliseren, moet je het evalueren op een aparte testset om een onbevooroordeelde beoordeling van de prestaties in de praktijk te krijgen.

Note
Opmerking

Een veelgebruikte keuze voor het aantal folds is 5. In dat geval wordt één fold gebruikt als de testset en de overige 4 folds voor de training.

We trainen vijf modellen met licht verschillende deelverzamelingen. Voor elk model berekenen we de testset-nauwkeurigheid:

accuracy=predicted correctlypredicted correctly+predicted incorrectly\text{accuracy} = \frac{\text{predicted correctly}}{\text{predicted correctly} + \text{predicted incorrectly}}

Wanneer dit is gedaan, kan het gemiddelde van deze 5 nauwkeurigheidsscores worden berekend, wat de cross-validatie nauwkeurigheidsscore zal zijn:

accuracyavg=accuracy1+accuracy2+...+accuracy55\text{accuracy}_{avg} = \frac{\text{accuracy}_1+\text{accuracy}_2+...+\text{accuracy}_5}{5}

Het is betrouwbaarder omdat we de nauwkeurigheidsscore hebben berekend met al onze data – alleen anders gesplitst in vijf iteraties.

Nu we weten hoe goed het model presteert, kunnen we het opnieuw trainen met de volledige dataset.

Gelukkig biedt sklearn de functie cross_val_score() voor het evalueren van het model met cross-validatie, zodat je dit niet zelf hoeft te implementeren:

Argumenten:

  • estimator — het modelobject;
  • X — een array met kenmerkwaarden;
  • y — een array met doelwaarden;
  • cv — het aantal folds (standaard 5);
  • scoring — de metriek (standaard nauwkeurigheid);

Retourneert:

  • scores — een array met scores bij elke iteratie.

Hier is een voorbeeld van het gebruik van cross-validatie met een k-NN-model getraind op de Star Wars-beoordelingsdataset:

12345678910111213141516171819
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import cross_val_score df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] scaler = StandardScaler() X = scaler.fit_transform(X) knn = KNeighborsClassifier(n_neighbors=3) # Calculating the accuracy for each split scores = cross_val_score(knn, X, y, cv=5) print('Scores: ', scores) print('Average score:', scores.mean())
copy

De standaardscore die wordt gebruikt voor classificatie is nauwkeurigheid.

question mark

Kies alle juiste uitspraken.

Select all correct answers

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 1. Hoofdstuk 19

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

bookTrain-Test Split en Crossvalidatie

Veeg om het menu te tonen

In de vorige hoofdstukken hebben we de modellen gebouwd en nieuwe waarden voorspeld. Maar we weten niet hoe goed het model presteert en of deze voorspellingen betrouwbaar zijn.

Train-test split

Om de prestaties van het model te meten, hebben we een subset van gelabelde data nodig die het model nog niet heeft gezien. Daarom splitsen we alle gelabelde data willekeurig in een trainingsset en een testset.

Dit is mogelijk met de functie train_test_split() van sklearn.

Argumenten:

  • X — een array met kenmerkwaarden;
  • y — een array met doelwaarden;
  • test_size — het aandeel van de testset;

Retourneert:

  • X_train, X_test, y_train, y_test — arrays van hetzelfde datatype als X, y.

Gewoonlijk wordt het model gesplitst in ongeveer 70-90% voor de trainingsset en 10-30% voor de testset.

Note
Opmerking

Wanneer je dataset miljoenen instanties bevat, is het gebruik van slechts enkele duizenden voor testen meestal ruim voldoende. In dergelijke gevallen kun je zelfs minder dan 10% van de data reserveren voor testen.

Nu kunnen we het model trainen met de trainingsset en de nauwkeurigheid evalueren op de testset.

123456789101112131415161718192021
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] # Splitting the data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) knn = KNeighborsClassifier(n_neighbors=3).fit(X_train_scaled, y_train) # Printing the accuracy on the test set print(knn.score(X_test_scaled, y_test))
copy

Maar deze aanpak heeft enkele nadelen:

  • We gebruiken niet alle beschikbare data voor training, wat het model zou kunnen verbeteren;
  • Omdat we de nauwkeurigheid van het model evalueren op een klein deel van de data (testset), kan deze nauwkeurigheidsscore onbetrouwbaar zijn bij kleinere datasets. Je kunt de bovenstaande code meerdere keren uitvoeren en zien hoe de nauwkeurigheid verandert telkens wanneer er een nieuwe testset wordt gesampled.

Kruisvalidering

Kruisvalidering is ontworpen om het probleem van overfitting aan te pakken en om ervoor te zorgen dat het model goed kan generaliseren naar nieuwe, ongeziene data. Zie het als klastraining voor je model — het helpt het model op een meer gebalanceerde manier te leren voordat het de echte eindtest ondergaat.

Het idee is om de gehele dataset te schudden en te verdelen in n gelijke delen, zogenaamde folds. Vervolgens doorloopt het model n iteraties. In elke iteratie worden n-1 folds gebruikt voor training en 1 fold voor validatie. Op deze manier wordt elk deel van de data één keer gebruikt voor validatie en krijgen we een betrouwbaardere schatting van de prestaties van het model.

Houd er rekening mee dat kruisvalidering niet bedoeld is als vervanging van de testset. Nadat je kruisvalidering hebt gebruikt om je model te kiezen en te optimaliseren, moet je het evalueren op een aparte testset om een onbevooroordeelde beoordeling van de prestaties in de praktijk te krijgen.

Note
Opmerking

Een veelgebruikte keuze voor het aantal folds is 5. In dat geval wordt één fold gebruikt als de testset en de overige 4 folds voor de training.

We trainen vijf modellen met licht verschillende deelverzamelingen. Voor elk model berekenen we de testset-nauwkeurigheid:

accuracy=predicted correctlypredicted correctly+predicted incorrectly\text{accuracy} = \frac{\text{predicted correctly}}{\text{predicted correctly} + \text{predicted incorrectly}}

Wanneer dit is gedaan, kan het gemiddelde van deze 5 nauwkeurigheidsscores worden berekend, wat de cross-validatie nauwkeurigheidsscore zal zijn:

accuracyavg=accuracy1+accuracy2+...+accuracy55\text{accuracy}_{avg} = \frac{\text{accuracy}_1+\text{accuracy}_2+...+\text{accuracy}_5}{5}

Het is betrouwbaarder omdat we de nauwkeurigheidsscore hebben berekend met al onze data – alleen anders gesplitst in vijf iteraties.

Nu we weten hoe goed het model presteert, kunnen we het opnieuw trainen met de volledige dataset.

Gelukkig biedt sklearn de functie cross_val_score() voor het evalueren van het model met cross-validatie, zodat je dit niet zelf hoeft te implementeren:

Argumenten:

  • estimator — het modelobject;
  • X — een array met kenmerkwaarden;
  • y — een array met doelwaarden;
  • cv — het aantal folds (standaard 5);
  • scoring — de metriek (standaard nauwkeurigheid);

Retourneert:

  • scores — een array met scores bij elke iteratie.

Hier is een voorbeeld van het gebruik van cross-validatie met een k-NN-model getraind op de Star Wars-beoordelingsdataset:

12345678910111213141516171819
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import cross_val_score df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] scaler = StandardScaler() X = scaler.fit_transform(X) knn = KNeighborsClassifier(n_neighbors=3) # Calculating the accuracy for each split scores = cross_val_score(knn, X, y, cv=5) print('Scores: ', scores) print('Average score:', scores.mean())
copy

De standaardscore die wordt gebruikt voor classificatie is nauwkeurigheid.

question mark

Kies alle juiste uitspraken.

Select all correct answers

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 1. Hoofdstuk 19
some-alt