Salta al contenuto
Note per Studenti Esercizio - Albero di decisione sul ristorante - guadagno d'informazione e potatura (slide del corso)

Esercizio - Albero di decisione sul ristorante - guadagno d'informazione e potatura (slide del corso)

Teoria: Apprendimento automatico nell'IA - supervisionato, SVM e valutazioneQuadro del machine learning nel corso di IA. Tre forme di apprendimento: supervisionato (coppie ingresso-uscita, classificazione se l'uscita è discreta e regressione se è un numero), non supervisionato (pattern senza feedback, per esempio clustering) e per rinforzo (ricompense). Un'ipotesi h approssima la funzione vera f e si valuta sul test set, non sul training set: un modello troppo semplice ha bias alto (underfitting), uno troppo complesso varianza alta (overfitting). Servono training, validation e test set; con pochi dati si usa la k-fold cross-validation. Alberi di decisione: si sceglie l'attributo con massimo guadagno d'informazione Gain = B(p/(p+n)) - somma (Nk/N) B(pk/Nk), si pota con il test del chi quadro (Delta > Delta*), si riduce la varianza con bagging e random forest. Perdita L1 e L2, regressione lineare e discesa del gradiente w <- w - alpha dL/dw. SVM: separatore a margine massimo, vettori di supporto, kernel trick con K(xj,xk). Pipeline scikit-learn del laboratorio 10: load_digits, train_test_split, SVC(C, kernel, gamma), fit, predict, classification_report, confusion_matrix, cross_val_score.Apprendimento automatico nell'IA - supervisionato, SVM e valutazione →, sezione 4. Approfondimento sugli alberi: 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 → e Esercizio - Albero di decisione ID3 sul dataset del tennis.

