Machine Learning Academy · Lektion

Visualisering og fortolkning af beslutningstræer

Eksportér og gengiv et træ med sklearms plot_tree, aflæs beslutningsreglerne, og udtræk feature-vigtigheder til rapporter for interessenter.

Lektion 4 af 413 trin

Visualisering og fortolkning af beslutningstræer er en gratis Machine Learning Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Machine Learning Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Machine Learning Academy-kurset indeholder 4 lektioner i alt.

Hvorfor visualisering af træer er vigtig

Beslutningstræer kaldes ofte white-box-modeller, fordi deres beslutningslogik er fuldt gennemsigtig. Ved at visualisere et træ, der er trænet, kan du kontrollere, at modellen træffer beslutninger baseret på meningsfulde egenskaber, forklare forudsigelser for ikke-tekniske interessenter, identificere potentielle problemer med datakvaliteten (f.eks. at en egenskab, der ikke burde være vigtig, optræder ved roden) og fejlfinde uventet adfærd. Visualisering omdanner træets matematiske struktur til et menneskeligt læsbart flowchart, som fageksperter kan kontrollere i forhold til deres viden.

from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

X, y = load_iris(return_X_y=True)
feature_names = load_iris().feature_names
class_names   = load_iris().target_names

tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)

plt.figure(figsize=(14, 6))
plot_tree(tree,
          feature_names=feature_names,
          class_names=class_names,
          filled=True,      # Color by majority class
          rounded=True,     # Rounded boxes
          fontsize=10)
plt.title('Iris Decision Tree (depth=3)')
plt.show()

Sådan læser du en knude i output fra plot_tree

Hver knude i outputtet fra plot_tree viser fire oplysninger: (1) Betingelsen for opdelingen (f.eks. petal length <= 2.45), (2) Knudens Gini-urenhed, (3) Antallet af eksempler, der nåede denne knude under træningen, og (4) Klassefordelingen som en liste med antallet af eksempler pr. klasse. Bladknuder viser alle fire oplysninger, men ingen betingelse for opdeling — klassen med flest eksempler er forudsigelsen. Knudens farveintensitet angiver renheden: mørkere betyder flere eksempler i den dominerende klasse.

# Interpreting node output from plot_tree:
#
# petal length (cm) <= 2.45     <- split condition
# gini = 0.667                  <- impurity before split
# samples = 150                 <- training samples reaching node
# value = [50, 50, 50]          <- samples per class [setosa, versicolor, virginica]
# class = setosa                <- majority class (prediction if leaf)

print('Gini 0.667 = equal 3-class split (maximum 3-class impurity)')
print('samples=150 at root = all training samples')
print('value=[50,50,50] = perfectly balanced classes')

Eksport af træet som tekst med export_text

Til logning, rapporter eller miljøer uden grafisk visning genererer export_text() en tekstbaseret gengivelse af træet. Hvert indrykningsniveau repræsenterer ét opdelingsniveau. Lodretstregen viser grene, og linjer for bladknuder viser den forudsagte klasse. Dette format er nyttigt til indlejring af beslutningsregler i dokumentation, lagring i logfiler eller visning i kommandolinjemiljøer. Det gør det også muligt at sammenligne træstrukturer numerisk på tværs af forskellige hyperparameterkonfigurationer.

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)

text_repr = export_text(
    tree,
    feature_names=list(load_iris().feature_names)
)
print(text_repr)

Eksport til Graphviz DOT-format

export_graphviz() genererer en DOT-sprogsfil, som kan gengives som en SVG- eller PNG-fil i høj kvalitet ved hjælp af Graphviz. Det er ideelt til trædiagrammer i præsentationskvalitet og til store træer, der kræver rulning for at blive vist. DOT-filen kan også konverteres til en PDF eller indlejres i rapporter. I Jupyter kan du bruge graphviz.Source(dot_data) til at gengive den direkte. Denne tilgang giver fuld kontrol over skriftstørrelse, farveskema og layout — hvilket er vigtigt, når træet deles med interessenter fra virksomheden.

from sklearn.tree import export_graphviz
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
import graphviz

X, y = load_iris(return_X_y=True)
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)

dot_data = export_graphviz(
    tree,
    out_file=None,
    feature_names=load_iris().feature_names,
    class_names=load_iris().target_names,
    filled=True, rounded=True,
    special_characters=True
)
# graph = graphviz.Source(dot_data)  # Renders in Jupyter
# graph.render('iris_tree', format='png')  # Save as PNG

Egenskabers betydning: Hvad drev modellen?

Efter træningen viser tree.feature_importances_ det relative bidrag fra hver inputegenskab til modellens forudsigelser. Egenskaber, der bruges ved roden og på de øverste niveauer, har typisk stor betydning, fordi deres opdelinger påvirker alle træningsprøver. Egenskaber, der kun bruges i dybe blade, har lille betydning. At afbilde egenskabernes betydning som et søjlediagram er et standardtrin i enhver træbaseret analyse — det bekræfter, at modellen bygger på fornuftige, domænerelevante egenskaber frem for tilfældige korrelationer, der blot fungerer på træningsdata.

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
import pandas as pd
import matplotlib.pyplot as plt

