Machine Learning Academy · Les

Boomdiepte beheersen om overfitting te voorkomen

U traint bomen met verschillende waarden voor max_depth, observeert de afweging tussen overfitting en underfitting en kiest de diepte op basis van de validatiescore.

Les 3 van 413 stappen

Boomdiepte beheersen om overfitting te voorkomen is een gratis Machine Learning Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Machine Learning Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Machine Learning Academy bevat in totaal 4 lessen.

Hoe diepte tot overfitting leidt

Een onbeperkte beslisboom groeit door totdat elk trainingsvoorbeeld zijn eigen blad heeft — met een trainingsnauwkeurigheid van 100% doordat alle gegevenspunten, inclusief ruis, uit het hoofd worden geleerd. Dit is het extreme geval van overfitting: de boom leert de eigenaardigheden van de trainingsgegevens in plaats van algemene patronen. Op nieuwe gegevens presteert zo'n boom slecht, omdat zijn regels te specifiek zijn. Het beperken van de boomdiepte is het belangrijkste regularisatiemechanisme voor beslisbomen, vergelijkbaar met het kiezen van alpha in geregulariseerde lineaire modellen of van k in KNN.

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

X, y = load_breast_cancer(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=42)

# Unlimited depth: memorises training data
tree = DecisionTreeClassifier(random_state=42)  # no max_depth
tree.fit(X_tr, y_tr)
print('Unlimited depth tree:')
print('  Tree depth:', tree.get_depth())
print('  Train accuracy:', tree.score(X_tr, y_tr).round(3))  # 1.000
print('  Test  accuracy:', tree.score(X_te, y_te).round(3))  # < 1.000

De parameter max_depth

max_depth beperkt hoeveel niveaus de boom kan groeien. Met max_depth=1 neemt de boom precies één beslissing (een 'stomp'). Met max_depth=3 kan de boom maximaal drie opeenvolgende vragen stellen. Minder diepe bomen generaliseren beter, maar kunnen underfitting vertonen; diepere bomen passen beter bij de trainingsgegevens, maar lopen meer risico op overfitting. De juiste max_depth is een hyperparameter die je via kruisvalidatie vindt. Een nuttige vuistregel: begin rond max_depth=3-5 en stem van daaruit af met een validatiecurve.

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

X, y = load_breast_cancer(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=42)

for depth in [1, 2, 3, 5, 10, None]:
    tree = DecisionTreeClassifier(max_depth=depth, random_state=42)
    tree.fit(X_tr, y_tr)
    print(f'max_depth={str(depth):4}: train={tree.score(X_tr,y_tr):.3f}, '
          f'test={tree.score(X_te,y_te):.3f}')

Validatiecurve voor max_depth

Als je de trainings- en validatienauwkeurigheid uitzet tegen max_depth, zie je het klassieke patroon van bias en variantie. Bij diepte 1 zijn zowel de trainings- als de validatienauwkeurigheid laag (underfitting — hoge bias). Naarmate de diepte toeneemt, stijgt de trainingsnauwkeurigheid snel naar 100%, terwijl de validatienauwkeurigheid een piek bereikt en daarna daalt (overfitting — hoge variantie). De optimale diepte is het punt waarop de validatiecurve piekt — voordat het verschil tussen training en validatie groter wordt. Gebruik kruisvalidatie in plaats van één validatiesplitsing voor een betrouwbaardere schatting van de locatie van de piek.

from sklearn.model_selection import validation_curve
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
import numpy as np
import matplotlib.pyplot as plt

X, y = load_breast_cancer(return_X_y=True)

train_sc, val_sc = validation_curve(
    DecisionTreeClassifier(random_state=42),
    X, y, param_name='max_depth',
    param_range=range(1, 16), cv=10
)

plt.plot(range(1,16), train_sc.mean(axis=1), label='Train')
plt.plot(range(1,16), val_sc.mean(axis=1), label='Validation')
plt.xlabel('max_depth'); plt.ylabel('Accuracy')
plt.title('Bias-Variance via max_depth')
plt.legend(); plt.show()

