Bygge et tre: Splitt, noder og blader
De vil følge hvordan et beslutningstre rekursivt deler data ved hver node, fra rot til blad, og lage prediksjoner ved å følge grenene.
Bygge et tre: Splitt, noder og blader er en gratis leksjon i Machine Learning Academy på CoddyKit. Dette er leksjon 1 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Machine Learning Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Machine Learning Academy inneholder totalt 4 leksjoner.
Hva er et beslutningstre?
Et beslutningstre er en struktur som ligner et flytskjema, der hver intern node stiller et ja/nei-spørsmål om én egenskap, hver gren representerer et svar, og hver bladnode inneholder en prediksjon. For å klassifisere et nytt utvalg starter man ved roten, følger grenene i henhold til egenskapsverdiene og kommer frem til en bladnode hvis etikett er prediksjonen. Beslutningstrær er tolkbare som en del av utformingen — man kan følge nøyaktig hvorfor en prediksjon ble gjort ved å lese sekvensen av besvarte spørsmål. Derfor er de populære i regulerte bransjer som finans og helsevesen.
# Conceptual tree for predicting loan default:
#
# Is income > 50000?
# |--- Yes: Is credit_score > 700?
# | |--- Yes: APPROVE (leaf)
# | |--- No: Is debt_ratio < 0.4?
# | |--- Yes: APPROVE (leaf)
# | |--- No: REJECT (leaf)
# |--- No: REJECT (leaf)
print('Decision tree makes predictions by asking questions')
print('Each path from root to leaf = one decision rule')Noder, grener og bladnoder
Et beslutningstre har tre typer komponenter: rotnode (det første spørsmålet som stilles – den mest informative oppdelingen av hele datasettet), indre noder (mellomliggende spørsmål som deler delmengder av dataene ytterligere) og bladnoder (sluttnoder der prediksjoner lagres). Hver indre node deler dataene inn i to eller flere delmengder basert på en terskelverdi for en egenskap. Dybden til et tre er lengden på den lengste veien fra roten til et blad. Dypere trær kan representere mer komplekse mønstre, men er mer utsatt for overtilpasning.
# Tree anatomy example
print('Root node: first split on most informative feature')
print('Internal nodes: further splits on subsets')
print('Leaf nodes: final predictions')
print()
print('Depth=1 tree (stump): one question, two leaves')
print('Depth=2 tree: up to three questions, four leaves')
print('Depth=d tree: up to 2^d leaves')
print()
print('More depth = more flexible but higher overfitting risk')Rekursiv oppdeling: Slik deler algoritmen opp dataene
Konstruksjon av beslutningstrær er en grådig, rekursiv algoritme. Ved hver node evaluerer den alle mulige splitter for hver egenskap og terskelverdi, velger splitten som skiller klassene best (målt med Gini-urenhet eller informasjonsgevinst), bruker denne splitten og gjentar deretter prosessen rekursivt for hver resulterende delmengde. Dette fortsetter til et stoppkriterium er nådd: maksimal dybde er nådd, minimum antall observasjoner per node er nådd, eller det ikke finnes flere nyttige splitter. Grådig betyr at den lokalt beste splitten velges ved hvert trinn, uten tilbakesporing – dette kan føre til at globalt optimale splitter overses, men gjør algoritmen praktisk gjennomførbar.
# Pseudocode for recursive tree building
def build_tree(X, y, depth=0, max_depth=3):
# Stopping conditions
if len(set(y)) == 1: # All same class
return {'leaf': True, 'prediction': y[0]}
if depth >= max_depth: # Max depth reached
from collections import Counter
return {'leaf': True, 'prediction': Counter(y).most_common(1)[0][0]}
# Find best split
best_feature, best_threshold = find_best_split(X, y)
# Partition data
left_mask = X[:, best_feature] <= best_threshold
right_mask = ~left_mask
return {
'leaf': False,
'feature': best_feature,
'threshold': best_threshold,
'left': build_tree(X[left_mask], y[left_mask], depth+1, max_depth),
'right': build_tree(X[right_mask], y[right_mask], depth+1, max_depth)
}Aksestilte splitter: Terskelverdier for enkelt-egenskaper
Beslutningstrær i scikit-learn bruker alltid aksestilte (ortogonale) splitter: hvert spørsmål undersøker om én egenskap ligger over eller under en terskelverdi (for eksempel age <= 35?). Dette skaper rektangulære beslutningsområder i et todimensjonalt egenskapsrom. Selv om denne fremgangsmåten er enkel og lett å tolke, kan den ikke representere diagonale beslutningsgrenser effektivt – det kreves for eksempel mange splitter for å skille to klasser langs en linje på 45 grader. Trebaserte ensemblemodeller (Random Forests) overvinner dette ved å kombinere mange trær, der hvert tre har ulike aksestilte splitter som samlet kan tilnærme seg en beslutningsgrense med vilkårlig form.
import numpy as np
# Simulate finding a split on one feature
feature_values = np.array([10, 20, 30, 40, 50])
labels = np.array([0, 0, 0, 1, 1])
# For each possible threshold between consecutive values:
for threshold in [15, 25, 35, 45]:
left_labels = labels[feature_values <= threshold]
right_labels = labels[feature_values > threshold]
print(f'Threshold {threshold}: left={list(left_labels)}, right={list(right_labels)}')
# Threshold 35 gives perfect separation [0,0,0] vs [1,1]Trening av et beslutningstre med scikit-learn
scikit-learn sitt DecisionTreeClassifier trenes med ett enkelt kall til fit(). Viktige parametere omfatter max_depth (maksimal tredybde – avgjørende for å kontrollere overtilpasning), criterion (mål på splittekvalitet: 'gini' eller 'entropy') og min_samples_split (minimum antall observasjoner som kreves for å dele en node – hindrer at svært små grupper deles). Etter tilpasningen er treet umiddelbart klart til å lage prediksjoner. I motsetning til KNN er prediksjon O(log N) – du følger ganske enkelt de lærte grenene – noe som gjør beslutningstrær raske ved prediksjon.
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
tree = DecisionTreeClassifier(
max_depth=3,
criterion='gini',
random_state=42
)
tree.fit(X_train, y_train)
print('Train accuracy:', tree.score(X_train, y_train).round(3))
print('Test accuracy:', tree.score(X_test, y_test).round(3))
print('Tree depth:', tree.get_depth())
print('Number of leaves:', tree.get_n_leaves())Følge en prediksjonssti
Styrken ved beslutningstrær er at du kan følge hver prediksjon trinn for trinn. Metoden decision_path() returnerer en sparsom matrise som viser hvilke noder hver observasjon passerte gjennom. Metoden apply() returnerer indeksen til bladnoden for hver observasjon. Disse verktøyene lar deg forklare en bruker nøyaktig hvilke spørsmål som ble stilt, og hvilke svar som førte til prediksjonen – noe som er avgjørende for etterlevelse av krav, feilsøking og tillitsbygging med ikke-tekniske interessenter.
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)
# Print human-readable decision rules
rules = export_text(tree, feature_names=load_iris().feature_names)
print(rules[:500]) # First 500 chars of the rule printout
# Which leaf does sample 0 land in?
leaf = tree.apply(X[[0]])
print('Sample 0 lands in leaf node:', leaf)Treprediksjoner i bladnoder
Hver bladnode lagrer en klassefordeling fra treningsobservasjonene som nådde den. Ved klassifisering er den predikerte klassen den vanligste klassen i bladet. Ved sannsynlighetsestimering returnerer predict_proba() andelen av hver klasse i bladet. En bladnode med 10 observasjoner: 9 i klasse A og 1 i klasse B, predikerer klasse A med sannsynlighet 0,9. Trær med færre observasjoner per blad gir mindre pålitelige sannsynlighetsestimater, og derfor er regulariseringsparametere som min_samples_leaf viktige for kalibrerte sannsynlighetsresultater.
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
import numpy as np
X, y = load_iris(return_X_y=True)
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)
# Predicted class and probabilities for first three samples
preds = tree.predict(X[:3])
probas = tree.predict_proba(X[:3])
for i in range(3):
print(f'Sample {i}: class={preds[i]}, probabilities={probas[i].round(3)}')Beslutningstre for regresjon
DecisionTreeRegressor fungerer på samme måte som klassifikatoren, men predikerer gjennomsnittet av målverdiene til treningsobservasjonene i hvert blad. Splittekriteriet endres: I stedet for Gini-urenhet minimeres gjennomsnittlig kvadratisk feil (eller gjennomsnittlig absolutt feil) i hver resulterende undernode. Regresjonstrær produserer prediksjoner som trappefunksjoner – konstante verdier innenfor rektangulære områder. Med tilstrekkelig dybde kan de tilpasse seg treningsdataene nøyaktig, men dette fører til alvorlig overtilpasning. Kontroller dybden og min_samples_leaf for å regularisere regresjonstreet.
from sklearn.tree import DecisionTreeRegressor
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
X = np.sort(5 * np.random.rand(80, 1), axis=0)
y = np.sin(X).ravel() + np.random.randn(80) * 0.3
for depth in [1, 3, 10]:
reg = DecisionTreeRegressor(max_depth=depth)
reg.fit(X, y)
mse = np.mean((reg.predict(X) - y)**2)
print(f'max_depth={depth}: train MSE={mse:.4f}')
# depth=10 nearly zero MSE (memorised training data)Egenskapsviktighet fra beslutningstrær
Etter tilpasningen gir tree.feature_importances_ et mål på hvor mye hver egenskap bidro til splittene. Egenskapsviktighet beregnes som den totale reduksjonen i urenhet (Gini eller entropi) som tilskrives hver egenskap, vektet etter andelen observasjoner som nådde hver splitt. Verdiene summerer seg til 1,0. Den viktigste egenskapen får høyest verdi. Dette gir en rask og tolkbar måte å identifisere hvilke inndata som i størst grad styrer prediksjonene på – nyttig for valg av egenskaper, forretningsinnsikt og oppdagelse av mulige problemer i dataene.
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
import pandas as pd
X, y = load_iris(return_X_y=True)
feature_names = load_iris().feature_names
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)
importances = pd.Series(tree.feature_importances_, index=feature_names)
print('Feature Importances:')
print(importances.sort_values(ascending=False))Skalauavhengighet: Trær trenger ikke skalering
En viktig praktisk fordel med beslutningstrær er at de er fullstendig skala-uavhengige. En splitt på income <= 50000 og en splitt på income_thousands <= 50 gir identiske trestrukturer. Hvis du legger 100 til alle verdiene i en egenskap eller multipliserer dem med 1000, endres ikke de valgte splittene. Du trenger aldri å bruke StandardScaler eller MinMaxScaler før et beslutningstre. Dette betyr også at beslutningstrær håndterer egenskaper med svært ulike skalaer uten forhåndsbehandling, noe som gjør prosesseringsrør enklere.
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
import numpy as np
X, y = load_iris(return_X_y=True)
# Without scaling
tree1 = DecisionTreeClassifier(random_state=42)
tree1.fit(X, y)
# With scaling (same result expected)
X_scaled = StandardScaler().fit_transform(X)
tree2 = DecisionTreeClassifier(random_state=42)
tree2.fit(X_scaled, y)
print('Without scaling accuracy:', tree1.score(X, y).round(3))
print('With scaling accuracy: ', tree2.score(X_scaled, y).round(3))
# Identical -- scaling has no effect on tree splitsHåndtering av manglende verdier i trær
Beslutningstrær håndterer manglende verdier mer fleksibelt enn mange andre algoritmer. scikit-learn sin DecisionTreeClassifier støtter manglende verdier direkte når splitter='best' brukes – observasjoner med manglende verdier for splitteegenskapen sendes til den undernoden som minimerer urenheten basert på dataene som ikke mangler verdier. Alternativt kan du bruke surrogatsplitter: Når den primære splitteegenskapen mangler for en observasjon, brukes en korrelert egenskap i stedet. Denne robustheten overfor manglende data er en praktisk fordel ved trebaserte modeller sammenlignet med avstandsbaserte metoder som KNN, som krever komplette egenskapsvektorer.
from sklearn.tree import DecisionTreeClassifier
import numpy as np
# Tree can handle NaN values with missing_values support
# In scikit-learn >= 1.0, DecisionTreeClassifier accepts NaN
X = np.array([
[1, 2], [np.nan, 3], [3, np.nan], [4, 5]
])
y = np.array([0, 1, 0, 1])
tree = DecisionTreeClassifier(random_state=42)
tree.fit(X, y)
preds = tree.predict(X)
print('Predictions with NaN features:', preds)
# Tree routes NaN samples gracefullyRask sjekk
Test forståelsen Deres av konsepter innen maskinlæring med Python fra denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen har De lært hvordan beslutningstrær deler opp data rekursivt ved hjelp av aksestilte splitter, at hvert blad lagrer klassefordelingen som brukes til prediksjon basert på flertallsavstemning, og at beslutningstrær er skala-uavhengige og ikke krever skalering av egenskaper. Neste gang utforsker vi Gini-urenhet og informasjonsgevinst – kriteriene som avgjør hvilken splitt som skal velges ved hver node.
Lær deg Python med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «Bygge et tre: Splitt, noder og blader» gratis?
Ja – hele teksten i «Bygge et tre: Splitt, noder og blader» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Machine Learning Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Machine Learning Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Bygge et tre: Splitt, noder og blader»?
De vil følge hvordan et beslutningstre rekursivt deler data ved hver node, fra rot til blad, og lage prediksjoner ved å følge grenene. Du øver på Machine Learning Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Machine Learning Academy?
Ingen tidligere erfaring er nødvendig. Machine Learning Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.
Hvor lang tid tar leksjonen «Bygge et tre: Splitt, noder og blader»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Machine Learning Academy-leksjonen?
Ja. Alle Machine Learning Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Bygge et tre: Splitt, noder og blader
- Gini-urenhet og informasjonsgevinst
- Kontrollere tredybden for å unngå overtilpasning
- Visualisere og tolke beslutningstrær