Hyperparameter Optimalisatie
Hyperparameters zijn de instellingen die je kiest voordat je een model traint. In tegenstelling tot gewone parameters (die het model zelf leert), moet je hyperparameters handmatig of via zoekstrategieën bepalen.
Hyperparameters vs. Parameters
| Type |
Beschrijving |
Voorbeeld |
| Parameters |
Geleerd door het model tijdens training |
Gewichten in een neuraal netwerk |
| Hyperparameters |
Ingesteld door de ontwikkelaar vóór training |
Learning rate, aantal bomen, max depth |
Voorbeelden per model
| Model |
Hyperparameters |
| Random Forest |
n_estimators, max_depth, min_samples_split |
| Neural Network |
learning_rate, batch_size, epochs, hidden_layers |
| SVM |
C, kernel, gamma |
| KNN |
n_neighbors, weights, metric |
| XGBoost |
learning_rate, max_depth, n_estimators, subsample |
K-Fold Cross-Validatie
K-fold cross-validatie is een techniek om de performance van een model betrouwbaarder te schatten dan met een enkele train/test split.
Hoe werkt het?
- Verdeel de data in K gelijke delen (folds)
- Train K keer:
- Gebruik K-1 folds voor training
- Gebruik 1 fold voor validatie
- Elke fold is precies één keer de validatieset
- Bereken het gemiddelde van alle K scores
Visueel (5-fold)
| Fold 1: [VAL] [train] [train] [train] [train]
Fold 2: [train] [VAL] [train] [train] [train]
Fold 3: [train] [train] [VAL] [train] [train]
Fold 4: [train] [train] [train] [VAL] [train]
Fold 5: [train] [train] [train] [train] [VAL]
|
Implementatie
| from sklearn.model_selection import cross_val_score, KFold
# Standaard cross-validatie
scores = cross_val_score(model, X, y, cv=5)
print(f"Scores per fold: {scores}")
print(f"Gemiddelde: {scores.mean():.3f} (+/- {scores.std():.3f})")
# Meer controle met KFold
kfold = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=kfold)
|
Varianten
| Variant |
Beschrijving |
Wanneer gebruiken |
| K-Fold |
Standaard verdeling in K delen |
Algemeen gebruik |
| Stratified K-Fold |
Behoudt klasseverdeling per fold |
Classificatie met ongebalanceerde klassen |
| Leave-One-Out (LOO) |
K = aantal datapunten |
Zeer kleine datasets |
| Repeated K-Fold |
K-fold meerdere keren herhalen |
Stabielere schattingen |
| from sklearn.model_selection import StratifiedKFold, RepeatedKFold
# Stratified voor classificatie
skfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
# Repeated voor stabiliteit
rkfold = RepeatedKFold(n_splits=5, n_repeats=3, random_state=42)
|
!!! tip "Hoeveel folds?"
- 5 of 10 folds is gebruikelijk
- Meer folds = minder bias, meer variantie, langere trainingstijd
- Bij kleine datasets: meer folds of LOO
Grid Search
Grid search is een systematische manier om de beste combinatie van hyperparameters te vinden door alle mogelijke combinaties te proberen.
Hoe werkt het?
- Definieer een grid van hyperparameterwaarden
- Probeer elke combinatie
- Evalueer met cross-validatie
- Selecteer de beste combinatie
Implementatie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 | from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
# Definieer het grid
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [5, 10, 20, None],
'min_samples_split': [2, 5, 10]
}
# Grid search met cross-validatie
grid_search = GridSearchCV(
estimator=RandomForestClassifier(random_state=42),
param_grid=param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1, # Gebruik alle CPU cores
verbose=1
)
grid_search.fit(X_train, y_train)
# Beste resultaten
print(f"Beste parameters: {grid_search.best_params_}")
print(f"Beste score: {grid_search.best_score_:.3f}")
# Beste model direct gebruiken
best_model = grid_search.best_estimator_
|
Aantal combinaties
Bij grid search groeit het aantal combinaties snel:
| 3 waarden voor n_estimators × 4 waarden voor max_depth × 3 waarden voor min_samples_split
= 3 × 4 × 3 = 36 combinaties
Met 5-fold cross-validatie = 36 × 5 = 180 model trainingen
|
Alternatieven voor grid search
| Methode |
Beschrijving |
Wanneer gebruiken |
| Grid Search |
Alle combinaties proberen |
Klein zoekgebied, voldoende tijd |
| Random Search |
Willekeurige combinaties |
Groot zoekgebied, beperkte tijd |
| Bayesian Optimization |
Slim zoeken op basis van eerdere resultaten |
Dure evaluaties (deep learning) |
| Halving Grid Search |
Snel slechte opties elimineren |
Veel combinaties, beperkte resources |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
# Random search met verdelingen
param_distributions = {
'n_estimators': randint(50, 500),
'max_depth': randint(3, 30),
'min_samples_split': randint(2, 20)
}
random_search = RandomizedSearchCV(
estimator=RandomForestClassifier(random_state=42),
param_distributions=param_distributions,
n_iter=50, # 50 willekeurige combinaties
cv=5,
random_state=42,
n_jobs=-1
)
|
!!! warning "Overfitting op validatieset"
Als je te veel hyperparametercombinaties probeert, kun je "overfitten" op je validatieset. Houd altijd een aparte testset achter de hand voor finale evaluatie.
Ensemble Methoden
Ensemble methoden combineren meerdere modellen om betere voorspellingen te maken. De twee hoofdstrategieën zijn bagging en boosting.
Bagging
Bagging (Bootstrap Aggregating) traint meerdere modellen parallel op verschillende subsets van de data en combineert hun voorspellingen.
Hoe werkt het?
- Maak N bootstrap samples (random sampling met teruglegging)
- Train een model op elke sample
- Combineer voorspellingen:
- Classificatie: meerderheid stemming
- Regressie: gemiddelde
Visueel
| Originele data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Bootstrap sample 1: [2, 3, 3, 5, 7, 7, 8, 9, 9, 10] → Model 1 → Voorspelling A
Bootstrap sample 2: [1, 1, 2, 4, 5, 6, 8, 8, 9, 10] → Model 2 → Voorspelling B
Bootstrap sample 3: [1, 3, 4, 4, 5, 6, 7, 9, 10, 10] → Model 3 → Voorspelling C
Finale voorspelling = Combinatie van A, B, C
|
Kenmerken
| Aspect |
Beschrijving |
| Doel |
Variantie verminderen |
| Base model |
Vaak decision trees |
| Training |
Parallel (onafhankelijk) |
| Voorspelling |
Gemiddelde of stemming |
| Bekendste voorbeeld |
Random Forest |
Random Forest als bagging
Random Forest is bagging met decision trees, plus een extra twist: bij elke split worden slechts een subset van features overwogen.
1
2
3
4
5
6
7
8
9
10
11
12
13 | from sklearn.ensemble import RandomForestClassifier, BaggingClassifier
# Random Forest (bagging + feature randomization)
rf = RandomForestClassifier(n_estimators=100, random_state=42)
# Generieke bagging (met elk base model)
bagging = BaggingClassifier(
estimator=DecisionTreeClassifier(),
n_estimators=100,
max_samples=0.8, # 80% van data per sample
max_features=0.8, # 80% van features per sample
random_state=42
)
|
Boosting
Boosting traint modellen sequentieel, waarbij elk volgend model focust op de fouten van de vorige.
Hoe werkt het?
- Train een eerste (zwak) model
- Identificeer de fouten
- Train een volgend model met meer gewicht op de fouten
- Herhaal tot N modellen
- Combineer alle modellen (gewogen som)
Visueel
| Model 1: Maakt fouten op datapunten [3, 7, 9]
↓
Model 2: Focust extra op [3, 7, 9], maakt nu fouten op [2, 7]
↓
Model 3: Focust extra op [2, 7], maakt fouten op [7]
↓
...
Finale model = Gewogen combinatie van alle modellen
|
Kenmerken
| Aspect |
Beschrijving |
| Doel |
Bias verminderen |
| Base model |
Zwakke learners (vaak shallow trees) |
| Training |
Sequentieel (afhankelijk) |
| Voorspelling |
Gewogen som |
| Bekendste voorbeelden |
AdaBoost, Gradient Boosting, XGBoost, LightGBM |
Boosting algoritmen
| Algoritme |
Beschrijving |
Kenmerken |
| AdaBoost |
Past gewichten aan op basis van fouten |
Eenvoudig, gevoelig voor outliers |
| Gradient Boosting |
Minimaliseert loss via gradient descent |
Flexibel, trager |
| XGBoost |
Geoptimaliseerde gradient boosting |
Snel, regularisatie ingebouwd |
| LightGBM |
Leaf-wise tree growth |
Zeer snel, goed voor grote data |
| CatBoost |
Native support voor categorische features |
Minder preprocessing nodig |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | from sklearn.ensemble import GradientBoostingClassifier, AdaBoostClassifier
from xgboost import XGBClassifier
# Gradient Boosting
gb = GradientBoostingClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
random_state=42
)
# XGBoost
xgb = XGBClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
random_state=42
)
# AdaBoost
ada = AdaBoostClassifier(
n_estimators=100,
learning_rate=0.1,
random_state=42
)
|
Bagging vs. Boosting
| Aspect |
Bagging |
Boosting |
| Training |
Parallel |
Sequentieel |
| Focus |
Variantie verminderen |
Bias verminderen |
| Base models |
Onafhankelijk |
Bouwen op elkaar voort |
| Gevoeligheid outliers |
Robuust |
Gevoeliger |
| Overfitting risico |
Laag |
Hoger (maar regularisatie mogelijk) |
| Snelheid |
Sneller (paralleliseerbaar) |
Trager |
| Voorbeeld |
Random Forest |
XGBoost, LightGBM |
Wanneer wat gebruiken?
| Situatie |
Aanpak |
| Hoge variantie (overfitting) |
Bagging / Random Forest |
| Hoge bias (underfitting) |
Boosting |
| Veel outliers / ruis |
Bagging |
| Maximale performance gewenst |
Boosting (XGBoost/LightGBM) |
| Snelle training nodig |
Bagging |
| Competities / benchmarks |
Boosting wint vaak |
!!! tip "Ensemble combineren"
Je kunt bagging en boosting ook combineren, of ensembles van verschillende modeltypes maken (stacking). Dit is vaak de winnende strategie in Kaggle-competities.