best_depth = np.argmax(val_sc.mean(axis=1)) + 1
print('Best depth:', best_depth)

min_samples_split: minimumaantal voorbeelden om een knoop te splitsen

min_samples_split voorkomt dat een knoop wordt gesplitst als die minder dan een opgegeven aantal voorbeelden bevat. De standaardwaarde is 2 (elke knoop met 2 of meer voorbeelden kan worden gesplitst). Als je deze waarde verhoogt, moet de boom wachten op meer bewijs voordat hij een beslissing neemt. Zo voorkom je zeer specifieke splitsingen op kleine groepen die waarschijnlijk ruis bevatten. Als je min_samples_split=20 instelt, wordt geen enkele knoop met minder dan 20 voorbeelden verder gesplitst. Dit is vooral nuttig voor gegevensverzamelingen met veel voorbeelden en veel zeldzame subgroepen.

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)

for min_split in [2, 5, 10, 20, 50]:
    tree = DecisionTreeClassifier(
        min_samples_split=min_split,
        random_state=42
    )
    score = cross_val_score(tree, X, y, cv=10).mean()
    tree.fit(X, y)
    print(f'min_samples_split={min_split:3}: depth={tree.get_depth()}, CV acc={score:.3f}')

min_samples_leaf: minimumaantal voorbeelden in een blad

min_samples_leaf vereist dat elke ontstane onderliggende knoop na een splitsing minstens dit aantal voorbeelden bevat. Als een mogelijke splitsing een onderliggende knoop met te weinig voorbeelden zou maken, wordt die splitsing afgewezen. Dit is een strengere beperking dan min_samples_split, omdat hiermee een minimumaantal voorbeelden in elk blad wordt gegarandeerd. Een grotere waarde voor min_samples_leaf levert kleinere, minder diepe bomen met vloeiendere beslissingsgrenzen. Voor het schatten van kansen is deze parameter cruciaal: bladknopen met zeer weinig voorbeelden leveren onbetrouwbare kansschattingen op.

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)

for min_leaf in [1, 5, 10, 20, 50]:
    tree = DecisionTreeClassifier(
        min_samples_leaf=min_leaf,
        random_state=42
    )
    score = cross_val_score(tree, X, y, cv=10).mean()
    tree.fit(X, y)
    print(f'min_samples_leaf={min_leaf:3}: leaves={tree.get_n_leaves():4}, CV acc={score:.3f}')

max_leaf_nodes: het totale aantal bladeren beperken

In plaats van de diepte te beperken, kun je rechtstreeks het maximumaantal bladknopen beperken. Met max_leaf_nodes=10 groeit de boom totdat hij precies 10 bladeren heeft. Bij elke stap kiest hij de splitsing die de grootste afname van impuriteit oplevert (groei volgens het beste eerst, niet volgens diepte eerst). Dit levert evenwichtigere bomen op dan groei met een dieptelimiet, omdat splitsingen worden toegewezen waar ze de meeste informatie opleveren in plaats van dat overal dezelfde diepte wordt afgedwongen. Groei volgens het beste eerst kan soms betere prestaties opleveren dan groei met een dieptelimiet bij hetzelfde aantal bladeren.

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)

for n_leaves in [2, 4, 8, 16, 32, 64]:
    tree = DecisionTreeClassifier(
        max_leaf_nodes=n_leaves,
        random_state=42
    )
    score = cross_val_score(tree, X, y, cv=10).mean()
    tree.fit(X, y)
    print(f'max_leaf_nodes={n_leaves:3}: depth={tree.get_depth()}, '
          f'actual leaves={tree.get_n_leaves()}, CV acc={score:.3f}')

Kosten-complexiteitspruning met ccp_alpha

