Creare un albero decisionale

In questa unità, utilizzerai il treno di libreria YDF (Yggdrasil Decision Forest) e interpreterai un albero decisionale.

Questa unità si ispira al tutorial 🧭 YDF Getting Started.

Eliminatorie

Prima di studiare il set di dati:

  1. Crea un nuovo blocco note Colab.
  2. Installa la libreria YDF inserendo ed eseguendo la seguente riga di codice nel nuovo blocco note di Colab:
    !pip install ydf -U
    
  3. Importa le seguenti librerie:
    import ydf
    import numpy as np
    import pandas as pd
    

Il set di dati Palmer Penguins

Questo Colab utilizza il set di dati Palmer Penguins, che contiene le misurazioni delle dimensioni di tre specie di pinguini:

  • Sottogola
  • Gentoo
  • Adelia

Questo è un problema di classificazione: l'obiettivo è prevedere le specie di pinguini in base ai dati del set di dati dei pinguini di Palmer. Ecco i pinguini:

Tre diverse specie di pinguini.

Figura 16. Tre diverse specie di pinguini. Immagine di @allisonhorst

 

Il seguente codice chiama una funzione panda per caricare in memoria il set di dati Palmer Penguins:

path = "https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins.csv"
dataset = pd.read_csv(path)
label = "species"

# Display the first 3 examples.
dataset.head(3)

La seguente tabella formatta i primi tre esempi nel set di dati Palmer Penguins:

Tabella 3. I primi tre esemplari di Palmer Penguins

specie island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g genere anno
0 Adelia Türgersen 39,1 18,7 181,0 3750,0 uomo 2007
1 Adelia Türgersen 39,5 17,4 186,0 3.800,0 donna 2007
2 Adelia Türgersen 40,3 18.0 195,0 3250,0 donna 2007

Il set di dati completo contiene una combinazione di caratteristiche numeriche (ad esempio bill_depth_mm), categoriali (ad esempio island) e mancanti. A differenza delle reti neurali, le foreste decisionali supportano tutti questi tipi di funzionalità in modo nativo, quindi non devi eseguire la codifica one-hot, la normalizzazione o la funzionalità is_present aggiuntiva.

La seguente cella di codice suddivide il set di dati in un set di addestramento e di test:

# Use the ~20% of the examples as the testing set
# and the remaining ~80% of the examples as the training set.
np.random.seed(1)
is_test = np.random.rand(len(dataset)) < 0.2

train_dataset = dataset[~is_test]
test_dataset = dataset[is_test]

print("Training examples: ", len(train_dataset))
# >> Training examples: 272

print("Testing examples: ", len(test_dataset))
# >> Testing examples: 72

Addestramento di alberi decisionali con iperparametri predefiniti

Puoi addestrare il tuo primo albero decisionale con l'algoritmo di apprendimento CART (alberi di classificazione e regressione) (ovvero studente) senza specificare alcun iperparametro. Questo perché lo studente ydf.CartLearner fornisce buoni valori predefiniti dell'iperparametro. Scoprirai di più su come funziona questo tipo di modello più avanti nel corso.

model = ydf.CartLearner(label=label).train(train_dataset)

La chiamata precedente non specificava le colonne da utilizzare come funzionalità di input. Di conseguenza, viene utilizzata ogni colonna nel set di addestramento. Inoltre, nella chiamata non è stata specificata la semantica (ad esempio numerica, categoriale, testo) delle caratteristiche di input. Di conseguenza, la semantica delle caratteristiche viene dedotta automaticamente.

Richiama model.plot_tree() per visualizzare la struttura decisionale risultante:

model.plot_tree()

In Colab, puoi usare il mouse per visualizzare i dettagli di elementi specifici, come la distribuzione delle classi in ogni nodo.

un albero decisionale addestrato
con iperparametri predefiniti.

Figura 17. Un albero decisionale addestrato con iperparametri predefiniti.

Colab mostra che la condizione principale contiene 243 esempi. Tuttavia, potresti ricordare che il set di dati di addestramento conteneva 272 esempi. I restanti 29 esempi sono stati riservati automaticamente per la convalida e l'eliminazione degli alberi.

La prima condizione verifica il valore di bill_depth_mm. Le tabelle 4 e 5 mostrano la probabilità di specie diverse in base all'esito della prima condizione.

Tabella 4. Probabilità di esistenza di specie diverse se bill_depth_mm ≥ 42.3

Specie Probabilità
Adelie (rossa) 8%
Gentoo (blu) il 58%
Sottogola (verde) 36%

 

Tabella 5. Probabilità di esistenza di specie diverse se bill_depth_mm < 42.3

Specie Probabilità
Adelie (rossa) 97%
Gentoo (blu) 2%
Sottogola (verde) 0%

