Gini-urenhet og informasjonsgevinst
De vil beregne Gini-urenhet og entropi for eksempeloppdelinger og forstå hvorfor treet velger oppdelingen som maksimerer informasjonsgevinsten.
Gini-urenhet og informasjonsgevinst er en gratis leksjon i Machine Learning Academy på CoddyKit. Dette er leksjon 2 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.
Splitteproblemet: Hvilken egenskap skal vi spørre om?
Når vi bygger et beslutningstre, må vi ved hver node velge hvilken egenskap og hvilken terskelverdi som gir den mest nyttige splitten. Målet er å opprette undernoder der observasjonene er så homogene som mulig – ideelt sett inneholder hver undernode bare én klasse. Vi trenger et matematisk mål på urenhet som forteller oss hvor blandede klassene er i en node. Lavere urenhet er bedre: En node der alle observasjonene tilhører samme klasse, har null urenhet (perfekt renhet). To mye brukte mål på urenhet er Gini-urenhet og entropi.
# Impurity measures how mixed the classes are in a node
# Perfect purity: all samples belong to one class -> impurity = 0
# Maximum impurity: classes are equally distributed
import numpy as np
# Node A: all class 0 -> pure
node_a = [0, 0, 0, 0] # impurity = 0
# Node B: 50/50 mix -> maximally impure
node_b = [0, 0, 1, 1] # impurity = maximum
# Node C: mostly one class
node_c = [0, 0, 0, 1] # impurity = low
for name, node in [('A', node_a), ('B', node_b), ('C', node_c)]:
print(f'Node {name}: classes = {node}')Gini-urenhet: Standardkriteriet
Gini-urenhet måler sannsynligheten for at en tilfeldig valgt observasjon fra en node ville blitt feilklassifisert dersom den ble klassifisert tilfeldig i henhold til klassefordelingen i noden. Formelen er: Gini = 1 - sum(p_i^2), der p_i er andelen av klasse i. Gini varierer fra 0 (ren) til 0,5 (lik fordeling mellom to klasser). For K klasser er maksimumsverdien 1 - 1/K. Gini-urenhet er standardkriteriet i scikit-learn sin DecisionTreeClassifier fordi det er beregningsmessig effektivt (ingen logaritmer).
import numpy as np
def gini_impurity(y):
classes, counts = np.unique(y, return_counts=True)
probabilities = counts / len(y)
return 1 - np.sum(probabilities ** 2)
# Pure node
print('Pure [0,0,0,0]:', gini_impurity([0,0,0,0])) # 0.0
# 50/50 split
print('50/50 [0,0,1,1]:', gini_impurity([0,0,1,1])) # 0.5
# 75/25 split
print('75/25 [0,0,0,1]:', gini_impurity([0,0,0,1])) # 0.375
# Three classes equal
print('3-class equal:', gini_impurity([0,1,2,0,1,2])) # ~0.667Entropi og informasjonsteori
Entropi er hentet fra informasjonsteorien og måler usikkerheten eller informasjonsinnholdet i en fordeling. Formel: H = -sum(p_i * log2(p_i)). En ren node har entropi 0 (ingen usikkerhet). En 50/50-fordeling har entropi 1 (én bit usikkerhet – du trenger ett spørsmål for å avgjøre klassen). Entropi og Gini produserer svært like trær i praksis. Entropi er litt tregere å beregne (krever logaritme), men kan gi bedre splitter når klassefordelingene er skjeve. Bruk criterion='entropy' i scikit-learn for å bytte.
import numpy as np
def entropy(y):
classes, counts = np.unique(y, return_counts=True)
probabilities = counts / len(y)
# Avoid log(0) by filtering zero probabilities
probs = probabilities[probabilities > 0]
return -np.sum(probs * np.log2(probs))
print('Pure [0,0,0,0]:', entropy([0,0,0,0])) # 0.0
print('50/50 [0,0,1,1]:', entropy([0,0,1,1])) # 1.0 (1 bit)
print('75/25 [0,0,0,1]:', entropy([0,0,0,1]).round(3)) # 0.811
print('3-class equal:', entropy([0,1,2,0,1,2]).round(3)) # 1.585Informasjonsgevinst: Målet på splittekvalitet
Informasjonsgevinst måler hvor mye en splitt reduserer urenheten. Den beregnes som urenheten i den overordnede noden minus den vektede gjennomsnittlige urenheten i undernodene: IG = impurity(parent) - (N_left/N * impurity(left) + N_right/N * impurity(right)). Den beste splitten maksimerer informasjonsgevinsten: Den oppretter undernoder som er så rene som mulig, vektet etter størrelsen deres (slik at større undernoder teller mer). Trebyggeren evaluerer informasjonsgevinsten for hver egenskap og hver terskelverdi, og velger deretter kombinasjonen med høyest gevinst.
import numpy as np
def gini_impurity(y):
_, counts = np.unique(y, return_counts=True)
p = counts / len(y)
return 1 - np.sum(p**2)
def information_gain(y_parent, y_left, y_right):
n = len(y_parent)
n_l, n_r = len(y_left), len(y_right)
parent_impurity = gini_impurity(y_parent)
weighted_child = (n_l/n)*gini_impurity(y_left) + (n_r/n)*gini_impurity(y_right)
return parent_impurity - weighted_child
y_parent = [0,0,0,1,1,1] # 50/50 parent
y_left = [0,0,0] # pure left
y_right = [1,1,1] # pure right
print('IG:', information_gain(y_parent, y_left, y_right)) # 0.5 (perfect split)Evaluering av flere splitter
For å finne den beste splitten evaluerer algoritmen alle kandidatkombinasjoner av egenskaper og terskelverdier, og velger den som gir høyest informasjonsgevinst. For et datasett med N observasjoner og d egenskaper evaluerer treet opptil N-1 terskelverdier per egenskap (midtpunktet mellom påfølgende unike verdier), noe som gir O(N * d) splitter å evaluere per node. Her er et forenklet eksempel som viser hvordan ulike terskelverdier gir ulik informasjonsgevinst for den samme egenskapen.
import numpy as np
X_feature = np.array([1, 2, 3, 4, 5, 6])
y = np.array([0, 0, 0, 1, 1, 1])
best_threshold, best_ig = None, -1
for threshold in [1.5, 2.5, 3.5, 4.5, 5.5]:
left_mask = X_feature <= threshold
right_mask = ~left_mask
y_l, y_r = y[left_mask], y[right_mask]
_, cnt_p = np.unique(y, return_counts=True)
_, cnt_l = np.unique(y_l, return_counts=True) if len(y_l) else (None, [1])
_, cnt_r = np.unique(y_r, return_counts=True) if len(y_r) else (None, [1])
ig = information_gain(y, y_l, y_r)
print(f'Threshold {threshold}: IG = {ig:.3f}')
if ig > best_ig:
best_ig, best_threshold = ig, threshold
print('Best threshold:', best_threshold, 'with IG:', best_ig)Gini kontra entropi: Praktisk forskjell
Gini-urenhet og entropi produserer nesten identiske trær mesteparten av tiden. De viktigste forskjellene er subtile: Entropi har en tendens til å produsere mer balanserte trær (den straffer ubalanserte splitter hardere på grunn av logaritmen), mens Gini har en tendens til å isolere den vanligste klassen i én gren. Beregningsmessig er Gini raskere fordi den unngår beregning av logaritmen. I praksis er valget mellom dem en hyperparameter som bør finjusteres – prøv begge med kryssvalidering, og velg den som fungerer best på Deres spesifikke datasett.
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 criterion in ['gini', 'entropy']:
tree = DecisionTreeClassifier(criterion=criterion, max_depth=5, random_state=42)
score = cross_val_score(tree, X, y, cv=10).mean()
print(f'criterion={criterion}: CV accuracy = {score:.3f}')
# Usually within 0.5% of each other -- not the critical choiceVektet Gini for flerk klasseproblemer
Gini-urenhet utvides naturlig til flerk klasseproblemer uten endringer: Gini = 1 - sum(p_i^2) fungerer for et hvilket som helst antall klasser. Beregningen av informasjonsgevinst er også uendret – vektet urenhet i undernodene minus urenheten i den overordnede noden. I et problem med tre klasser har et perfekt rent blad (for eksempel med bare klasse 2) Gini lik 0. En node med like store andeler av tre klasser har maksimal Gini lik 2/3. Beslutningstrær er blant de få algoritmene som håndterer flerk klasseproblemer direkte uten endringer – i motsetning til logistisk regresjon, som krever utvidelser som én-mot-rest eller softmax.
import numpy as np
def gini_multiclass(y):
_, counts = np.unique(y, return_counts=True)
p = counts / len(y)
return 1 - np.sum(p**2)
# 3-class examples
print('Pure [0,0,0]:', gini_multiclass([0,0,0])) # 0.0
print('Equal [0,1,2]:', gini_multiclass([0,1,2]).round(3)) # 0.667
print('2 dominant [0,0,1,2]:', gini_multiclass([0,0,1,2]).round(3)) # 0.625
# Max Gini for K classes = 1 - 1/K
for K in [2, 3, 4, 5]:
print(f'Max Gini for {K} classes: {1 - 1/K:.3f}')Reduksjon i urenhet i scikit-learn
Internt i scikit-learn lagrer treet urenheten før splitten og urenheten i hver undernode ved hver node. Differansen, vektet etter antall observasjoner, er reduksjonen i urenhet (informasjonsgevinsten). Denne verdien summeres per egenskap på tvers av alle noder og normaliseres for å beregne feature_importances_ – den totale reduksjonen i urenhet som tilskrives hver egenskap. Egenskaper som forekommer nær roten og håndterer mange observasjoner, har en tendens til å få høyest viktighet fordi hver splitt påvirker en stor del av dataene.
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(criterion='gini', max_depth=3, random_state=42)
tree.fit(X, y)
# Impurity at root and children
print('Root impurity (Gini):', tree.tree_.impurity[0].round(4))
print('Left child impurity:', tree.tree_.impurity[1].round(4))
print('Right child impurity:', tree.tree_.impurity[2].round(4))
# Feature importances = total weighted impurity reduction per feature
print('Feature importances:', tree.feature_importances_.round(3))Rollen til min_impurity_decrease
Som standard deler treet noder så lenge det finnes en reduksjon i urenhet og noden har nok utvalg. Parameteren min_impurity_decrease legger til en minimumsterskel: en deling opprettes bare hvis den reduserer urenheten med minst dette beløpet. Dette hindrer treet i å opprette trivielt små delinger som memoriserer støy. Hvis min_impurity_decrease=0.01, deler treet bare når informasjonsgevinsten overstiger 0.01. Dette er et nyttig alternativ for regularisering sammenlignet med å kontrollere dybden direkte.
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_ig in [0.0, 0.001, 0.005, 0.01, 0.05]:
tree = DecisionTreeClassifier(
min_impurity_decrease=min_ig,
random_state=42
)
score = cross_val_score(tree, X, y, cv=5).mean()
depth = tree.fit(X, y).get_depth()
print(f'min_impurity_decrease={min_ig}: depth={depth}, CV acc={score:.3f}')Sammenligne delinger på tvers av egenskaper
Et gjennomarbeidet eksempel som viser hvordan treet velger den beste egenskapen og terskelen. Med to egenskaper og én delingsterskel for hver beregner treet informasjonsgevinsten for alle alternativene og velger vinneren. Dette illustrerer hvorfor trær naturlig utfører implisitt egenskapsutvelgelse: Egenskaper som aldri gir høy informasjonsgevinst ved noen terskel, blir aldri valgt som deleegenskaper og blir i praksis ignorert. Dette gjør beslutningstrær robuste overfor irrelevante egenskaper, i motsetning til KNN, som påvirkes negativt av dem.
import numpy as np
# Toy dataset: X[:,0]=income, X[:,1]=age; y=churn
X = np.array([[100, 25], [120, 30], [40, 22], [50, 28], [90, 35], [30, 40]])
y = np.array([0, 0, 1, 1, 0, 1])
# Try splitting on income at 75
left_y = y[X[:, 0] <= 75] # [1,1,1]
right_y = y[X[:, 0] > 75] # [0,0,0]
ig_income = information_gain(y, left_y, right_y)
# Try splitting on age at 30
left_y2 = y[X[:, 1] <= 30] # [0,0,1,1]
right_y2 = y[X[:, 1] > 30] # [0,1]
ig_age = information_gain(y, left_y2, right_y2)
print(f'IG(income<=75): {ig_income:.3f}')
print(f'IG(age<=30): {ig_age:.3f}')
print('Best split:', 'income' if ig_income > ig_age else 'age')Bruke Gini i GridSearchCV
Når De justerer et beslutningstre med GridSearchCV, kan De ta med parameteren criterion (gini eller entropy) i parametergridet, slik at kryssvalideringen kan velge det beste alternativet for datasettet Deres. Kombiner dette med max_depth, min_samples_split og min_samples_leaf i det samme søket. Det å søke over criterion gir minimale ekstra beregningskostnader – bare to ekstra konfigurasjoner per kombinasjon – og kan av og til gi en merkbar forbedring når klassefordelingene er svært skjeve eller datasettet har mange delinger med omtrent samme kvalitet.
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 = {
'criterion': ['gini', 'entropy'],
'max_depth': [3, 5, 7, None],
'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 criterion:', grid.best_params_['criterion'])
print('Best depth:', grid.best_params_['max_depth'])
print('Best CV accuracy:', grid.best_score_.round(4))Kort sjekk
Test forståelsen Deres av Machine Learning med Python-konseptene fra denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen lærte De at Gini-urenhet måler hvor blandede klassene er i en node (formel: 1 - sum(p_i^2)), at informasjonsgevinst måler hvor mye en deling reduserer urenheten (urenheten i foreldrenoden minus den vektede urenheten i barnenodene), og at treet alltid velger delingen som maksimerer informasjonsgevinsten på tvers av alle egenskaper og terskler. Deretter skal vi se på hvordan treets dybde kan begrenses for å forhindre overtilpasning.
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 «Gini-urenhet og informasjonsgevinst» gratis?
Ja – hele teksten i «Gini-urenhet og informasjonsgevinst» 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 «Gini-urenhet og informasjonsgevinst»?
De vil beregne Gini-urenhet og entropi for eksempeloppdelinger og forstå hvorfor treet velger oppdelingen som maksimerer informasjonsgevinsten. 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 2 av 4.
Hvor lang tid tar leksjonen «Gini-urenhet og informasjonsgevinst»?
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