Pruning na het trainen verkleint een volledig gegroeide boom door splitsingen te verwijderen die weinig voorspellende waarde bijdragen. Scikit-learn implementeert kosten-complexiteitspruning via de parameter ccp_alpha. Een grotere ccp_alpha snoeit agressiever, wat kleinere bomen oplevert. Je kunt de optimale alpha vinden door het snoeipad te berekenen met cost_complexity_pruning_path(). Deze methode retourneert de alpha-waarden waarbij elke subboom optimaal wordt. Voer kruisvalidatie uit over deze alpha-waarden om de waarde te vinden die de validatienauwkeurigheid maximaliseert.

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.datasets import load_breast_cancer
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=42)

# Get pruning path
tree = DecisionTreeClassifier(random_state=42)
path = tree.cost_complexity_pruning_path(X_tr, y_tr)
ccp_alphas = path.ccp_alphas

# Cross-validate each alpha
best_alpha, best_score = 0, 0
for alpha in ccp_alphas[::5]:  # sample every 5th
    t = DecisionTreeClassifier(ccp_alpha=alpha, random_state=42)
    score = cross_val_score(t, X_tr, y_tr, cv=5).mean()
    if score > best_score:
        best_score, best_alpha = score, alpha

print(f'Best ccp_alpha: {best_alpha:.5f}, CV acc: {best_score:.3f}')

Overfitting en goede passing visualiseren

Als je een ondiepe en een diepe boom naast elkaar uitzet op een tweedimensionale gegevensverzameling, wordt het effect van overfitting visueel duidelijk. Een ondiepe boom (depth=2) tekent enkele rechthoekige beslissingsgebieden die de hoofdstructuur van de gegevens vastleggen. Een diepe boom (depth=20) maakt honderden kleine rechthoekige gebieden die de trainingspunten perfect volgen, inclusief ruis. Goede generalisatie ontstaat door de diepte te vinden waarbij de nauwkeurigheid op de testgegevens het hoogst is — deze ligt altijd onder de diepte van de volledig gegroeide boom, en het vinden ervan is het doel van elk experiment voor het afstemmen van de diepte.

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_moons
import numpy as np

X, y = make_moons(n_samples=300, noise=0.3, random_state=42)

for depth in [2, 5, 20]:
    tree = DecisionTreeClassifier(max_depth=depth, random_state=42)
    tree.fit(X, y)
    train_acc = tree.score(X, y)
    print(f'depth={depth:2}: train={train_acc:.3f}, '
          f'leaves={tree.get_n_leaves()}')

# depth=2:  train~0.85 (underfit), few leaves
# depth=5:  train~0.92 (good fit), balanced leaves
# depth=20: train=1.00 (overfit), many tiny leaves

GridSearchCV voor hyperparameters van de boomdiepte

Gebruik GridSearchCV om meerdere regularisatieparameters tegelijk te onderzoeken. Door combinaties van max_depth, min_samples_split en min_samples_leaf te onderzoeken, vind je in één stap de best geregulariseerde boom. Dit is systematischer dan parameters één voor één afstemmen, omdat ze elkaar kunnen beïnvloeden: een ondiepe boom heeft mogelijk een grotere min_samples_leaf nodig dan een diepe boom. Voer deze zoekopdracht altijd uit binnen een kruisvalidatielus om een onbevooroordeelde schatting te krijgen van de werkelijke prestaties van de optimale configuratie.

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)

param_grid = {
    'max_depth': [3, 5, 7, 10, None],
    'min_samples_split': [2, 10, 20],
    'min_samples_leaf': [1, 5, 10]
}

grid = GridSearchCV(
    DecisionTreeClassifier(random_state=42),
    param_grid, cv=10, scoring='accuracy', n_jobs=-1
)
grid.fit(X, y)

print('Best params:', grid.best_params_)
print('Best CV accuracy:', grid.best_score_.round(3))

Leercurves: over- en underfitting vaststellen

Leercurves zetten de modelprestaties uit tegen het aantal trainingsvoorbeelden. Bij een goed afgestemde boom convergeren de trainings- en validatienauwkeurigheid naar een hoge waarde naarmate de omvang van de trainingsgegevens toeneemt. Bij een overfitte diepe boom blijft de trainingsnauwkeurigheid hoog, maar blijft de validatienauwkeurigheid laag, zelfs bij veel voorbeelden. Bij een underfitte ondiepe boom vlakken beide curves af op een matige nauwkeurigheid, ongeacht de hoeveelheid gegevens. Als meer gegevens de validatienauwkeurigheid verbeteren, vertoont het model underfitting. Als het verschil tussen de trainings- en validatienauwkeurigheid groot is, vertoont het model overfitting en heeft het meer regularisatie nodig.

from sklearn.model_selection import learning_curve
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
import numpy as np

X, y = load_breast_cancer(return_X_y=True)

for depth in [3, None]:
    tree = DecisionTreeClassifier(max_depth=depth, random_state=42)
    sizes, tr_sc, val_sc = learning_curve(
        tree, X, y, cv=5,
        train_sizes=np.linspace(0.1, 1.0, 10)
    )
    print(f'max_depth={depth}: final train={tr_sc[:,-1].mean():.3f}, '
          f'final val={val_sc[:,-1].mean():.3f}')

Aanbevolen werkwijzen voor het beperken van de boomdiepte

Een samenvatting van aanbevolen werkwijzen voor het beperken van de diepte: (1) Begin altijd met een ondiepe boom (diepte 3-5) en voeg alleen diepte toe als kruisvalidatie verbetering laat zien. (2) Gebruik min_samples_leaf naast max_depth — ze beperken overfitting op verschillende detailniveaus. (3) Gebruik bij onevenwichtige gegevensverzamelingen gestratificeerde kruisvalidatie bij het afstemmen. (4) Als de gegevensverzameling veel kenmerken heeft, kun je ook max_features overwegen om willekeur toe te voegen. (5) Houd er rekening mee dat het afstemmen van de diepte van één boom minder belangrijk is als je van plan bent een ensemble te gebruiken (Random Forest of Gradient Boosting) — het ensemble compenseert dit.

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)

# Practical starting configuration
tree = DecisionTreeClassifier(
    max_depth=5,             # Start shallow
    min_samples_split=20,    # Need 20+ samples to split
    min_samples_leaf=10,     # Each leaf must have 10+ samples
    class_weight='balanced', # Handle class imbalance
    random_state=42
)

score = cross_val_score(tree, X, y, cv=10)
print(f'CV accuracy: {score.mean():.3f} (+/- {score.std():.3f})')

Korte kennistoets

Toets je begrip van de concepten uit deze les over machinaal leren met Python.

Samenvatting van de les

In deze les heb je geleerd hoe onbeperkte bomen overfitten door ruis uit de trainingsgegevens uit het hoofd te leren, wat de belangrijkste regularisatieparameters zijn — max_depth, min_samples_split, min_samples_leaf en max_leaf_nodes — en hoe je deze selecteert via GridSearchCV. Ook heb je kosten-complexiteitspruning leren kennen als alternatief na het trainen. Hierna bekijken we hoe je beslisbomen visualiseert en interpreteert om modelbeslissingen uit te leggen.

Gratis beginnen

Leer Python met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
30
Lessen
120

Veelgestelde vragen

Is de les “Boomdiepte beheersen om overfitting te voorkomen” gratis?

Ja — de volledige tekst van “Boomdiepte beheersen om overfitting te voorkomen” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Machine Learning Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Machine Learning Academy bevat in totaal 4 lessen.

Wat leer ik in “Boomdiepte beheersen om overfitting te voorkomen”?

U traint bomen met verschillende waarden voor max_depth, observeert de afweging tussen overfitting en underfitting en kiest de diepte op basis van de validatiescore. Je oefent met Machine Learning Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Machine Learning Academy te beginnen?

Ervaring vooraf is niet nodig. Machine Learning Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Boomdiepte beheersen om overfitting te voorkomen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Machine Learning Academy?

Ja. Elke les over Machine Learning Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Een boom bouwen: splitsingen, knopen en bladeren
  2. Gini-onzuiverheid en informatiewinst
  3. Boomdiepte beheersen om overfitting te voorkomen
  4. Beslisbomen visualiseren en interpreteren
← Terug naar Machine Learning Academy