bill_depth_mm è una caratteristica numerica. Pertanto, è stato trovato il valore 42,3 utilizzando l'algoritmo della suddivisione esatta per la classificazione binaria con caratteristiche numeriche.

Se bill_depth_mm ≥ 42.3 è True, testiamo ulteriormente se flipper_length_mm ≥ 207.5 è in grado di separare quasi perfettamente Gentoos e Gentoos+Adelie.

Il codice seguente fornisce l'accuratezza dell'addestramento e del test del modello:

train_evaluation = model.evaluate(train_dataset)
print("train accuracy:", train_evaluation.accuracy)
# >> train accuracy:  0.9338

test_evaluation = model.evaluate(test_dataset)
print("test accuracy:", test_evaluation.accuracy)
# >> test accuracy:  0.9167

È raro, ma è possibile, che l'accuratezza del test sia superiore a quella dell'addestramento. In questo caso, il set di test potrebbe essere diverso dal set di addestramento. Tuttavia, questo non è il caso qui perché i dati di addestramento e test sono stati suddivisi in modo casuale. Una spiegazione più probabile è che il set di dati di test è molto piccolo (solo 72 esempi), per cui la stima dell'accuratezza è poco affidabile.

In pratica, per un set di dati così piccolo, sarebbe preferibile l'utilizzo della convalida incrociata, in quanto calcolerebbe valori delle metriche di valutazione più accurati. Tuttavia, in questo esempio, continuiamo con addestramento e test per motivi di semplicità.

Migliorare gli iperparametri del modello

Il modello consiste in un singolo albero decisionale addestrato con valori di iperparametri predefiniti. Per ottenere previsioni migliori, puoi:

  1. Utilizza uno studente più potente, ad esempio una foresta casuale o un modello di alberi potenziati con gradiente. Questi algoritmi di apprendimento verranno spiegati nella prossima pagina.

  2. Ottimizza l'iperparametro utilizzando le tue osservazioni e l'intuizione. La guida al miglioramento del modello può essere utile.

  3. Usa l'ottimizzazione degli iperparametri per testare automaticamente un numero elevato di possibili iperparametri.

Poiché non abbiamo ancora rilevato l'algoritmo degli alberi potenziati con gradiente e foresta casuale e, dato che il numero di esempi è troppo basso per eseguire l'ottimizzazione automatica degli iperparametri, migliorerai manualmente il modello.

L'albero decisionale mostrato sopra è piccolo e la foglia con 61 esempi contiene un mix di etichette Adelie e Chinstrap. Perché l'algoritmo non ha diviso ulteriormente questa foglia? Il simbolo "--" può essere visualizzato per due ragioni:

  • Potrebbe essere stato raggiunto il numero minimo di campioni per foglia (min_examples=5 per impostazione predefinita).
  • L'albero potrebbe essere stato diviso e poi potato per evitare un attacco eccessivo.

Riduci il numero minimo di esempi a 1 e visualizza i risultati:

model = ydf.CartLearner(label=label, min_examples=1).train(train_dataset)
model.plot_tree()

un albero decisionale addestrato con
min_examples=1.

Figura 18. Un albero decisionale addestrato con min_examples=1.

 

Il nodo foglia contenente 61 esempi è stato ulteriormente diviso più volte.

Per capire se l'ulteriore divisione del nodo è utile, valutiamo la qualità di questo nuovo modello sul set di dati di test:

print(model.evaluate(test_dataset).accuracy)
# >> 0.97222

La qualità del modello è aumentata con un'accuratezza del test che passa da 0,9167 a 0,97222. Questa modifica dell'iperparametro era una buona idea.

Precedente di una decisione sulle foreste

Continuando a migliorare gli iperparametri, potremmo raggiungere una precisione perfetta. Invece di questo processo manuale, possiamo addestrare un modello più potente, ad esempio una foresta casuale, e vedere se funziona meglio.

model = ydf.RandomForestLearner(label=label).train(pandas_train_dataset)
print("Test accuracy: ", model.evaluate(pandas_test_dataset).accuracy)
# >> Test accuracy: 0.986111

La precisione di una foresta casuale è migliore del nostro semplice albero. Nelle prossime pagine scoprirai il perché.

Utilizzo e limitazioni

Come accennato in precedenza, un singolo albero decisionale spesso ha una qualità inferiore rispetto ai moderni metodi di machine learning come foreste casuali, gradiente di alberi e reti neurali. Tuttavia, gli alberi decisionali sono comunque utili nei seguenti casi:

  • Come base semplice ed economica per valutare approcci più complessi.
  • Quando c'è un compromesso tra la qualità del modello e l'interpretabilità.
  • Come sostituto dell'interpretazione del modello di foreste decisionali, che il corso analizzerà più avanti.