L’albero delle decisioni e il machine learning

L’albero delle decisioni e il machine learning

Condividi con i tuoi amici...

Il punto di partenza di qualsiasi sistema o modello di apprendimento automatico è costituito dai dati che gli vengono forniti per poter fare previsioni o compiere azioni. I dati si dicono strutturati quando sono organizzati in forma tabulare in righe e colonne. Le singole righe rappresentano le istanze o elementi individuali, mentre i valori contenuti nelle colonne rappresentano gli attributi delle istanze.

Questi dati possono essere interrogati o recuperati utilizzando un linguaggio di programmazione chiamato SQL (Structured Query Language). Una ‘query’ SQL consente di estrarre un particolare sottoinsieme di dati basato su specifici attributi.

Da un punto di vista tecnico, una query SQL può apparire come segue:

SELECT attributo1, attributo2
FROM nomeTabella
WHERE attributo1 = valoreDesiderato
AND/OR attributo2 = valoreDesiderato;

In questo esempio, l’operatore SELECT viene utilizzato per specificare gli attributi (o le colonne) che si desidera recuperare. L’operatore FROM è utilizzato per definire la tabella da cui vengono recuperati i dati. Infine, l’operatore WHERE è utilizzato per filtrare i dati in base a specifiche condizioni.

Tuttavia, anche se le query SQL sono efficaci nell’interrogare i dati, non sono progettate per fare previsioni. Ad esempio, se si vuole fare una previsione sul valore di un certo attributo, ma i valori di altri attributi correlati non sono esattamente quelli presenti nel database, si possono incontrare difficoltà con SQL.

Ed è qui che entrano in gioco i metodi di apprendimento automatico, e in particolare i cosiddetti alberi decisionali.

Gli alberi decisionali

Un albero decisionale è un metodo di apprendimento automatico che consente di fare previsioni basate su dati storici. Questo viene fatto dividendo l’insieme di dati in sottoinsiemi più piccoli basati su alcune condizioni, in un processo chiamato “branching”. Questo processo di “branching” continua fino a quando non si è in grado di fare una previsione.

Per esempio, un albero decisionale potrebbe suddividere i dati in base all’età e al genere per prevedere l’insoddisfazione dei clienti in un’impresa di telecomunicazioni. Questo potrebbe aiutare l’impresa a identificare i fattori che contribuiscono all’insoddisfazione dei clienti e a formulare strategie appropriate per mitigarlo.

In questi casi, il dataset è caratterizzato da un certo numero di attributi di cui uno in particolare è detto attributo target perché i suoi valori rappresentano le classi con cui si vogliono etichettare le singole istanze.

Per esempio questa tabella mostra due istanze con quattro attributi. Abbigliamento rappresenta l’attributo target perché i suoi valori: Maglietta/Giacca assumono la funzione di etichette o classi a cui sono assegnate le rispettive istanze

TemperaturaUmiditàVelocità del ventoAbbigliamento
CaldoAltaDeboleMaglietta
FreddoBassaForteGiacca
Maglietta e giacca sono i valori dell’attributo target che rappresentano l’etichetta da assegnare alle singole istanze.

In un modello previsionale, dati in input i valori dei primi tre attributi si cerca di prevedere come output il valore del quarto (target).

Gli alberi decisionali sono una tecnica di apprendimento automatico supervisionato. Questo significa che si parte da un set di dati di addestramento, dove abbiamo vari esempi con associati i risultati (etichette), e cerchiamo di “apprendere” un modello che, dato un nuovo esempio, sia in grado di prevedere il risultato.

Supponiamo di avere un dataset di pazienti in un ospedale con diversi attributi (età, genere, condizioni pregresse, ecc) e vogliamo prevedere se un paziente è a rischio di ammalarsi di una certa malattia. Gli alberi decisionali si sviluppano seguendo una serie di domande basate su questi attributi. Ad esempio un albero potrebbe iniziare domandando se il paziente è di un certo genere, poi basandosi sull’età, e così via.

Quindi come facciamo a scegliere l’attributo su cui fare la domanda? Qui entra in gioco il concetto di entropia.

L’entropia in questo contesto è una misura dell’incertezza. Vogliamo scegliere l’attributo che riduca al massimo questa incertezza.

