Presumo che l'entropia sia stata menzionata nel contesto della costruzione di alberi decisionali .
Per illustrare, immagina il compito di imparare a classificare i nomi di battesimo in gruppi maschili / femminili. Viene fornito un elenco di nomi ciascuno etichettato con uno m
o f
, vogliamo imparare un modello che si adatta ai dati e che può essere utilizzato per prevedere il genere di un nuovo nome invisibile.
name gender
----------------- Now we want to predict
Ashley f the gender of "Amro" (my name)
Brian m
Caroline f
David m
Il primo passo è decidere quali caratteristiche dei dati sono rilevanti per la classe target che vogliamo prevedere. Alcune caratteristiche di esempio includono: prima / ultima lettera, lunghezza, numero di vocali, termina con una vocale, ecc. Quindi, dopo l'estrazione delle caratteristiche, i nostri dati sembrano:
# name ends-vowel num-vowels length gender
# ------------------------------------------------
Ashley 1 3 6 f
Brian 0 2 5 m
Caroline 1 4 8 f
David 0 2 5 m
L'obiettivo è costruire un albero decisionale . Un esempio di un albero sarebbe:
length<7
| num-vowels<3: male
| num-vowels>=3
| | ends-vowel=1: female
| | ends-vowel=0: male
length>=7
| length=5: male
praticamente ogni nodo rappresenta un test eseguito su un singolo attributo e andiamo a sinistra oa destra a seconda del risultato del test. Continuiamo a attraversare l'albero fino a raggiungere un nodo foglia che contiene la previsione della classe ( m
o f
)
Quindi, se eseguiamo il nome Amro su questo albero, iniziamo testando " è la lunghezza <7? " E la risposta è sì , quindi scendiamo quel ramo. Dopo il ramo, il prossimo test " è il numero di vocali <3? " Restituisce nuovamente vero . Questo porta a un nodo foglia etichettato m
, e quindi la previsione è maschio (che mi capita di essere, quindi l'albero ha previsto correttamente il risultato ).
L'albero decisionale è costruito dall'alto verso il basso , ma la domanda è: come scegliere quale attributo suddividere in ciascun nodo? La risposta è trovare la funzione che divide meglio la classe target nei nodi figlio più puri possibili (ovvero: nodi che non contengono una combinazione di nodi maschio e femmina, piuttosto nodi puri con una sola classe).
Questa misura di purezza è chiamata informazione . Rappresenta la quantità prevista di informazioni che sarebbero necessarie per specificare se una nuova istanza (nome) deve essere classificata maschio o femmina, dato l'esempio che ha raggiunto il nodo. Lo calcoliamo in base al numero di classi maschili e femminili nel nodo.
L'entropia invece è una misura dell'impurità (il contrario). È definito per una classe binaria con valoria
/b
come:
Entropy = - p(a)*log(p(a)) - p(b)*log(p(b))
Questa funzione di entropia binaria è illustrata nella figura seguente (la variabile casuale può assumere uno di due valori). Raggiunge il massimo quando la probabilità lo è p=1/2
, nel senso che p(X=a)=0.5
o allo stesso modo p(X=b)=0.5
con una probabilità del 50% / 50% di essere uno a
o b
(l'incertezza è al massimo). La funzione entropia è al minimo zero quando la probabilità è p=1
o p=0
con completa certezza ( p(X=a)=1
o p(X=a)=0
rispettivamente, quest'ultima implica p(X=b)=1
).
Naturalmente la definizione di entropia può essere generalizzata per una variabile casuale discreta X con esiti N (non solo due):
(il log
nella formula di solito è preso come logaritmo alla base 2 )
Tornando al nostro compito di classificazione dei nomi, diamo un'occhiata a un esempio. Immagina ad un certo punto durante il processo di costruzione dell'albero, stavamo considerando la seguente divisione:
ends-vowel
[9m,5f] <--- the [..,..] notation represents the class
/ \ distribution of instances that reached a node
=1 =0
------- -------
[3m,4f] [6m,1f]
Come puoi vedere, prima della divisione avevamo 9 maschi e 5 femmine, cioè P(m)=9/14
e P(f)=5/14
. Secondo la definizione di entropia:
Entropy_before = - (5/14)*log2(5/14) - (9/14)*log2(9/14) = 0.9403
Quindi lo confrontiamo con l'entropia calcolata dopo aver considerato la divisione guardando due rami figlio. Nel ramo sinistro di ends-vowel=1
, abbiamo:
Entropy_left = - (3/7)*log2(3/7) - (4/7)*log2(4/7) = 0.9852
e il ramo giusto di ends-vowel=0
, abbiamo:
Entropy_right = - (6/7)*log2(6/7) - (1/7)*log2(1/7) = 0.5917
Combiniamo le entropie sinistra / destra usando il numero di istanze giù per ciascun ramo come fattore di peso (7 istanze sono andate a sinistra e 7 istanze sono andate a destra) e otteniamo l'entropia finale dopo la divisione:
Entropy_after = 7/14*Entropy_left + 7/14*Entropy_right = 0.7885
Ora confrontando l'entropia prima e dopo la divisione, otteniamo una misura del guadagno di informazioni o quante informazioni abbiamo ottenuto facendo la divisione usando quella particolare funzione:
Information_Gain = Entropy_before - Entropy_after = 0.1518
È possibile interpretare il calcolo di cui sopra come segue: eseguendo la divisione con la end-vowels
funzione, siamo stati in grado di ridurre l'incertezza nel risultato della previsione del sottoalbero di una piccola quantità di 0,1518 (misurata in bit come unità di informazione ).
Su ciascun nodo dell'albero, questo calcolo viene eseguito per ogni caratteristica e la caratteristica con il maggior guadagno di informazioni viene scelta per la divisione in modo avido (favorendo così le caratteristiche che producono divisioni pure con bassa incertezza / entropia). Questo processo viene applicato in modo ricorsivo dal nodo radice verso il basso e si interrompe quando un nodo foglia contiene istanze tutte aventi la stessa classe (non è necessario dividerlo ulteriormente).
Nota che ho ignorato alcuni dettagli che esulano dallo scopo di questo post, incluso come gestire le caratteristiche numeriche , i valori mancanti , gli alberi di overfitting e potatura , ecc.