
Il primo algoritmo boosting creato e che ebbe un grande successo è stato l’AdaBoost, quello che abbiamo visto nei precedenti articoli.
In questa sede ci concentriamo su un altro algoritmo che rientra nella famiglia Boosting, definito Gradient Boosting, una tecnica che attira l’attenzione per la sua velocità e accuratezza di previsione, specialmente con dati grandi e complessi.
Ensemble e Boosting
Il principio base di un algoritmo Gradient Boosting è che è un modello ensemble, ossia si basa su una combinazione di singoli modelli semplici (detti weak learner) che insieme creano un nuovo modello più potente (chiamato strong learner).
Il modo in cui questa combinazione viene fatta viene definita dalla tecnica boosting, come parte del suo nome, perché inizia inserendo un modello iniziale (ad esempio un albero o una regressione lineare) nei dati.
In seguito, viene creato un secondo modello in sequenza, che si concentra sulla previsione accurata dei casi in cui il primo modello ha prestazioni scarse. La combinazione di questi due modelli dovrebbe essere migliore di entrambi i modelli presi singolarmente.
Quindi questo processo di boosting viene ripetuto molte volte. Ogni modello successivo tenta di correggere le carenze dell’insieme boosting combinato di tutti i modelli precedenti.
Algoritmo Gradient Boosting
Secondo wikipedia,
Il Gradient Boosting è una tecnica di apprendimento automatico per problemi di regressione e classificazione, che produce un modello di previsione sotto forma di un insieme di modelli di previsione deboli, in genere alberi decisionali (vedi fonte inglese).
In linea generare, l’algoritmo Gradient Boosting ragiona al contrario della maggior parte degli algoritmi che abbiamo visto fin’ora.
Anziché puntare a prevedere il risultato della variabile target che vogliamo prevedere, si prefigge di prevedere gli errori del modello. Questi errori vengono stimati dai residui, ossia dalla differenza tra il valore realmente osservato e il valore previsto.
I residui vengono calcolati da alberi di regressione a più di un livello di profondità, a differenza dell’Adaboost, che si avvale di decision stump, ossia alberi decisionali ad un livello di profondità.
Una volta calcolati i residui, il Gradient Boosting si avvale di un altro modello (solitamente sempre un albero di regressione) per prevedere i nuovi residui.
E così via ad ogni iterazione: il modello punta a stimare i residui che, via via, si riducono progressivamente.
Alla conclusione dell’algoritmo, che avviene dopo un certo numero di stimatori, l’errore complessivo del modello è ridotto rispetto l’inizio.
Vengono considerati tutti i risultati dei modelli in precedenza utilizzati che, pian piano, migliorano le performance del modello finale. Anche l’accuratezza del training set aumenta di conseguenza.
Due parametri fondamentali: il numero di alberi e il Learning Rate
Quando si implementa un algoritmo Gradient Boosting si devono tenere a mente due parametri da cui dipenderà l’accuratezza del modello: la scelta del numero di alberi da utilizzare e il tasso di apprendimento.
Il primo è abbastanza semplice: corrisponde semplicemente al numero di alberi che saranno adattati in serie per correggere gli errori di predizione.
Il tasso di apprendimento, detto anche Learning Rate (LR), corrisponde alla velocità con cui l’errore viene corretto da ciascun albero al successivo ed è un semplice moltiplicatore che ricade nell’intervallo ]0,1] (0 escluso e 1 incluso).
Ad esempio, se la previsione corrente per un campione particolare è 0,2 e l’albero successivo prevede che dovrebbe effettivamente essere 0,8, la correzione sarebbe + 0,6. A un tasso di apprendimento di 1, la previsione aggiornata sarebbe esattamente la 0,2 + 1 * (0,6) = 0,8, mentre una velocità di apprendimento di 0,1 aggiornerebbe la previsione a 0,2 + 0,1*(0,6) = 0,26.
Vari studi consigliano di impostare un learning rate basso piuttosto che alto in modo da ridurre la varianza complessiva del modello finale.
Esistono anche altri parametri da definire, come la profondità massima degli alberi, campioni minimi per dividere un nodo e i campioni minimi in un nodo foglia.
Questi parametri possono anche avere un grande impatto dopo aver stabilito una combinazione efficace di numero degli alberi / tasso di apprendimento, ma nel processo tendono ad essere definiti in un secondo momento.
Come regola generale, ad esempio, utilizzare l’80-90% dei dati in ogni fase e mantenere gli alberi relativamente poco profondi (profondità massima tra 2-5 livelli) tende ad essere abbastanza efficace nella maggior parte dei casi.
Principio di funzionamento dell’algoritmo Gradient Boosting per problemi di regressione
Come anticipato, l’algoritmo Gradient Boosting è utilizzabile sia per problemi di classificazione che di regressione. In questo esempio vedremo un esempio del secondo tipo in 7 step, per comprendere più in dettaglio come l’algoritmo funziona.
Supponiamo di voler cercare di prevedere il prezzo di una casa data la loro età, metratura e posizione.
Step 1: Calcola la media della variabile target
Quando affrontiamo i problemi di regressione, iniziamo con una foglia che è il valore medio della variabile che vogliamo prevedere. Questa foglia verrà utilizzata come base per avvicinarsi alla soluzione corretta nelle fasi successive.
Step 2: Calcola i residui
Per ogni campione, calcoliamo il valore residuo, ossia la differenza tra il valore osservato e quello previsto:
residuo = valore osservato – valore previsto
Nel nostro esempio, il valore previsto è uguale alla media calcolata nel passaggio precedente e il valore effettivo può essere trovato nella colonna dei prezzi di ciascun campione. Dopo aver calcolato i residui, otteniamo la seguente tabella.
Step 3: Costruisci un albero di regressione
Successivamente, costruiamo un albero con l’obiettivo di prevedere i residui. In altre parole, ogni foglia conterrà una previsione sul valore del residuo (non sull’etichetta desiderata).
Gli alberi sono costruiti, scegliendo i migliori punti di divisione in base ai punteggi di purezza come Gini o per ridurre al minimo la funzione di costo.
Se dovessimo calcolare semplicemente l’albero di regressione ci troveremmo in una situazione simile alla seguente:
Il precedente albero, che non calcola i residui, è composto da 2 nodi e 3 foglie. I nodi si riconoscono dalla caratteristica inclusa nella prima riga (Metri_q e Anni). L’informazione mse indica l’errore quadratico medio (mean squared error, mse), samples il numero di campioni che sono suddivisi nell’albero, e value indica il valore di prezzo della casa.
Quest’ultimo attributo rappresenta la media dei prezzi che rientrano in tale foglia: ad esempio, se consideriamo l’ultimo nodo foglia in basso a sinistra che ha value = 168,5, vediamo che esso considera le case minori di 185 metri quadri che hanno meno di 5 anni di età.
I campioni che rispettano queste due condizioni sono il primo (175), il quarto (164), il quinto (150) e il settimo record (185). La media di questi valori fa appunto 168,5 ((175 + 164 + 150 + 185) / 4).
A noi però serve il valore dei residui di ogni foglia. Come li calcoliamo?
Semplice: posizionando i valori dei residui trovati al punto precedente all’interno delle foglie cui appartengono. Se per una foglia ho più di un residuo, come capita per le foglie al livello di profondità due dell’albero, calcolerò la media dei residui dei campioni che vi rientreranno.
In sostanza avremo:
I valori trovati alla foglia 1 e 2 rappresentano una media dei residui.
Quindi il residuo medio per la foglia 1 è pari a: (-28,428 -39,428 -53,428 -18,428) / 4 = -34,928
Per la foglia 2 è pari a: (-3,428 -3,428) /2 = -3,428
Step 4: Utilizza il learning rate e prevedi la nuova variabile decisionale
Ogni campione passa attraverso i nodi decisionali dell’albero appena formato fino a raggiungere una determinata foglia. Il residuo in detta foglia viene utilizzato per prevedere il prezzo della casa.
Oltre al residuo viene utilizzato il tasso di apprendimento (o learning rate).
In altre parole, quando facciamo una previsione, ogni residuo viene moltiplicato per il tasso di apprendimento. Ciò ci costringe a usare più alberi decisionali, ognuno facendo un piccolo passo verso la soluzione finale.
Utilizzeremo in questa sede un learning rate pari a 0,1. Quindi avremo:
Previsione prezzo = Prezzo medio + tasso di apprendimento x Residuo previsto dall’albero
Previsione prezzo = 203,428 + 0.1 x -34,928 = 199,936
È bene notare che questa previsione è valida per i 4 campioni che sono stati raggruppati in questo nodo dall’albero di regressione. Di seguito i risultati anche per gli altri record:
Step 5: Calcola i nuovi residui
Calcoliamo un nuovo insieme di residui sottraendo i prezzi effettivi delle case dalle previsioni fatte nel passaggio precedente. I residui verranno quindi utilizzati per le foglie dell’albero decisionale successivo come descritto al passaggio 3.
residuo = valore osservato – valore previsto
Ad esempio per il primo record abbiamo:
Residuo = 175 – 199,936 = -24,936
E così via anche per gli altri record:
La cosa interessante che possiamo notare, che al calcolo dei nuovi residui, essi sono più bassi dei vecchi residui. Stiamo facendo un passo nella giusta direzione.
Step 6: Ripeti i passaggi da 3 a 5 fino a quando il numero di iterazioni corrisponde al numero specificato dal parametro (ovvero il numero di stimatori)
Ripetendo gli step da 3 a 5 si riducono man mano, ad ogni iterazione i residui, finchè non ci si avvicina pressochè al livello di previsione iniziale del problema.
Se otterremmo gli stessi valori, saremmo in condizione di overfitting per il set di addestramento, e avremmo cioè elevata varianza nei nostri dati.
Ciò significherebbe che il modello funzionerà bene sui dati di allenamento, ma funzionerà male su dati invisibili.
Passaggio 7: una volta addestrato, utilizzare tutti gli alberi dell’insieme per effettuare una previsione finale sul valore della variabile target
La previsione finale sarà uguale alla media calcolata nel primo passaggio, oltre a tutti i residui previsti dagli alberi che compongono la foresta moltiplicati per il tasso di apprendimento.
Quindi se si vuole prevedere il prezzo di una casa, ad esempio di 75 metri quadri con 3 anni di vita il suo prezzo avrà un valore pari a:
Prezzo previsto = 203,428 + 0,1 * (-18,428) + 0,1 * (-14,936) + ….
Al posto dei puntini ci saranno i valori del learning rate moltiplicati per i nuovi residui trovati dai nuovi alberi di regressione. Questo tante volte, quante sono le iterazioni che si sono ripetute.
Esempio in Python
Vediamo ora in python l’esempio proposto per prevedere il prezzo di una casa. Abbiamo 3 caratteristiche e 1 variabile target:
- Anni: il numero di anni da quando è stata costruita l’abitazione;
- Metri quadrati (Metri_q): dimensione in metri quadrati;
- Posizione: posizione dell’abitazione (1 = ottima, 2 = buona, 3 = discreta, 4 = sufficiente, 5 = non buona);
- Prezzo: valore in migliaia di € (k€) dell’abitazione.
NB: questo è un dataset con 7 record, molto piccolo di fatto e utilizzato solamente come spiegazione. In genere, non vengono costruiti modelli di machine learning con dataset così piccoli, se non a scopo formativo.
Inoltre, sia chiaro che i risultati del modello, dipendono e sono una conseguenza diretta dei dati iniziali, e che non si sono considerate in questa analisi altre variabili che possono influenzare il valore del prezzo di una casa.
Lo scopo di questo esempio è solamente mostrare come utilizzare l’algoritmo Gradient Boosting in python.
Importare le librerie
Importiamo le librerie necessarie per eseguire l’algoritmo Gradient Boosting. Tra di esse abbiamo Pandas e Numpy, due delle librerie fondamentali per python nel machine learning.
In aggiunta importiamo:
- Train Test Split: la funzione per suddividere il dataset in set di addestramento e set di test;
- GradientBoostingRegressor: la classe che ci permette di creare il modello e utilizzare l’algoritmo Gradient Boosting;
- MSE (Mean Squared Error) e MAE (Mean Absolute Error): le metriche per valutare l’algoritmo.
Creare il dataset
Siccome abbiamo pochi dati, possiamo creare direttamente il set di dati, tramite inserimento manuale nel seguente modo:
La sintassi prevede una parentesi graffa, cui all’interno abbiamo le caratteristiche e la variabile target tra apici, mentre i datapoints sono inseriti uno dopo l’altro separati tra virgola all’interno delle parentesi quadre.
I dati appena creati li inseriamo in un dataframe di pandas chiamato df:
E li visualizziamo:
Train Test Split
In questa sede non utilizziamo nessuna tecnica di preprocessamento perché non necessaria al nostro scopo.
Piuttosto associamo le caratteristiche alla variabile X, e alla y la variabile target:
Provvediamo ora a suddividere il dataset in set di dati di test e di allenamento. In questo caso consideriamo il 20% del set di dati come dato di test, mentre l’80% sarà il set di dati di addestramento.
Creare il modello
Siamo pronti per costruire ed adattare il modello. Digitiamo le seguenti righe di codice:
Dove max_depth si riferisce al numero di foglie di ogni albero (cioè 4) mentre n_estimators si riferisce al numero totale di alberi nell’insieme.
Come accennato in precedenza, il parametro learning_rate ridimensiona il contributo di ciascun albero. Se lo si imposta su un valore basso, saranno necessari più alberi nell’insieme per adattarsi al set di allenamento e la varianza complessiva sarà inferiore.
Utilizziamo 100 stimatori, e come learning rate scegliamo 0,1.
Per ogni iterazione calcoliamo il valore di MSE, avvalendoci del metodo staged_predict.
Possiamo notare che il valore degli errori (MSE) va da 2660,44 alla prima iterazione, e scende fino ad arrivare a 442,312 alla 100 esima iterazione. Troviamo l’indice del valore che ritorna il minor mse:
Siccome parte da zero, 99 indica la centesima iterazione come miglior prestazione del modello di Gradient Boosting.
Dopodichè, visualizziamo il set di test:
Prevediamo ora un valore per questo set di test:
E calcoliamo l’errore medio assoluto (MAE), che misura l’entità media degli errori in una serie di previsioni, senza considerare la loro direzione. Di fatto rappresenta la media sul campione di prova delle differenze assolute tra previsione e osservazione effettiva in cui tutte le differenze individuali hanno lo stesso peso.
Che risulta essere pari a:
Si può concludere che il valore è abbastanza elevato per due campioni rientranti nel set di test, in quanto ad ogni previsione mediamente il modello può discostarsi dalla previsione di 17,5 k€ sia in positivo che in negativo (c’è da dire che il dataset è molto piccolo, quindi tutto sommato può anche andarci bene).
Infatti, se prevediamo il valore della casa per l’ultimo record (si potrebbe vedere anche visualizzando y_pred, in quanto X_test già considera questo valore al suo interno):
Risulta essere pari a 184,067 (k€) rispetto ai 185k€ osservati:
Conclusione
In questo articolo abbiamo visto cos’è l’algoritmo Gradient Boosting, quali sono i parametri fondamentali che ne determinano le performance e il principio di funzionamento per un problema di regressione tramite un esempio.
Definendo i weak learner, rappresentati solitamente da alberi di regressione, e mettendoli in sequenza, l’algoritmo punta a prevedere i residui ad ogni iterazione e calcolare la nuova variabile decisionale, riducendo maggiormente iterazione dopo iterazione il valore degli errori.
La previsione finale viene calcolata considerando la media iniziale, e il valore ottenuto dal learning rate moltiplicato con il residuo tante volte quante sono il numero di alberi utilizzati per la previsione.