Se un attributo ha un alto livello di entropia, ad esempio, la metà dei pazienti sono maschi e l’altra metà sono femmine,questi dati non ci forniscono molte informazioni per prevedere la malattia.

Al contrario, se un attributo ha bassa entropia (ad esempio, il 90% dei pazienti con la malattia hanno più di 60 anni), questo attributo fornisce un significativo contributo alla previsione della malattia.

Da questa tabella emerge che l’attributo ‘genere’ non fornisce informazioni per fare previsioni sulla malattia:

AB …GenereMalattia
Maschiosi
Femminano
Femminasi
Femminasi
Maschiono
Maschiosi

infatti sia il campione dei malati che quello dei non malati hanno lo stesso rapporto di maschi e di femmine (50%-50%)

Sarebbe inefficiente iniziare un albero decisionale dividendo il dataset in due campioni rispetto al genere in quanto otterremmo due sottoinsiemi con le stesse informazioni:

AB …GenereMalattia
Femminano
Femminasi
Femminasi

AB …GenereMalattia
Maschiosi
Maschiono
Maschiosi

Consideriamo invece il caso della seguente tabella:

AetàGenereMalattia
> 60Maschiosi
< 60Femminano
> 60Femminasi
< 60Femminasi
< 60Maschiono
> 60Maschiosi

La divisione dei dati rispetto all’età aggiunge informazione in quanto mostra una tendenza maggiore ad ammalarsi con l’età. Infatti i 3/4 dei malati hanno più di 60 anni

AetàGenereMalattia
< 60Femminano
< 60Femminasi
< 60Maschiono

AetàGenereMalattia
> 60Maschiosi
> 60Femminasi
> 60Maschiosi

L’entropia di Shannon e il criterio di suddivisione

Una funzione che ci permette di quantificare l’informazione presente in un insieme di dati distribuiti in un certo modo è l’entropia di Shannon,

Il calcolo dell’entropia si basa sulla formula:

E(S) = -Σx P(x) log2 P(x)

Qui x rappresenta il singolo valore dell’attributo target e P(x) è la probabilità di ciascun valore dell’attributo data dal rapporto tra il numero di volte che quel valore è presente nei dati e il numero totale di dati intesi come numero di istanze o righe del database.

L’informazione guadagnata da una suddivisione viene calcolata sottraendo l’entropia ponderata dei sottoinsiemi risultanti dall’entropia dell’insieme iniziale, e rappresenta la riduzione di incertezza ottenuta grazie alla scelta dell’attributo:

Gain(S,A) = E(S)−∑v∈Valori(A) (∣Sv∣ / ∣S∣ × E(Sv))

Dove:

S è l’insieme di dati iniziale
A è l’attributo su cui stiamo considerando la divisione
Sv​ è l’insieme di dati dove l’attributo A ha il valore v
Valori(A) sono i diversi valori che l’attributo A può avere

|S| e |Sv| rappresentano la cardinalità dei due insiemi, in pratica il numero dei loro elementi.

Il calcolo viene effettuato per ogni possibile scelta dell’attributo A e si sceglie quello che fornisce un maggior guadagno in termini di informazione.

l’informazione guadagnata ci permette di scegliere l’attributo che riduce maggiormente l’entropia dell’insieme di dati.

Nei casi precedenti per calcolare l’entropia E(S) si devono calcolare i due valori P(malattia=si) e P(malattia=no)

P(malattia=si) = 4/6 4 casi su 6

P(malattia=no) = 2/6 2 casi su 6

inizialmente l’entropia dell’insieme è

E(S) = – (P(malattia=si) log2 P(malattia=si)) – (P(malattia=no) log2 P(malattia=no)) =

= – 4/6 log2 (4/6) – 2/6 log2 (2/6) = 0.91829

Consideriamo il caso della suddivisione per genere

∣Smaschio∣ = 3 istanze
∣Sfemmina∣ = 3 istanze
∣S∣ = 6 istanze totali
E(Smaschio) = – (P1(malattia=si) log2 P1(malattia=si)) – (P1(malattia=no) log2 P1(malattia=no))
E(Sfemmina) = – (P2(malattia=si) log2 P2(malattia=si)) – (P2(malattia=no) log2 P2(malattia=no))


dove P1 è la probabilità calcolata sui dati della tabella in cui genere=maschio
e P2 è la probabilità calcolata sui dati della tabella in cui genere=femmina