X, y = load_breast_cancer(return_X_y=True)
features = load_breast_cancer().feature_names

tree = DecisionTreeClassifier(max_depth=5, random_state=42)
tree.fit(X, y)

imp = pd.Series(tree.feature_importances_, index=features).sort_values(ascending=False)

imp.head(10).plot(kind='barh')
plt.title('Top 10 Feature Importances')
plt.xlabel('Importance')
plt.gca().invert_yaxis()
plt.show()

print('Top feature:', imp.index[0], '(importance:', imp.iloc[0].round(3), ')')

Sporing af en enkelt forudsigelse

Metoden decision_path() returnerer en sparsom indikator-matrix, der viser, hvilke knuder hver prøve besøger. Kombineret med tree.tree_ kan du rekonstruere den nøjagtige rækkefølge af beslutninger for enhver forudsigelse. Dette er grundlaget for automatiserede forklaringssystemer: For hver forudsigelse kan du generere en menneskeligt læsbar liste over regler som »kronbladets længde var 1,4 cm (≤2,45), så vejen gik til venstre; endte i et blad, der forudsiger setosa«. Dette niveau af gennemsigtighed er påkrævet i regulerede domæner, hvor enhver beslutning skal kunne revideres.

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

X, y = load_iris(return_X_y=True)
features = load_iris().feature_names
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)

# Trace the path for sample 0
node_indicator = tree.decision_path(X[[0]])
nodes_visited = node_indicator.indices

T = tree.tree_
for node in nodes_visited[:-1]:  # All except leaf
    feature = features[T.feature[node]]
    threshold = T.threshold[node]
    val = X[0, T.feature[node]]
    direction = 'left (<= )' if val <= threshold else 'right (> )'
    print(f'Node {node}: {feature} = {val:.2f}, threshold={threshold:.2f} -> {direction}')

Fortolkning af opdelingsbetingelser for interessenter

Når du kommunikerer træbeslutninger til ikke-tekniske interessenter, skal du omsætte de matematiske opdelingsbetingelser til formuleringer i et almindeligt sprog. I stedet for »petal length (cm) <= 2.45: gini=0.0, samples=50« kan du sige »Hvis kronbladet er kortere end 2,45 cm, er blomsten næsten med sikkerhed en Setosa.« Formulér hver gren ud fra egenskabens forretningsmæssige betydning. Beslutningstræer er blandt ML-modeller de bedst egnede til kommunikation med interessenter, fordi hver beslutning svarer til en regel fra virksomheden, som kan testes og fortolkes.

# Human-readable rule extraction from a trained tree
from sklearn.tree import _tree

def extract_rules(tree, feature_names, class_names):
    T = tree.tree_
    rules = []
    
    def recurse(node, path):
        if T.feature[node] != _tree.TREE_UNDEFINED:
            feat = feature_names[T.feature[node]]
            thresh = T.threshold[node]
            recurse(T.children_left[node],  path + [f'{feat} <= {thresh:.2f}'])
            recurse(T.children_right[node], path + [f'{feat} > {thresh:.2f}'])
        else:
            majority_class = class_names[T.value[node].argmax()]
            rules.append(' AND '.join(path) + f' => {majority_class}')
    
    recurse(0, [])
    return rules

Partielle afhængighedsdiagrammer for individuelle egenskaber

Mens egenskabernes betydning viser hvilke egenskaber der betyder mest, viser Partial Dependence Plots (PDP) hvordan en egenskab påvirker forudsigelsen. Et PDP marginaliserer over alle andre egenskaber og afbilder modellens forudsagte output som en funktion af én eller to egenskaber. For beslutningstræer danner PDP'er trinformede kurver, der afspejler de akseparallelle opdelingstærskler. Scikit-learns PartialDependenceDisplay genererer disse diagrammer direkte fra et tilpasset træ, så det bliver nemt at forklare individuelle egenskabers effekter for domæneeksperter.

from sklearn.inspection import PartialDependenceDisplay
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

X, y = load_iris(return_X_y=True)
features = load_iris().feature_names

tree = DecisionTreeClassifier(max_depth=4, random_state=42)
tree.fit(X, y)

# PDP for the two most important features
fig, ax = plt.subplots(figsize=(10, 4))
PartialDependenceDisplay.from_estimator(
    tree, X, features=[2, 3],  # petal length and petal width
    feature_names=features, ax=ax
)
plt.tight_layout()
plt.show()

Sammenligning af træstrukturer på tværs af hyperparametre

At visualisere, hvordan træstrukturen ændrer sig med dybden, hjælper med at opbygge intuition. Et træ med dybde 1 (en stump) har én opdeling og to blade — den vigtigste enkeltstående egenskab. Et træ med dybde 2 forfiner begge grene med et andet niveau af spørgsmål. Når du sammenligner træer med dybde 1, 3 og 5 på det samme datasæt, kan du se, hvordan modellen opbygger stadig mere kompleks beslutningslogik. Hvis træet med dybde 5 bruger de samme egenskaber som træet med dybde 3 på de øverste niveauer, er disse egenskaber reelt vigtige. Hvis der dukker nye, uklare egenskaber op ved dybde 5, opfanger de sandsynligvis støj.

from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
feat_names = list(load_iris().feature_names)

for depth in [1, 3, 5]:
    tree = DecisionTreeClassifier(max_depth=depth, random_state=42)
    tree.fit(X, y)
    print(f'\n--- max_depth={depth}, leaves={tree.get_n_leaves()} ---')
    print(export_text(tree, feature_names=feat_names)[:300])

Brug af træer til at generere forretningsregler

En af de mest værdifulde anvendelser af beslutningstræer i industrien er at generere eksplicitte forretningsregler, som kan implementeres i regelmotorer, regneark eller ældre systemer, der ikke kan køre ML-modeller. Hver sti fra rod til blad er en komplet HVIS-SÅ-regel. Disse regler kan omsættes til SQL WHERE-betingelser, Python-ordbøger eller scorekort til kreditvurdering. Ved omhyggeligt at styre træets dybde og begrænsningerne for det mindste antal prøver kan du generere et lille regelsæt med høj nøjagtighed, som en forretningsanalytiker manuelt kan gennemgå, godkende og vedligeholde.

# Generate SQL-like rules from a trained decision tree
from sklearn.tree import _tree

def tree_to_sql(tree, feature_names, class_names):
    T = tree.tree_
    rules = []
    
    def traverse(node, conditions):
        if T.feature[node] != _tree.TREE_UNDEFINED:
            fname = feature_names[T.feature[node]]
            thresh = T.threshold[node]
            traverse(T.children_left[node],
                     conditions + [f'{fname} <= {thresh:.3f}'])
            traverse(T.children_right[node],
                     conditions + [f'{fname} > {thresh:.3f}'])
        else:
            pred = class_names[T.value[node].argmax()]
            where = ' AND '.join(conditions)
            rules.append(f'WHEN {where} THEN {pred!r}')
    
    traverse(0, [])
    return 'CASE\n  ' + '\n  '.join(rules) + '\nEND',

Lagring af trævisualiseringer i filer

Når du gemmer trævisualiseringer i filer, bliver de nemme at dele i rapporter, præsentationer og modeldokumentation. Med plot_tree og matplotlib kan du gemme dem som PNG eller SVG ved hjælp af plt.savefig(). Med Graphviz kan du gengive dem direkte som PDF. Til interaktiv udforskning i Jupyter-notesbøger giver indlejret SVG det tydeligste resultat, fordi formatet kan skaleres ubegrænset — nyttigt til dybe træer, der ville blive slørede som en PNG med fast opløsning. Til leverancer til interessenter skal du altid eksportere med høj DPI (300+) eller som vektorformatet SVG, så teksten i knuderne forbliver skarp ved zoom.

from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

X, y = load_iris(return_X_y=True)
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)

# Save as high-DPI PNG for reports
fig, ax = plt.subplots(figsize=(16, 8))
plot_tree(tree, feature_names=load_iris().feature_names,
          class_names=load_iris().target_names,
          filled=True, rounded=True, ax=ax, fontsize=10)
fig.savefig('iris_decision_tree.png', dpi=200, bbox_inches='tight')
fig.savefig('iris_decision_tree.svg', format='svg', bbox_inches='tight')
print('Saved PNG and SVG tree visualisations')

Hurtigt tjek

Test din forståelse af begreberne inden for Machine Learning med Python fra denne lektion.

Opsummering af lektionen

I denne lektion har du lært: hvordan du visualiserer beslutningstræer ved hjælp af plot_tree, export_text og export_graphviz, hvordan du læser oplysninger om knuder (opdelingsbetingelse, Gini, prøver, værdi), og hvordan du udtrækker egenskabers betydning og beslutningsstier til kommunikation med interessenter. Næste emne er Naive Bayes — en sandsynlighedsklassifikator, der anvender Bayes' sætning til at lave forudsigelser.

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Visualisering og fortolkning af beslutningstræer” gratis?

Ja — hele teksten til “Visualisering og fortolkning af beslutningstræer” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Machine Learning Academy-kurset, skal du opgradere til CoddyKit PRO. Machine Learning Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Visualisering og fortolkning af beslutningstræer”?

Eksportér og gengiv et træ med sklearms plot_tree, aflæs beslutningsreglerne, og udtræk feature-vigtigheder til rapporter for interessenter. Du øver dig i Machine Learning Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Machine Learning Academy?

Der kræves ingen tidligere erfaring. Machine Learning Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Visualisering og fortolkning af beslutningstræer”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Machine Learning Academy-lektion?

Ja. Alle Machine Learning Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Opbygning af et træ: Opdelinger, noder og blade
  2. Gini-urenhed og informationsgevinst
  3. Styring af trædybde for at forebygge overfitting
  4. Visualisering og fortolkning af beslutningstræer
← Tilbage til Machine Learning Academy