Testo (dalle slide). Si vuole decidere se aspettare un tavolo al ristorante (WillWait, sì o no). Gli attributi sono 10: Alt (esiste un ristorante alternativo vicino), Bar (c'è un'area bar per aspettare), Fri (venerdì o sabato), Hun (si ha fame), Pat (clienti presenti: None, Some, Full), Price (fascia di prezzo: basso, medio, alto), Rain (piove), Res (c'è una prenotazione), Type (French, Italian, Thai, Burger), Est (attesa stimata in minuti: 0-10, 10-30, 30-60, >60). Il training set ha 12 casi:

es. Alt Bar Fri Hun Pat Price Rain Res Type Est WillWait
1 Sì No No Sì Some alto No Sì French 0-10 Sì
2 Sì No No Sì Full basso No No Thai 30-60 No
3 No Sì No No Some basso No No Burger 0-10 Sì
4 Sì No Sì Sì Full basso Sì No Thai 10-30 Sì
5 Sì No Sì No Full alto No Sì French >60 No
6 No Sì No Sì Some medio Sì Sì Italian 0-10 Sì
7 No Sì No No None basso Sì No Burger 0-10 No
8 No No No Sì Some medio Sì Sì Thai 0-10 Sì
9 No Sì Sì No Full basso Sì No Burger >60 No
10 Sì Sì Sì Sì Full alto No Sì Italian 10-30 No
11 No No No No None basso No No Thai 0-10 No
12 Sì Sì Sì Sì Full basso No No Burger 30-60 Sì

(a) Calcolare l'entropia dell'insieme e il guadagno d'informazione di ogni attributo alla radice. (b) Costruire l'albero con l'algoritmo del corso. (c) Con il test del χ2\chi^2 (5%), stabilire se vanno potati il nodo Hungry sotto Patrons = Full e il nodo Patrons alla radice.

Soluzione

Formule. B(q)=−(qlog⁡2q+(1−q)log⁡2(1−q))B(q)=-(q\log_2q+(1-q)\log_2(1-q)); Gain(A)=B(pp+n)−∑kNkNB(pkNk)\text{Gain}(A)=B(\tfrac p{p+n})-\sum_k\tfrac{N_k}{N}B(\tfrac{p_k}{N_k}).

(a) Radice

Positivi: 1, 3, 4, 6, 8, 12, cioè p=6p=6; negativi: 2, 5, 7, 9, 10, 11, cioè n=6n=6. L'entropia è B(612)=B(12)=1B(\tfrac6{12})=B(\tfrac12)=1 bit.

Conteggi (positivi, negativi) per ogni valore e guadagni:

attributo suddivisione (pos, neg) Gain
Alt No (3,3), Sì (3,3) 00
Bar No (3,3), Sì (3,3) 00
Fri No (4,3), Sì (2,3) 0,02070{,}0207
Hun No (1,4), Sì (5,2) 0,19570{,}1957
Pat None (0,2), Some (4,0), Full (2,4) 0,5409\mathbf{0{,}5409}
Price basso (3,4), medio (2,0), alto (1,2) 0,19570{,}1957
Rain No (3,4), Sì (3,2) 0,02070{,}0207
Res No (3,4), Sì (3,2) 0,02070{,}0207
Type French (1,1), Italian (1,1), Thai (2,2), Burger (2,2) 00
Est 0-10 (4,2), 10-30 (1,1), 30-60 (1,1), >60 (0,2) 0,20750{,}2075

Calcoli rappresentativi:

  • Pat: 212B(0)+412B(1)+612B(26)=0+0+0,5⋅0,9183=0,4591\tfrac2{12}B(0)+\tfrac4{12}B(1)+\tfrac6{12}B(\tfrac26)=0+0+0{,}5\cdot0{,}9183=0{,}4591, quindi Gain=0,5409\text{Gain}=0{,}5409 (≈0,541\approx0{,}541 bit nelle slide). B(13)=13log⁡23+23log⁡232=0,5283+0,3900=0,9183B(\tfrac13)=\tfrac13\log_23+\tfrac23\log_2\tfrac32=0{,}5283+0{,}3900=0{,}9183.
  • Type: ogni sottoinsieme è metà e metà, entropia 11 in ogni caso: Remainder=1\text{Remainder}=1, Gain=0\text{Gain}=0. Dividere per Type non aiuta (come dicono le slide).
  • Hun: 512B(15)+712B(57)=512⋅0,7219+712⋅0,8631=0,3008+0,5035=0,8043\tfrac5{12}B(\tfrac15)+\tfrac7{12}B(\tfrac57)=\tfrac5{12}\cdot0{,}7219+\tfrac7{12}\cdot0{,}8631=0{,}3008+0{,}5035=0{,}8043, quindi Gain=0,1957\text{Gain}=0{,}1957.
  • Est: 612B(46)+212B(12)+212B(12)+212B(0)=0,5⋅0,9183+412=0,7925\tfrac6{12}B(\tfrac46)+\tfrac2{12}B(\tfrac12)+\tfrac2{12}B(\tfrac12)+\tfrac2{12}B(0)=0{,}5\cdot0{,}9183+\tfrac4{12}=0{,}7925, quindi Gain=0,2075\text{Gain}=0{,}2075.

La radice è Patrons.

(b) L'albero

  • Patrons = None: (0,2), tutti negativi, foglia No.
  • Patrons = Some: (4,0), tutti positivi, foglia Sì.
  • Patrons = Full: p=2p=2 (es. 4 e 12), n=4n=4 (es. 2, 5, 9, 10). Entropia B(26)=0,9183B(\tfrac26)=0{,}9183. Si ricalcolano i guadagni solo su questi 6 esempi:
attributo suddivisione (pos, neg) in Full Gain
Hun No (0,2), Sì (2,2) 0,25160{,}2516
Price basso (2,2), alto (0,2) 0,25160{,}2516
Res No (2,2), Sì (0,2) 0,25160{,}2516
Type French (0,1), Italian (0,1), Thai (1,1), Burger (1,1) 0,25160{,}2516
Est 10-30 (1,1), 30-60 (1,1), >60 (0,2) 0,25160{,}2516
Alt, Fri No (0,1), Sì (2,3) 0,10920{,}1092
Rain No (1,3), Sì (1,1) 0,04410{,}0441
Bar No (1,2), Sì (1,2) 00

Per esempio Hun\text{Hun}: Remainder=26B(0)+46B(24)=0+23⋅1=0,6667\text{Remainder}=\tfrac26B(0)+\tfrac46B(\tfrac24)=0+\tfrac23\cdot1=0{,}6667, Gain=0,9183−0,6667=0,2516\text{Gain}=0{,}9183-0{,}6667=0{,}2516. Cinque attributi sono a pari merito (Hun, Price, Res, Type, Est): l'algoritmo non dice quale scegliere e le slide scelgono Hungry. (Con una scelta diversa si ottengono alberi diversi ma tutti coerenti con il training set.)

  • Full e Hun = No: (0,2), foglia No.
  • Full e Hun = Sì: (2,2) (es. 2, 4, 10, 12), ancora misto. Entropia 1. Guadagni: Type =1−[24⋅B(12) (Thai: es. 2,4)+14B(0) (Italian)+14B(1) (Burger)]=1−0,5=0,5=1-\big[\tfrac24\cdot B(\tfrac12)\ (\text{Thai: es. }2,4)+\tfrac14B(0)\ (\text{Italian})+\tfrac14B(1)\ (\text{Burger})\big]=1-0{,}5=0{,}5; Fri =0,3113=0{,}3113; si sceglie Type: Italian →\to No; Burger →\to Sì; Thai (es. 2 con Fri = No e es. 4 con Fri = Sì) →\to si divide ancora con Fri (guadagno 1): Fri = No →\to No, Fri = Sì →\to Sì.

Albero completo (coerente con tutti i 12 esempi):

Patrons?
├─ None  -> No
├─ Some  -> Sì
└─ Full  -> Hungry?
            ├─ No  -> No
            └─ Sì  -> Type?
                      ├─ Italian -> No
                      ├─ Burger  -> Sì
                      └─ Thai    -> Fri?  (No -> No, Sì -> Sì)

(c) Potatura con il χ2\chi^2

Hungry sotto Full (0 positivi e 2 negativi se No; 2 e 2 se Sì): p=2p=2, n=4n=4, N=6N=6. Attesi: No (Nk=2N_k=2): p^=2⋅26=0,667\hat p=2\cdot\tfrac26=0{,}667, n^=4⋅26=1,333\hat n=4\cdot\tfrac26=1{,}333; Sì (Nk=4N_k=4): p^=1,333\hat p=1{,}333, n^=2,667\hat n=2{,}667. Δ=(0−0,667)20,667+(2−1,333)21,333+(2−1,333)21,333+(2−2,667)22,667=0,667+0,333+0,333+0,167=1,5.\Delta=\tfrac{(0-0{,}667)^2}{0{,}667}+\tfrac{(2-1{,}333)^2}{1{,}333}+\tfrac{(2-1{,}333)^2}{1{,}333}+\tfrac{(2-2{,}667)^2}{2{,}667}=0{,}667+0{,}333+0{,}333+0{,}167=1{,}5. Attributo a d=2d=2 valori: 1 grado di libertà, Δ∗=3,841\Delta^*=3{,}841 (tavola, probabilità 0,050{,}05). 1,5<3,8411{,}5<3{,}841: l'ipotesi nulla (Hungry irrilevante) non si rifiuta: si pota. Il ramo Full diventa una foglia con il valore più frequente: No (4 negativi contro 2 positivi).

Patrons alla radice (p=n=6p=n=6, N=12N=12): attesi p^=n^=6⋅Nk12\hat p=\hat n=6\cdot\tfrac{N_k}{12}: None (Nk=2N_k=2) 11 e 11; Some (Nk=4N_k=4) 22 e 22; Full (Nk=6N_k=6) 33 e 33. Δ=(0−1)21+(2−1)21+(4−2)22+(0−2)22+(2−3)23+(4−3)23=1+1+2+2+13+13=6,667.\Delta=\tfrac{(0-1)^2}{1}+\tfrac{(2-1)^2}{1}+\tfrac{(4-2)^2}{2}+\tfrac{(0-2)^2}{2}+\tfrac{(2-3)^2}{3}+\tfrac{(4-3)^2}{3}=1+1+2+2+\tfrac13+\tfrac13=6{,}667. Con d=3d=3 i gradi di libertà sono 2 e Δ∗=5,991\Delta^*=5{,}991: 6,667>5,9916{,}667>5{,}991, l'attributo è significativo, si tiene.

Albero potato: Patrons: None →\to No, Some →\to Sì, Full →\to No. Accuratezza sul training: 2+4+4=102+4+4=10 esempi su 12, cioè 83,3%83{,}3\%, contro il 100%100\% dell'albero completo; ma l'albero potato è molto più semplice (un solo test) e di solito generalizza meglio, come richiede il rasoio di Ockham.

Verifica con Python

python
import math

righe = """Sì No No Sì Some alto No Sì French 0-10 Sì
Sì No No Sì Full basso No No Thai 30-60 No
No Sì No No Some basso No No Burger 0-10 Sì
Sì No Sì Sì Full basso Sì No Thai 10-30 Sì
Sì No Sì No Full alto No Sì French >60 No
No Sì No Sì Some medio Sì Sì Italian 0-10 Sì
No Sì No No None basso Sì No Burger 0-10 No
No No No Sì Some medio Sì Sì Thai 0-10 Sì
No Sì Sì No Full basso Sì No Burger >60 No
Sì Sì Sì Sì Full alto No Sì Italian 10-30 No
No No No No None basso No No Thai 0-10 No
Sì Sì Sì Sì Full basso No No Burger 30-60 Sì""".split("\n")
nomi = ["Alt", "Bar", "Fri", "Hun", "Pat", "Price", "Rain", "Res", "Type", "Est"]
D = [r.split() for r in righe]

def B(q): return 0 if q in (0, 1) else -(q * math.log2(q) + (1 - q) * math.log2(1 - q))
def H(S): return B(sum(r[-1] == "Sì" for r in S) / len(S))
def gain(S, a):
    resto = sum(len(T) / len(S) * H(T) for v in set(r[a] for r in S) for T in [[r for r in S if r[a] == v]])
    return H(S) - resto
def delta(S, a):                                     # statistica chi quadro per la potatura
    p = sum(r[-1] == "Sì" for r in S); n = len(S) - p; d = 0
    for v in set(r[a] for r in S):
        T = [r for r in S if r[a] == v]; pk = sum(r[-1] == "Sì" for r in T); nk = len(T) - pk
        ph, nh = p * len(T) / len(S), n * len(T) / len(S)
        d += (pk - ph) ** 2 / ph + (nk - nh) ** 2 / nh
    return d

for a, nome in enumerate(nomi): print(nome, round(gain(D, a), 4))
full = [r for r in D if r[4] == "Full"]
print("Hungry in Full: gain", round(gain(full, 3), 4), "delta", delta(full, 3))   # 0.2516 e 1.5
print("Patrons alla radice: delta", round(delta(D, 4), 3))                         # 6.667

Output: guadagni come in tabella (Pat 0,54090{,}5409), Δ=1,5\Delta=1{,}5 e Δ=6,667\Delta=6{,}667.

Versione ripasso

Teoria: Apprendimento automatico nell'IA - supervisionato, SVM e valutazioneQuadro del machine learning nel corso di IA. Tre forme di apprendimento: supervisionato (coppie ingresso-uscita, classificazione se l'uscita è discreta e regressione se è un numero), non supervisionato (pattern senza feedback, per esempio clustering) e per rinforzo (ricompense). Un'ipotesi h approssima la funzione vera f e si valuta sul test set, non sul training set: un modello troppo semplice ha bias alto (underfitting), uno troppo complesso varianza alta (overfitting). Servono training, validation e test set; con pochi dati si usa la k-fold cross-validation. Alberi di decisione: si sceglie l'attributo con massimo guadagno d'informazione Gain = B(p/(p+n)) - somma (Nk/N) B(pk/Nk), si pota con il test del chi quadro (Delta > Delta*), si riduce la varianza con bagging e random forest. Perdita L1 e L2, regressione lineare e discesa del gradiente w <- w - alpha dL/dw. SVM: separatore a margine massimo, vettori di supporto, kernel trick con K(xj,xk). Pipeline scikit-learn del laboratorio 10: load_digits, train_test_split, SVC(C, kernel, gamma), fit, predict, classification_report, confusion_matrix, cross_val_score.Apprendimento automatico nell'IA - supervisionato, SVM e valutazione →, 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 →.