E(Smaschio) = – 2/3 log2 (2/3) – 1/3 log2 (1/3) = 0.91829
E(Sfemmina) = – 2/3 log2 (2/3) – 1/3 log2 (1/3) = 0.91829

Valutiamo il guadagno d’informazione dopo la divisione rispetto all’attributo genere

Gain(S,genere) = E(S) – ((∣Smaschio∣ / ∣S∣ × E(Smaschio)) + (∣Sfemmina∣ / ∣S∣ × E(Sfemmina))
= 0.91829 – ((3/6 x 0.91829) + (3/6 x 0.91829) = 0

Come si può vedere non c’è guadagno d’informazione.

Caso dei malati

∣Seta>60∣ = 3 istanze
∣Seta<60∣ = 3 istanze
∣S∣ = 6 istanze totali

E(Seta>60) = – (P1(malattia=si) log2 P1(malattia=si)) – (P1(malattia=no) log2 P1(malattia=no))
E(Seta<60) = – (P2(malattia=si) log2 P2(malattia=si)) – (P2(malattia=no) log2 P2(malattia=no))

Dove P1 è la probabilità calcolata sui dati della tabella in cui età > 60
e P2 è la probabilità calcolata sui dati della tabella in cui età < 60

E(Seta>60) = 0
E(Seta<60) = – 1/3 log2 (1/3) – 2/3 log2 (2/3) = 0.91829

Valutiamo il guadagno d’informazione dopo la divisione rispetto all’attributo età

Gain(S,eta) = E(S) – ((∣Seta>60∣ / ∣S∣ × E(Seta>60)) + (∣Seta<60∣ / ∣S∣ × E(Seta<60))) =
0.91829 – ((3/6 x 0) + (3/6 x 0.91829)) = 0.91829 – 0.91829 /2 = 0.45914

In questo caso dalla divisione dei dati si ottiene un guadagno informativo!

Esempio di costruzione di un albero delle decisioni

Prendiamo ad esempio un dataset che descrive il tipo di abbigliamento indossato da un gruppo di persone in base a tre attributi: temperatura, umidità dell’aria e velocità del vento. L’obiettivo è costruire un albero decisionale per classificare le istanze di dati nelle categorie di abbigliamento “giacca” e “maglietta”.

Supponiamo che il dataset sia il seguente:

TemperaturaUmiditàVelocità del ventoAbbigliamento
CaldoAltaDeboleMaglietta
CaldoAltaForteMaglietta
TiepidoAltaDeboleMaglietta
FreddoNormaleDeboleMaglietta
FreddoBassaDeboleGiacca
FreddoBassaForteGiacca
TiepidoBassaForteGiacca
CaldoNormaleDeboleMaglietta
CaldoBassaDeboleGiacca
FreddoNormaleForteGiacca
CaldoNormaleForteGiacca
TiepidoNormaleDeboleGiacca
TiepidoAltaForteMaglietta
TiepidoNormaleForteGiacca

Innanzitutto, per utilizzare l’entropia come criterio di divisione, dobbiamo calcolare l’entropia iniziale basata sulla variabile target, che in questo caso è “Abbigliamento”. L’entropia è definita come:

E(S)=− p+log⁡2(p+) − plog⁡2(p)

dove:

p+è la porzione di esempi positivi nella selezione (in questo caso, porzione di “Maglietta“)
p è la porzione di esempi negativi nella selezione (in questo caso, porzione di “Giacca”)
p log2(p) si pone a zero in caso di p=0

Una volta calcolata l’entropia iniziale, per ogni attributo, calcoleremo l’entropia dopo la divisione e il guadagno informativo

Gain(S,A) = E(S)−∑v∈Valori(A) (∣Sv∣ / ∣S∣ ×E(Sv))

L’attributo con il guadagno informativo maggiore sarà l’attributo rispetto al quale divideremo i dati.

L’entropia iniziale per il nostro set di dati, basata sulla variabile target “Abbigliamento”, è circa 0.9852, infatti vale:

E(S) = −p+log⁡2(p+)−p−log⁡2(p) = -6/14 log2 (6/14) – 8/14 log2 (8/14) = 0.9852

Ora, calcoleremo l’entropia e il guadagno informativo per ogni attributo:

Temperatura
Umidità
Velocità del vento

Calcolo per l’attributo temperatura

Iniziamo con l’attributo “Temperatura”. Ci sono tre possibili valori : caldo, tiepido, freddo
bisogna calcolare l’entropia per tutti questi valori

E(Scaldo)=− p+log⁡2(p+) − plog⁡2(p) = 0.97095
E(Stiepido)=− p+log⁡2(p+) − plog⁡2(p) = 0.97095
E(Sfreddo)=− p+log⁡2(p+) − plog⁡2(p) = 0.81128

infatti osservando le suddivisioni in ragione della temperatura otteniamo i valori di p e p+ nei tre casi da sostituire nelle formule precedenti

5 campioni per caldo di cui 2 con giacca e 3 con maglietta -> p = 2/5 p+ = 3/5

TemperaturaUmiditàVelocità del ventoAbbigliamento
CaldoAltaDeboleMaglietta
CaldoAltaForteMaglietta
CaldoNormaleDeboleMaglietta
CaldoBassaDeboleGiacca
CaldoNormaleForteGiacca

5 campioni per tiepido di cui 3 con giacca e 2 maglietta -> p = 3/5 p+ = 2/5

TemperaturaUmiditàVelocità del ventoAbbigliamento
TiepidoAltaDeboleMaglietta
TiepidoBassaForteGiacca
TiepidoNormaleDeboleGiacca
TiepidoAltaForteMaglietta
TiepidoNormaleForteGiacca

4 campioni per freddo di cui 3 con giacca e 1 con maglietta -> p = 3/4 p+ = 1/4

TemperaturaUmiditàVelocità del ventoAbbigliamento
FreddoNormaleDeboleMaglietta
FreddoBassaDeboleGiacca
FreddoBassaForteGiacca
FreddoNormaleForteGiacca

Gain(S,A) = E(S)−∑v∈Valori(A) (∣Sv∣ / ∣S∣ × E(Sv))

Gain(S,Temperatura) = 0.9852 – ((5/14)E(Scaldo) + (5/14)E(Stiepido) + (4/14)*E(Sfreddo)) =
0.9852 – 0.9253 = 0.0599

Il guadagno informativo ottenuto dividendo il set di dati rispetto all’attributo “Temperatura” è circa 0.0599

Per nessuno dei tre valori di temperatura si è raggiunto un nodo puro in quanto per tutti i valori vi è un misto di risultati (giacca / maglietta).

Calcolo per l’attributo umidità

Proseguiamo ora calcolando il guadagno informativo per l’attributo “Umidità“. Ci sono tre valori possibili: alta, normale, bassa

bisogna calcolare l’entropia per tutti questi valori

E(Salta)=− p+log⁡2(p+) − plog⁡2(p−) = 0
E(Snormale)=− p+log⁡2(p+) − plog⁡2(p−) = 0.91829
E(Sbassa)=− p+log⁡2(p+) − plog⁡2(p−) = 0

infatti

4 campioni per umidità alta tutti con maglietta -> p = 0 p+ = 4/4

TemperaturaUmiditàVelocità del ventoAbbigliamento
CaldoAltaDeboleMaglietta
CaldoAltaForteMaglietta
TiepidoAltaDeboleMaglietta
TiepidoAltaForteMaglietta

6 campioni per umidità normale di cui 4 con giacca e 2 con maglietta -> p= 4/6 e p+ = 2/6

TemperaturaUmiditàVelocità del ventoAbbigliamento
FreddoNormaleDeboleMaglietta
CaldoNormaleDeboleMaglietta
FreddoNormaleForteGiacca
CaldoNormaleForteGiacca
TiepidoNormaleDeboleGiacca
TiepidoNormaleForteGiacca

4 campioni per umidità bassa tutti con giacca -> p = 4/4 p+ = 0

TemperaturaUmiditàVelocità del ventoAbbigliamento
FreddoBassaDeboleGiacca
FreddoBassaForteGiacca
TiepidoBassaForteGiacca
CaldoBassaDeboleGiacca

Gain(S,A) = E(S)−∑v∈Valori(A) (∣Sv∣ \ ∣S∣ × E(Sv))

Gain(S,umidità) = 0.9852 – ((4/14)E(Salta) + (6/14)E(Snormale) + (4/14)E(Sbassa)) = 0.9852 – (6/14)E(Snormale) = 0.9852 – 0.39355 = 0.5917

Il guadagno informativo ottenuto dividendo il set di dati rispetto all’attributo “Umidità” è circa 0.5917

Si può già vedere che nei casi di umidità alta e umidità bassa si raggiungono nodi puri in quanto il risultato è omogeneo in entrambi i casi: solo giacca per umidità alta e solo maglietta per umidità bassa. Siamo in presenza di una “foglia” in emtrambi i casi.

Calcolo per l’attributo velocità del vento

Procediamo ora calcolando il guadagno informativo per l’attributo “Velocità del vento“. Ci sono due valori possibili: debole, forte

bisogna calcolare l’entropia per tutti questi valori

E(Sdebole)=− p+log⁡2(p+) − plog⁡2(p) = 0.98522
E(Sforte)=− p+log⁡2(p+) − plog⁡2(p) = 0.86312

infatti

7 campioni per vento debole di cui 3 con giacca e 4 maglietta -> p = 3/7 p+ = 4/7

TemperaturaUmiditàVelocità del ventoAbbigliamento
CaldoAltaDeboleMaglietta
TiepidoAltaDeboleMaglietta
FreddoNormaleDeboleMaglietta
FreddoBassaDeboleGiacca
CaldoNormaleDeboleMaglietta
CaldoBassaDeboleGiacca
TiepidoNormaleDeboleGiacca

7 campioni per vento forte di cui 5 con giacca e 2 maglietta -> p = 5/7 p+ = 2/7

TemperaturaUmiditàVelocità del ventoAbbigliamento
CaldoAltaForteMaglietta
FreddoBassaForteGiacca
TiepidoBassaForteGiacca
FreddoNormaleForteGiacca
CaldoNormaleForteGiacca
TiepidoAltaForteMaglietta
TiepidoNormaleForteGiacca

Gain(S,A) = E(S) − ∑v∈Valori(A) (∣Sv∣ / ∣S∣ × E(Sv))

Gain(S,vento) = 0.9852 – ((7/14)E(Sdebole) + (7/14)E(Sforte) = 0.9852 – (0.98522 / 2 + 0.86312 / 2) =
= 0.9852 – 0.92417 = 0,061

Il guadagno informativo ottenuto dividendo il set di dati rispetto all’attributo “Velocità del vento” è di circa 0.061. In questo caso non si raggiunge un nodo puro

Riassumendo i guadagni informativi per ciascun attributo in termini di entropia sono i seguenti:

Temperatura: 0.0599
Umidità: 0.5917
Velocità del vento: 0.0610

L’attributo “Umidità” ha il guadagno informativo più alto, quindi sarà il primo attributo rispetto al quale divideremo il nostro set di dati nella costruzione dell’albero delle decisioni.

Ecco come si distribuiscono i dati rispetto ai valori dell’attributo “Umidità”:

Umidità Alta:
Maglietta: 4
Giacca: 0
Umidità Normale:
Maglietta: 2
Giacca: 4
Umidità Bassa:
Maglietta: 0
Giacca: 4

Dalla distribuzione, possiamo vedere che quando l’umidità è “Alta”, l’abbigliamento scelto è sempre “Maglietta”. Allo stesso modo, quando l‘umidità è “Bassa”, l’abbigliamento scelto è sempre “Giacca”. Tuttavia, quando l’umidità è “Normale”, vi è una divisione tra “Maglietta” e “Giacca”.

Quindi, per il nodo dell’umidità “Normale”, dobbiamo eseguire ulteriori suddivisioni basate sugli attributi rimanenti. Ciò significa che dobbiamo calcolare il guadagno informativo per “Temperatura” e “Velocità del vento” usando solo il sottoinsieme di dati con umidità “Normale”.

Sottoinsieme “Umidità normale”

Calcoliamo il guadagno informativo per questi due attributi nel sottoinsieme “Umidità Normale”:

TemperaturaUmiditàVelocità del ventoAbbigliamento
FreddoNormaleDeboleMaglietta
CaldoNormaleDeboleMaglietta
FreddoNormaleForteGiacca
CaldoNormaleForteGiacca
TiepidoNormaleDeboleGiacca
TiepidoNormaleForteGiacca

Calcoliamo l’entropia associata al sottoinsieme rispetto ai risultati (Maglietta/Giacca)
E(S)=− p+log⁡2(p+) − plog⁡2(p) = 0.91829

dove p+ = 2/6 e p = 4/6 (infatti ci sono due casi Maglietta e 4 casi Giacca su 6)

Calcoliamo il guadagno informativo rispetto alla temperatura (Freddo/caldi/tiepido)

Calcolo per l’attributo temperatura (sottoinsieme Umidità normale)

bisogna calcolare l’entropia per tutti questi valori della temperatura

E(Sfreddo)=− p+log⁡2(p+) − plog⁡2(p−) = 1
E(Scaldo)=− p+log⁡2(p+) − plog⁡2(p−) = 1
E(Stiepido)=− p+log⁡2(p+) − plog⁡2(p−) = 0

infatti

2 campioni per freddo di cui uno associato a giacca e l’altro a maglietta -> p = 1/2 p+ = 1/2

TemperaturaUmiditàVelocità del ventoAbbigliamento
FreddoNormaleDeboleMaglietta
FreddoNormaleForteGiacca

2 campioni per caldo di cui uno associato a giacca e l’altro a maglietta -> p = 1/2 p+ = 1/2

TemperaturaUmiditàVelocità del ventoAbbigliamento
CaldoNormaleDeboleMaglietta
CaldoNormaleForteGiacca

2 campioni per Tiepido entrambi associati a giacca -> p = 1 p+ = 0

TemperaturaUmiditàVelocità del ventoAbbigliamento
TiepidoNormaleDeboleGiacca
TiepidoNormaleForteGiacca

Il guadagno informativo rispetto alla temperatura è

Gain(S,A) = E(S)−∑v∈Valori(A) (∣Sv∣ \ ∣S∣ × E(Sv))

Gain(S,temperatura) = 0.91829 – ((2/6)E(Sfreddo) + (2/6)E(Scaldo) + E(Stiepido)) = 0.91829 – 2/3 =
= 0.91829 – 0.66667 = 0.25162

Calcolo per l’attributo velocità del vento (sottoinsieme Umidità normale)

Calcoliamo il guadagno informativo rispetto alla velocità del vento (debole / forte)

bisogna calcolare l’entropia per questi due valori della velocità del vento

E(Sdebole)=−p+log⁡2(p+)−plog⁡2(p) = 0.91829
E(Sforte)=−p+log⁡2(p+)−plog⁡2(p) = 0

infatti

3 campioni per vento debole di cui 2 con maglietta e 1 con giacca -> p = 1/3 p+ = 2/3

TemperaturaUmiditàVelocità del ventoAbbigliamento
FreddoNormaleDeboleMaglietta
CaldoNormaleDeboleMaglietta
TiepidoNormaleDeboleGiacca

3 capioni per vento forte tutti associati a giacca -> p = 1 p+ = 0

TemperaturaUmiditàVelocità del ventoAbbigliamento
FreddoNormaleForteGiacca
CaldoNormaleForteGiacca
TiepidoNormaleForteGiacca

Il guadagno informativo rispetto alla velocità del vento è

Gain(S,A) = E(S) − ∑v∈Valori(A)(∣Sv∣ \ ∣S∣ × E(Sv))

Gain(S,vento) = 0.91829 – ((3/6)E(Sdebole) + (3/6)E(Sforte)) = 0.91829 – 0.91829/2
= 0.91829 – 0.45914 = 0.45915

In sintesi per il sottoinsieme di dati con “Umidità Normale”, i guadagni informativi sono:

Temperatura: 0.2516
Velocità del vento: 0.4591

La “Velocità del vento” ha il guadagno informativo più alto tra i due, quindi sarà il prossimo attributo rispetto al quale divideremo il nostro set di dati nel sottoinsieme “Umidità Normale”.

Ora vediamo come si distribuiscono i dati rispetto ai valori dell’attributo “Velocità del vento” nel sottoinsieme “Umidità Normale”.

Per il sottoinsieme di dati con “Umidità Normale”, la distribuzione rispetto alla “Velocità del vento” è la seguente:

Vento Debole:
Maglietta: 2
Giacca: 1
Vento Forte:
Maglietta: 0
Giacca: 3

Dalla distribuzione, possiamo vedere che quando la velocità del vento è “Forte“, l’abbigliamento scelto è sempre “Giacca”. Tuttavia, quando la velocità del vento è “Debole”, c’è una divisione tra “Maglietta” e “Giacca”. Quindi, per il nodo del vento “Debole”, potremmo considerare ulteriori suddivisioni basate sull’attributo rimanente, che è “Temperatura”.

Tuttavia, prima di procedere, possiamo già disegnare una parte dell’albero delle decisioni basata su quanto abbiamo dedotto finora. Ecco come appare in modo schematico l’albero delle decisioni finora:

Umidità
|
|– Alta: Maglietta
|
|– Bassa: Giacca
|
|– Normale
——|
——|– Velocità del vento
———|
———|– Debole: ?
———|
———|– Forte: Giacca

Il “?” indica che dobbiamo ancora determinare come suddividere ulteriormente i dati per il nodo “Vento Debole” sotto “Umidità Normale”.

Proseguiamo ora analizzando la distribuzione dei dati rispetto all’attributo “Temperatura” nel sottoinsieme “Velocità del vento Debole” e “Umidità Normale”.

TemperaturaUmiditàVelocità del ventoAbbigliamento
FreddoNormaleDeboleMaglietta
CaldoNormaleDeboleMaglietta
TiepidoNormaleDeboleGiacca

Per il sottoinsieme di dati con “Umidità Normale” e “Velocità del vento Debole”, la distribuzione rispetto all’attributo “Temperatura” è la seguente:

Temperatura Calda:
Maglietta: 1
Giacca: 0
Temperatura Tiepida:
Maglietta: 0
Giacca: 1
Temperatura Fredda:
Maglietta: 1
Giacca: 0

Dalla distribuzione, possiamo dedurre che:

Quando la temperatura è “Calda” o “Fredda”, l’abbigliamento scelto è sempre “Maglietta”.
Quando la temperatura è “Tiepida”, l’abbigliamento scelto è “Giacca”.

Ora possiamo completare il nostro albero delle decisioni:

CLICCA SULL’IMMAGINE PER INGRANDIRLA

In altre parole:

Se l'umidità è bassa, l'abbigliamento consigliato è una giacca.
Se l'umidità è alta, l'abbigliamento consigliato è una maglietta.
Se l'umidità è normale, allora:
    Se la velocità del vento è forte, l'abbigliamento consigliato è una giacca.
    Se la velocità del vento è debole, allora:
        Se la temperatura è calda, l'abbigliamento consigliato è una maglietta.
        Se la temperatura è tiepida, l'abbigliamento consigliato è una giacca.
        Se la temperatura è fredda, l'abbigliamento consigliato è una maglietta.

Questo albero delle decisioni ci fornisce una guida su quale abbigliamento scegliere in base ai tre attributi forniti.

Procedimento per creare l’albero decisionale

Lo pseudocodice per un algoritmo di albero decisionale può apparire come segue:

Se il nodo corrente è “puro” (cioè contiene solo esempi di una singola classe), ETICHETTALO con quella classe e TERMINA.
Altrimenti, SCEGLI l’attributo MIGLIORE per dividere i dati.
Crea un NODO decisionale che DIVIDE i dati sull’attributo MIGLIORE.
RIPETI il processo per ciascun sottoinsieme di dati.

Alberi multi-way e alberi binari

Nel precedente esempio l’albero decisionale prevede divisioni multi-way cioè i nodi possono avere più di due figli e sono tanti quanti sono i valori diversi di un attributo. Nella maggior parte delle librerie di machine learning, inclusa scikit-learn gli alberi decisionali sono binari, dividono sempre i dati in due gruppi ad ogni nodo. Quindi in corrispondenza di attributi con più valori diversi avvengono degli accorpamenti dei dati e si ottiene un albero più profondo.

Il modulo sklearn.tree

sklearn.tree è un modulo della libreria scikit-learn che fornisce algoritmi per la modellazione e l’analisi di dati strutturati come alberi di decisione.

Ecco alcune delle principali funzionalità e classi fornite dal modulo sklearn.tree:

DecisionTreeClassifier: Questa è la classe principale utilizzata per creare alberi di decisione per problemi di classificazione. Offre vari parametri come il criterio (entropia, indice di Gini), la profondità massima dell’albero, e altri per controllare la crescita dell’albero.

DecisionTreeRegressor: Questa classe è utilizzata per problemi di regressione con alberi di decisione. Invece di prevedere una classe, prevede un valore continuo.

export_text: Una funzione che permette di esportare l’albero in formato testuale. Questo può essere utile per una rapida ispezione dell’albero.

plot_tree: Una funzione per visualizzare l’albero di decisione. È un modo semplice e diretto per ottenere una rappresentazione visiva dell’albero senza dover ricorrere ad altre librerie di visualizzazione.

export_graphviz: Questa funzione è utilizzata per esportare l’albero in formato Graphviz, che può poi essere utilizzato da strumenti esterni (come il software Graphviz) per generare una rappresentazione visiva dell’albero.

Gli alberi di decisione sono modelli popolari nella scienza dei dati e nel machine learning perché sono intuitivi, facilmente interpretabili e possono gestire sia dati numerici che categorici. Tuttavia, tendono ad avere un’elevata varianza e possono sovradattarsi facilmente ai dati di addestramento. Per questo motivo, spesso vengono utilizzati come blocchi di costruzione per modelli più complessi come le foreste casuali (Random Forests) o gli alberi potenziati (Boosted Trees).

Codice python per realizzare un albero binario dai dati d’esempio

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree

# Creazione del DataFrame
data = {
    'Temperatura': ['Caldo', 'Caldo', 'Tiepido', 'Freddo', 'Freddo', 'Freddo', 'Tiepido', 'Caldo', 'Caldo', 'Freddo', 'Caldo', 'Tiepido', 'Tiepido', 'Tiepido'],
    'Umidità': ['Alta', 'Alta', 'Alta', 'Normale', 'Bassa', 'Bassa', 'Bassa', 'Normale', 'Bassa', 'Normale', 'Normale', 'Normale', 'Alta', 'Normale'],
    'Velocità del vento': ['Debole', 'Forte', 'Debole', 'Debole', 'Debole', 'Forte', 'Forte', 'Debole', 'Debole', 'Forte', 'Forte', 'Debole', 'Forte', 'Forte'],
    'Abbigliamento': ['Maglietta', 'Maglietta', 'Maglietta', 'Maglietta', 'Giacca', 'Giacca', 'Giacca', 'Maglietta', 'Giacca', 'Giacca', 'Giacca', 'Giacca', 'Maglietta', 'Giacca']
}

df = pd.DataFrame(data)

# Trasformazione dei dati categorici in numeri usando LabelEncoder
label_encoders = {}
for column in df.columns:
    le = LabelEncoder()
    df[column] = le.fit_transform(df[column])
    label_encoders[column] = le


# Separazione delle features e del target
X = df.drop('Abbigliamento', axis=1)
y = df['Abbigliamento']

# Creazione e addestramento dell'albero delle decisioni usando l'entropia come criterio (di nuovo)
clf_entropy_corrected = DecisionTreeClassifier(criterion='entropy')
clf_entropy_corrected.fit(X, y)

# Visualizzazione dell'albero delle decisioni corretto basato sull'entropia
plt.figure(figsize=(15, 10))
plot_tree(clf_entropy_corrected, filled=True, feature_names=X.columns, class_names=['Giacca', 'Maglietta'], rounded=True)
plt.show()

OUTPUT

Esempio: Individui a rischio infarto

Si consideri un dataset in formato CSV che contiene i dati di individui con vari attributi come età, sesso, angina, presenza di dolore toracico, pressione del sangue, colesterolo, glicemia, etc.. ed infine l’attributo target: infarto (si/no)

Mostriamo a titolo d’esempio un estratto del dataset già codificato numericamente:

Codice python per realizzare l’albero decisionale


import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
import matplotlib.pyplot as plt

# Let's read the CSV file
data = pd.read_csv('dati.csv')

# Display the first few rows of the data to understand its structure

# Splitting data into features and target
X = data.drop('output', axis=1)
y = data['output']

# Create the decision tree classifier with entropy criterion
clf = DecisionTreeClassifier(criterion='entropy', random_state=0)
clf = clf.fit(X, y)

# Plot the decision tree
plt.figure(figsize=(20,10))
tree.plot_tree(clf, feature_names=X.columns, class_names=["0", "1"], filled=True)
plt.show()

L’albero decisionale che otteniamo ha la struttura di quello mostrato all’inizio dell’articolo: