Alberi di decisione con R Emanuele Taufer file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 1/14
Implementare gli alberi decisionali con R Per adattare un albero di regressione (o classificazione) possiamo usare la funzione tree() dalla libreria tree. La funzione determina automaticamente se implementare un albero di regressione oppure di classificazione basandosi sulla classe della variabile dipendente: albero di regressione se Y è numeric albero di classificazione se Y è factor L input minimo è molto semplice poiché è sufficiente indicare l equazione di regressione (o classificazione) ed i dati. (analogo a quanto già imparato per la funzione lm()) file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 2/14
Esempio -Hitters Caricare prima la libreria tree ed il dataset Hitters dalla libreria ISLR library(tree) library(islr) data("hitters") ## eliminiamo le osservazioni con dati mancanti Hitters<-Hitters[complete.cases(Hitters),] Per adattare un albero in cui Salary f(y ears, Hits) si usi h.tree<-tree(salary~hits+years,hitters) summary(h.tree) ## ## Regression tree: ## tree(formula = Salary ~ Hits + Years, data = Hitters) ## Number of terminal nodes: 8 ## Residual mean deviance: 101200 = 25820000 / 255 ## Distribution of residuals: ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## -1238.00-157.50-38.84 0.00 76.83 1511.00 file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 3/14
Plot dell albero plot(h.tree,lwd=3) text(h.tree,pretty=0,cex=1.2,col="blue") Nel diagramma, l altezza dei rami indica l efficacia dello split nella riduzione di RSS. Nell esempio i primi split sono i più efficaci. file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 4/14
Analisi dell albero h.tree ## node), split, n, deviance, yval ## * denotes terminal node ## ## 1) root 263 53320000 535.9 ## 2) Years < 4.5 90 6769000 225.8 ## 4) Hits < 39.5 5 3131000 676.5 * ## 5) Hits > 39.5 85 2564000 199.3 ## 10) Years < 3.5 58 309400 138.8 * ## 11) Years > 3.5 27 1586000 329.3 * ## 3) Years > 4.5 173 33390000 697.2 ## 6) Hits < 117.5 90 5312000 464.9 ## 12) Years < 6.5 26 644100 334.7 * ## 13) Years > 6.5 64 4048000 517.8 * ## 7) Hits > 117.5 83 17960000 949.2 ## 14) Hits < 185 76 13290000 914.3 ## 28) Years < 5.5 8 82790 622.5 * ## 29) Years > 5.5 68 12450000 948.7 * ## 15) Hits > 185 7 3571000 1328.0 * file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 5/14
Interpretare l output analitico Per interpretare i risultati nella slide precedente si noti che: I nodi terminali sono indicati con l asterisco (8 in questo caso). Gli altri sono nodi interni La prima riga dell output ci da la chiave di lettura dei risultati: node) : numero del nodo split : criterio di suddivisione n : numero di osservazioni deviance: RSS a quel nodo nel caso degli alberi di regressione; il valore dell indice di Gini o entropia nel caso degli alberi di classificazione il valore ȳ a quel nodo, ossia, la previsione se il nodo è terminale. file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 6/14
Esempio: Nodo 1): include tutte le unità del dataset, 263 RSS = 53320000 la media di Salary è 535, 9. Nodo 2): il primo split è definito dalla condizione Y ears < 4.5, ci sono 90 giocatori che soddisfano la condizione, lo RSS per questo gruppo di giocatori è 6769000 la media di Salary per il gruppo è 225.8. file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 7/14
Controllare i parametri dell albero I parametri di costruzione dell albero possono essere controllati con la funzione tree.control() tree.control(nobs, mincut = 5, minsize = 10, mindev = 0.01) Argomento: nobs : numero di osservazioni nel data set analizzato. mincut : vedi help minsize: vedi help mindev: La devianza minima per procedere ad uno split, si diminuisca (incrementi) il valore di default per ottenere un albero più (meno) grande. file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 8/14
Esempio Per ottenere l albero della slide 8 nella lezione sugli alberi di decisione si usi setup<-tree.control(nrow(hitters), mincut = 5, minsize = 10, mindev = 0.05) h.tree<-tree(salary~hits+years,hitters,control=setup) Su noti che i nuovi parametri sono stati inseriti nell oggetto setup che è poi usato come argomento di tree Per ottenere l albero della slide 19 si usi il codice setup<-tree.control(nrow(hitters), mincut = 5, minsize = 10, mindev = 0.003) h.tree<-tree(salary~.,hitters,control=setup) Nota: la sintassi Salary~. dice ad R di utilizzare Salary come dipendente e tutte le altre variabili nel dataset come indipendenti file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 9/14
Potare l albero La funzione cv.tree() effettua una cross-validazione per ottenere il livello ottimale di complessità dell albero. Per adattare alberi di regressione si usi l argomento FUN=prune.tree (nel qual caso RSS sarà il criterio guida) Per adattare alberi di classificazione si usi l argomento FUN=prune.misclass (nel qual caso il tasso di errore sarà il criterio guida) L output di cv.tree() riporterà: il numero di nodi terminali di ogni albero considerato (size) il corrispondente RSS (o tasso di errore) (dev) altri parametri (non discussi a lezione). file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 10/14
Output Effettuiamo una cross valizazione dell albero ottenuto nella slide 19 set.seed (3) cv.hitters =cv.tree(h.tree,fun=prune.tree ) cv.hitters ## $size ## [1] 20 19 18 16 15 14 13 12 11 10 9 8 7 5 4 3 2 1 ## ## $dev ## [1] 35971835 35971835 35971835 35971835 35971835 35971835 35971835 ## [8] 35971835 35992946 36040462 36691144 37131503 36610330 36258728 ## [15] 34449336 32766687 37931672 53747961 ## ## $k ## [1] -Inf 168100.4 192901.2 228099.7 241121.1 328182.7 ## [7] 375936.1 464830.1 483111.9 752916.8 890908.5 910051.7 ## [13] 1211524.7 1935300.6 2106474.2 2387417.1 6412476.9 20002805.0 ## ## $method ## [1] "deviance" ## ## attr(,"class") ## [1] "prune" "tree.sequence" file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 11/14
Plot Riportiamo in un grafico i risultati per size e dev plot(cv.hitters$size,cv.hitters$dev,type="b", lwd=3,col="blue", xlab="nodi terminali", ylab="rss",main="cost complexity pruning" ) La cross-validazione indica che la dimensione ottimale è 3. file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 12/14
L albero potato A questo punto si utilizzi la funzione prune.tree() per potare l albero iniziale al numero di nodi scelti in base ai risultati ottenuti dalla cross-validazione. prune.hitters=prune.tree(h.tree, best =3) plot(prune.hitters,lwd=3) text(prune.hitters,pretty =0,cex=1.2,col="blue") file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 13/14
Riferimenti bibliografici An Introduction to Statistical Learning, with applications in R. (Springer, 2013) Alcune delle figure in questa presentazione sono tratte dal testo con il permesso degli autori: G. James, D. Witten, T. Hastie e R. Tibshirani file:///c:/users/emanuele.taufer/google%20drive/2%20corsi/3%20sqg/labs/l8-alberi_di_decisione.html#(1) 14/14