Formule. B(q)=−(qlog⁡2q+(1−q)log⁡2(1−q))B(q)=-(q\log_2q+(1-q)\log_2(1-q)); Gain(A)=B(pp+n)−∑kNkNB(pkNk)\text{Gain}(A)=B(\tfrac p{p+n})-\sum_k\frac{N_k}{N}B(\frac{p_k}{N_k}); Δ=∑k[(pk−p^k)2p^k+(nk−n^k)2n^k]\Delta=\sum_k[\frac{(p_k-\hat p_k)^2}{\hat p_k}+\frac{(n_k-\hat n_k)^2}{\hat n_k}], p^k=pNk/N\hat p_k=pN_k/N, n^k=nNk/N\hat n_k=nN_k/N.

Radice (p=n=6p=n=6, H=1H=1). Guadagni: Alt 00, Bar 00, Fri 0,02070{,}0207, Hun 0,19570{,}1957, Pat 0,54090{,}5409, Price 0,19570{,}1957, Rain 0,02070{,}0207, Res 0,02070{,}0207, Type 00, Est 0,20750{,}2075.

  • Pat: None (0,2), Some (4,0), Full (2,4): Remainder=612B(26)=0,5⋅0,9183=0,4591\text{Remainder}=\tfrac6{12}B(\tfrac26)=0{,}5\cdot0{,}9183=0{,}4591, Gain=0,5409\text{Gain}=0{,}5409.
  • Type: ogni sottoinsieme (1,1) o (2,2), entropia 1, Gain=0\text{Gain}=0.

