- Je onderscheidt bootstrapping en willekeurige featurekeuze.
- Je traint een reproduceerbaar forest en begrijpt welke rijen een boom niet heeft gezien.
Je beslisboom ziet één extra zieke plant en kiest ineens een andere eerste vraag. Zo'n verandering kan alle volgende takken beïnvloeden. Wat gebeurt er als je meerdere bomen elk een iets andere versie van dezelfde training geeft?
Bagging laat modellen op verschillende steekproeven leren en combineert hun uitkomsten. Een random forest doet dit met bomen en beperkt bovendien willekeurig welke features een split mag onderzoeken. Minder gelijksoortige fouten kunnen elkaar daardoor gedeeltelijk uitmiddelen.
1. Trek rijen met teruglegging
Geef vier trainingsrijen de indices 0,1,2,3. Trek vier keer, waarbij na elke trekking alle vier indices weer beschikbaar zijn. Een mogelijke uitkomst is [1,0,2,0]: dezelfde lengte als de training, maar rij 0 telt tweemaal en rij 3 ontbreekt.
Zo'n bootstrapsteekproef bewaart dus zowel herhalingen als volgorde. Zet de uitkomst niet om in een verzameling: daarmee verdwijnen de extra stemmen van herhaalde rijen.
import random
rng = random.Random(1)
indices = []
for i in range(4):
indices.append(rng.randrange(4))
print(indices) # [1, 0, 2, 0]
Random(1) maakt een eigen generator met seed 1. randrange(4) kiest een index van 0 tot en met 3; iedere aanroep verplaatst de generator naar zijn volgende toestand. Maak de generator daarom één keer vóór de lus.
Een vaste seed laat je dezelfde proef herhalen. Hij maakt de steekproef niet eerlijker of representatiever. De visualisatie gebruikt een andere eenvoudige generator: dezelfde seed hoeft tussen die generator en Python geen gelijke reeks te geven.
Elke rij A–H heeft bij iedere trekking dezelfde kans. De tellingen laten zien welke rijen deze steekproef mist.
Getrokken volgorde:
Seed 7. Dit voorbeeld gebruikt een vaste eenvoudige generator voor herhaalbaarheid; Python gebruikt zijn eigen generator.
Maak bootstrap(n,seed) voor een positief geheel aantal rijen. Trek n indices met één lokale random.Random(seed) en randrange(n); een ongeldige n geeft ValueError. De globale randomgenerator mag door jouw functie niet veranderen.
2. Zoek de rijen die deze boom niet zag
Bij [1,0,2,0] zijn de aanwezige indices 0,1,2. Rij 3 is out of bag (OOB): buiten deze steekproef. Dat is geen fout, maar een gevolg van teruglegging.
aanwezig = set(indices)
buiten = []
for i in range(4):
if i not in aanwezig:
buiten.append(i)
print(buiten) # [3]
Hier is een set wél geschikt, omdat alleen aanwezigheid telt. De oplopende lus zorgt meteen voor gesorteerde uitvoer. Maak buiten_steekproef(n,indices) voor n ≥ 0 en geldige getrokken indices; een lege steekproef laat alle rijen buiten.
Waarom ontbreekt überhaupt een rij? Eén gekozen rij wordt bij iedere trekking met kans 3/4 gemist. Bij vier onafhankelijke trekkingen vermenigvuldig je die kansen:
Dit is de kans voor één bepaalde rij, niet het gegarandeerde aandeel ontbrekende rijen in iedere trekking. Voor OOB-evaluatie laat je een rij alleen voorspellen door bomen waarvoor hij ontbrak. Bomen die hem wel zagen zouden informatie uit hun training terugbrengen in die beoordeling.
OOB is nuttig, maar vervangt geen passende groeps- of tijdsplitsing. Bij opeenvolgende metingen van dezelfde plant kan gewone rijbootstrapping informatie tussen sterk verwante voorbeelden mengen.
023. Combineer echte bomen met de bibliotheek
Nu train je RandomForestClassifier. Net als in het regressielab is x een tabel: iedere binnenste lijst is één rij, iedere positie een feature. y bevat precies één klasse per rij; fit leert en predict verwerkt nieuwe rijen.
from sklearn.ensemble import (
RandomForestClassifier)
x = [[0, 0], [0, 1], [1, 0], [1, 1]]
y = [0, 0, 1, 1]
model = RandomForestClassifier(
n_estimators=32, max_depth=4,
max_features="sqrt", bootstrap=True,
random_state=7, n_jobs=1)
model.fit(x, y)
print(model.predict([[0, .5], [1, .5]]))
# [0 1]
n_estimators kiest 32 bomen en max_depth begrenst elke boom tot vier niveaus met vragen. max_features="sqrt" bepaalt hoeveel willekeurige featurekandidaten een split in beginsel onderzoekt; bij twee features is dat één. De bibliotheek kan verder zoeken als die kandidaten geen geldige split opleveren.
bootstrap=True maakt de rijsteekproeven; random_state=7 zet de toevalsbron vast. n_jobs=1 schakelt parallelle uitvoering uit. Maak fit_forest(x,y) met precies deze instellingen en geef het gefitte model terug.
Veelgemaakte fout: denken dat het forest altijd een harde meerderheid van boomlabels neemt. Deze bibliotheek middelt de klassekansen van de bomen. Drie bomen met kansen 0.49, 0.49 en 0.90 voor klasse 1 laten het verschil zien:
kansen = [0.49, 0.49, 0.90]
gemiddelde = sum(kansen) / len(kansen)
print(gemiddelde) # ongeveer 0.626667
print(gemiddelde >= 0.5) # True
Twee harde boomkeuzes zouden klasse 0 kiezen; de gemiddelde kans kiest klasse 1. Dit zijn voorbeeldkansen om de combinatieregel te begrijpen, geen beweerde uitkomsten van het model hierboven.
Meer bomen kunnen toevallige schommelingen verminderen, maar herstellen geen systematisch verkeerde labels. Ook 32 bomen moeten op onafhankelijke gegevens worden beoordeeld.
03Wat neem je mee?
- Bootstrapping trekt met teruglegging; dubbele en ontbrekende rijen zijn onderdeel van het ontwerp.
- OOB-voorspellingen gebruiken per rij alleen bomen die die rij niet zagen.
- Een forest varieert rijen én featurekeuze en combineert klassekansen.
Hierna bouwen modellen niet naast elkaar, maar na elkaar verder aan de resterende fout.