Esercizio - Albero di decisione con criteri di impurità e potatura sul dataset iris
Questa pagina non ha ancora la versione ripasso: qui sotto c'è il testo completo.
In questa pagina 4
Testo (laboratorio LAB5). Sul dataset iris (150 fiori, 4 feature, 3 classi):
- con l'indice di Gini trovare la prima divisione ottimale e costruire l'albero di profondità 3; calcolare l'accuracy sul training al variare della profondità;
- confrontare i criteri Gini, entropia e guadagno d'informazione su una divisione stratificata ;
- eseguire la potatura a costo-complessità: calcolare i dei nodi interni e l'effetto della potatura sull'accuracy;
- (esercizio del laboratorio) scrivere
EntropyCriterioneInformationGainCriterion.
Teoria usata: Alberi di decisioneUn albero di decisione partiziona i dati con una sequenza di regole su una sola variabile alla volta (nodi interni = regole, foglie = predizioni: classe più frequente, oppure media del target in regressione). Si costruisce in modo ricorsivo scegliendo a ogni nodo la divisione che rende i figli più «puri»: con l'entropia $H=-\sum p_i\log_2p_i$ e il guadagno d'informazione $IG=H(S)-\sum\frac{|S_v|}{|S|}H(S_v)$ (ID3), oppure con l'indice di Gini $1-\sum p_i^2$ e soglie $x\le t$ su variabili numeriche (CART); in regressione con MSE o riduzione di varianza. Un albero pienamente sviluppato fa overfitting (varianza alta): si limita con la profondità massima (pre-potatura) o con la potatura a costo-complessità $R_\alpha(T)=R(T)+\alpha|T|$ (post-potatura). Pro: interpretabile, niente normalizzazione, predizione immediata; contro: varianza alta, da cui le foreste. Programma di Telecomunicazioni: Decision Trees e Random Forests.Alberi di decisione → (Gini, entropia, soglie, costo-complessità); Esponenziale e logaritmoLa funzione esponenziale a^x (base positiva diversa da 1) e la sua inversa, il logaritmo in base a, con grafici e proprietà.Esponenziale e logaritmo → per i logaritmi dell'entropia; il confronto con la validazione in Overfitting, ridge regression e cross-validationUna buona prestazione sul training non basta: serve stimare quella su dati nuovi. La cross-validation (K-fold: $k$ parti, ciascuna a turno come test, errore medio; Monte Carlo: $k$ divisioni casuali con quota di test $q$; leave-one-out se $k=n$) evita di dipendere da una sola divisione casuale. L'errore atteso si scompone in $\text{bias}^2+\text{varianza}+\sigma^2$: i modelli semplici fanno underfitting (bias alto), quelli complessi overfitting (varianza alta). La regolarizzazione aggiunge alla perdita una penalità: la ridge regression minimizza $|y-X\beta|^2+\lambda\sum_{j\ge1}\beta_j^2$ e ha soluzione $\beta=(X^TX+\lambda\tilde I)^{-1}X^Ty$ (l'intercetta non si penalizza, le feature si standardizzano): riduce i coefficienti, rende l'inversa stabile con feature collineari, e $\lambda$ è un iperparametro scelto con la validazione (cross-validation annidata per non contaminare il test).Overfitting, ridge regression e cross-validation →.
1. Prima divisione
Per ogni feature e per ogni soglia (si provano tutti i valori osservati, con partizione e ) si calcola il Gini ponderato . Alla radice .
La migliore divisione è sulla lunghezza del petalo con soglia cm: a sinistra le setosa (Gini ), a destra campioni (50 versicolor, 50 virginica) con Gini . Gini ponderato (riduzione ). La larghezza del petalo con soglia produce la stessa partizione (pareggio): la scelta dipende dall'ordine di scansione delle feature.
Albero di profondità 3 (con scikit-learn, stessa partizione): larghezza petalo : setosa; altrimenti larghezza e poi lunghezza (foglia e foglia ), oppure larghezza e lunghezza (foglie e ). Le foglie contengono (setosa, versicolor, virginica) e prevedono la classe di maggioranza: sbaglia campione, ne sbaglia , ne sbaglia , nessuno. Errori totali su 150: accuracy sul training .
| profondità | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| accuracy training |
Con profondità 1 si separa solo la setosa: a sinistra campioni tutti giusti, a destra campioni metà versicolor e metà virginica, di cui se ne indovinano : ; con profondità 5 si arriva a sul training (overfitting probabile: l'accuracy sul training cresce sempre).
2. Confronto dei criteri
Con np.random.seed(0) e divisione stratificata (120 training e 30 test, 10 per classe): Gini, entropia e guadagno d'informazione danno gli stessi risultati: accuracy di training e di test per l'albero di profondità 3. Le tre misure di impurità sono quasi equivalenti e scelgono quasi sempre lo stesso attributo. Per per il guadagno d'informazione il criterio si massimizza (), per Gini ed entropia di split si minimizza: nel codice questo si gestisce con l'attributo OPTIMIZATION.
Entropia e guadagno nel codice.
class EntropyCriterion(Criterion):
OPTIMIZATION = "minimize"
@staticmethod
def impurity(y):
p = np.unique(y, return_counts=True)[1] / len(y)
return -np.sum(p * np.log2(p + 1e-16)) # il termine 1e-16 evita log(0)
@staticmethod
def split_impurity(y_left, y_right):
n = len(y_left) + len(y_right)
return (len(y_left) * EntropyCriterion.impurity(y_left) + len(y_right) * EntropyCriterion.impurity(y_right)) / n
class InformationGainCriterion(Criterion):
OPTIMIZATION = "maximize"
# impurity = entropia; split_impurity = H(y_left U y_right) - entropia ponderata dei figli
# is_tolerance_reached: improvement = split_impurity (il guadagno stesso), confrontato con min_improvement3. Potatura a costo-complessità
Per ogni nodo interno : , con e la somma di sulle foglie del sottoalbero. Sull'albero di profondità 3 (5 foglie):
- il nodo «larghezza » (46 campioni, ): ; foglie e con ; (il più piccolo: si pota per primo);
- il nodo «larghezza » (54 campioni): ;
- il nodo «larghezza » (4 foglie): ; la radice (5 foglie): .
Potare il nodo 1 lo trasforma in una foglia (46 campioni, classe virginica): le foglie diventano 4 e l'accuracy sul training resta . Poi si ricalcolano gli sull'albero potato: ora il nodo «larghezza » ha ancora ed è il minimo: potandolo le foglie diventano 3 e l'accuracy scende a ; infine il nodo «larghezza », ormai con due foglie, ha (potandolo restano foglie, accuracy ) e poi la radice ha ( foglia: accuracy ).
| di potatura | foglie rimaste | accuracy training |
|---|---|---|
La potatura iniziale (fino a ) toglie foglie quasi senza perdere accuracy: i rami eliminati distinguevano pochissimi campioni, tipicamente rumore. La scelta del livello di potatura si fa con un insieme di validazione, non sul training (dove l'accuracy non può che scendere). Nel notebook di laboratorio il nodo radice ha e non perché il loro albero divide anche il nodo puro delle setosa (7 foglie: ); gli altri tre valori coincidono.
Codice
from sklearn.tree import DecisionTreeClassifier
for depth in range(1, 6):
t = DecisionTreeClassifier(max_depth=depth, random_state=0).fit(X, y); print(depth, t.score(X, y))
tree = DecisionTreeClassifier(max_depth=3, random_state=0).fit(X, y)
print(tree.cost_complexity_pruning_path(X, y).ccp_alphas) # [0, 0.0042, 0.0297, 0.2598, 0.3333]
pruned = DecisionTreeClassifier(max_depth=3, ccp_alpha=0.03, random_state=0).fit(X, y) # 3 foglie