Albero. None →\to No; Some →\to Sì; Full (2,4), H=0,9183H=0{,}9183: Hun, Price, Res, Type, Est tutti con guadagno 0,25160{,}2516 (pari merito; le slide scelgono Hungry: Remainder=46⋅1\text{Remainder}=\tfrac46\cdot1). Hun = No →\to No; Hun = Sì (2,2) →\to Type (guadagno 0,50{,}5): Italian →\to No, Burger →\to Sì, Thai →\to Fri (No →\to No, Sì →\to Sì).

Potatura (χ2\chi^2, 5%).

  • Hungry in Full: attesi No p^=0,667\hat p=0{,}667, n^=1,333\hat n=1{,}333; Sì 1,3331{,}333 e 2,6672{,}667: Δ=0,667+0,333+0,333+0,167=1,5<3,841\Delta=0{,}667+0{,}333+0{,}333+0{,}167=1{,}5<3{,}841 (1 grado di libertà): si pota, Full →\to No.
  • Patrons: Δ=1+1+2+2+13+13=6,667>5,991\Delta=1+1+2+2+\tfrac13+\tfrac13=6{,}667>5{,}991 (2 gradi di libertà): si tiene.
  • Albero potato: None No, Some Sì, Full No; accuratezza sul training 10/12=83,3%10/12=83{,}3\% contro 100%100\% dell'albero completo.

Attributi: Alt, Bar, Fri, Hun, Pat (None, Some, Full), Price (basso, medio, alto), Rain, Res, Type (French, Italian, Thai, Burger), Est (0-10, 10-30, 30-60, >60). Positivi: esempi 1, 3, 4, 6, 8, 12 (p=6p=6); negativi: 2, 5, 7, 9, 10, 11 (n=6n=6).

Esempi di calcolo. Hun: 512B(15)+712B(57)=0,3008+0,5035=0,8043\tfrac5{12}B(\tfrac15)+\tfrac7{12}B(\tfrac57)=0{,}3008+0{,}5035=0{,}8043, Gain=0,1957\text{Gain}=0{,}1957. Est: 0,5⋅0,9183+412⋅1=0,79250{,}5\cdot0{,}9183+\tfrac4{12}\cdot1=0{,}7925, Gain=0,2075\text{Gain}=0{,}2075. In Full: Rain 46B(14)+26B(12)=0,5409+0,3333=0,8742\tfrac46B(\tfrac14)+\tfrac26B(\tfrac12)=0{,}5409+0{,}3333=0{,}8742, Gain=0,0441\text{Gain}=0{,}0441; Alt e Fri 0,10920{,}1092; Bar 00. In Full e Hun = Sì: Type =1−24⋅1=0,5=1-\tfrac24\cdot1=0{,}5, Fri 0,31130{,}3113.

Ricordare: B(13)=0,9183B(\tfrac13)=0{,}9183; i guadagni dei sottoalberi si calcolano solo sugli esempi del ramo; pari merito tra cinque attributi in Full, le slide scelgono Hungry; Δ∗=3,841\Delta^*=3{,}841 con 1 grado di libertà e 5,9915{,}991 con 2.

python
gain(D, 4)                                         # 0.5409
delta([r for r in D if r[4] == "Full"], 3)         # 1.5

Errori tipici: calcolare i guadagni dei sottoalberi sull'insieme intero; non pesare per Nk/NN_k/N; gradi di libertà diversi da d−1d-1; dimenticare la foglia con il valore più frequente dopo la potatura.

Teoria collegata