L'algoritmo Boruta serve per scoprire quali sono le feature più importanti per un modello predittivo

La fase di selezione delle feature presenti nel set di addestramento è di fondamentale importanza in qualsiasi progetto di machine learning. Spiegherò l'algoritmo Boruta, in grado di creare una classifica delle nostre caratteristiche, dalla più importante alla meno impattante per il nostro modello. Boruta è semplice da usare e più potente delle tradizionali tecniche usate per lo stesso compito.

Introduzione

Iniziamo scrivendo che Boruta non è un algoritmo a se stante, ma estende l'algoritmo Random Forest. Infatti, il nome Boruta deriva dal nome dello spirito della foresta nella mitologia slava. Per comprendere come funziona l'algoritmo facciamo una introduzione al Random Forest.

Il Random Forest si basa sul bagging - crea molti campioni casuali del set di addestramento e addestra un modello statistico diverso per ognuno di essi. Per un task di classificazione il risultato è la maggioranza dei voti da parte dei modelli, mentre per un task di regressione il risultato è la media dei vari modelli. La differenza tra il bagging canonico e quello fatto nel Random Forest è che quest'ultimo utilizza sempre e solo modelli di albero di decisione (decision trees). Per ogni campione preso in considerazione, l'albero decisionale prende in considerazione un set limitato di feature. Questo permette all'algoritmo Random Forest di poter stimare l'importanza di ogni feature, poiché traccia l'errore nelle predizioni proprio in base allo split di feature considerate.

Prendiamo in considerazione un task di classificazione. Il modo in cui Random Forest stimi l'importanza delle feature funziona in due fasi. Per prima cosa, ogni albero decisionale crea una predizione e questa viene memorizzata. Secondo, i valori di certe feature vengono permutati casualmente attraverso i vari esempi e lo step precedente viene ripetuto, andando a tracciare il risultato delle predizioni nuovamente. L'importanza di una feature per un singolo albero decisionale è calcolato come la differenza delle performance tra il modello che utilizza le feature originali contro quello che utilizza le feature permutate diviso per il numero di esempi nel set di addestramento. L'importanza di una feature è la media delle misurazioni tra tutti gli alberi per quella feature. Quello che non viene fatto durante questa procedura è calcolare gli z-score per ogni feature. Qui entra in gioco Boruta.

L'Algoritmo Boruta

L'idea di Boruta è abbastanza semplice: per tutte le feature presenti nel dataset originale, ne andiamo a creare delle copie casuali (chiamate shadow feature - caratteristiche fantasma) e addestrare dei classificatori che si basano su questo dataset esteso. Per comprendere l'importanza di una feature, la compariamo a tutte le shadow feature generate. Solo le feature che sono statisticamente più importanti delle feature sintetiche vengono mantenute poiché contribuiscono di più alle performance del modello.

Ecco gli step principali che effettua Boruta per la selezione delle feature

  1. Crea una copia delle feature del set di addestramento e le unisce alle feature originali
  2. Crea permutazioni casuali sulle feature sintetiche per rimuovere ogni tipo di correlazione tra queste e la variabile target y - in pratica, queste feature sintetiche sono combinazioni randomizzate della feature originale dalla quale derivano
  3. Si comporta come il Random Forest: le feature sintetiche sono randomizzate a ogni nuova iterazione
  4. Per ogni nuova iterazione, calcola lo z-score di tutte le feature originali e di quelle sintetiche. Una feature è considerata rilevante se la sua importanza è più alta della importanza massima di tutte le feature sintetiche
  5. Applica un test statistico per tutte le feature originali e traccia i suoi risultati. L'ipotesi nulla è che l'importanza di una feature sia uguale alla importanza massima delle feature sintetiche. Il test statistico va a testare l'uguaglianza tra le feature originali e quelle sintetiche. L'ipotesi nulla viene respinta quando l'importanza di una feature è significativamente più alta o più bassa di una di quelle delle feature sintetiche
  6. Rimuove le feature che sono considerate non importanti dal dataset, sia dal dataset originale che da quello sintetico
  7. Ripete tutti gli step per un numero n di iterazioni finché tutte le feature sono rimosse o considerate importanti

Va notato che Boruta agisce come una euristica: vale a dire che non ci sono garanzie della sua performance. È dunque consigliabile lanciare il processo più volte e valutarne i risultati.

Esempio di Utilizzo in Python

Vediamo come funziona Boruta in Python con la libreria dedicata. Useremo il dataset load_diabetes() di Sklearn.datasets per testare Boruta su un problema di regressione.

Il feature set X è composto dalle variabili

  • age (età in anni)
  • sex (sesso)
  • bmi (body mass index, indice di massa corporea)
  • bp (pressione sanguigna media)
  • s1 (tc, colesterolo totale)
  • s2 (ldl, low-density lipoproteins)
  • s3 (hdl, high-density lipoproteins)
  • s4 (tch, colesterolo totale / HDL)
  • s5 (ltg, logaritmo del livello di trigliceridi)
  • s6 (glu, livello di zucchero nel sangue)

il target y è la progressione del diabete registrata nel tempo.

Lanciando lo script vedremo in terminale come Boruta stia costruendo le sue inferenze

Risultato di 10 iterazioni di Boruta sul dataset del diabete di Sklearn

Il nostro report stampa questo risultato, molto comprensibile

Report del risultato di Boruta - selezione delle feature semplice e comprensibile

Vediamo come bmi, bp, s5 e s6 siano le feature da usare poiché quelle più importanti. Boruta le ha identificate e ci ha aiutato nella selezione delle feature per il nostro modello.

Per filtrare il nostro dataset e selezionare solo le feature che per Boruta sono importanti basta fare feat_selector.transform(np.array(X)) che restituirà un array Numpy.

Feature selezionate da Boruta con .fit_transform. Questo vettore è pronto per essere usato per l'addestramento.

Ora siamo pronti per fornire al nostro modello RandomForestRegressor un set di selezionato di feature X. Addestriamo il modello e stampiamo il Root Mean Squared Error (RMSE).

Ecco i risultati dell'addestramento

Predizioni ed errore per il modello RandomForestRegressor su un feature set dai valori selezionati

Il Codice

Il codice completo qui

Andrea D'Agostino
Ciao, sono Andrea D'Agostino e sono un data scientist con 6 anni di esperienza nel campo della business intelligence. Applico tecniche statistiche e di machine learning per aiutare i clienti a trovare e risolvere problemi nei loro asset digitali e a sfruttare le debolezze dei competitor a loro vantaggio.

Sono il fondatore e l'autore di questo blog, il cui obiettivo è raccogliere le informazioni più importanti che ho imparato durante il mio percorso lavorativo e accademico al fine di poter aiutare il lettore a migliorare le sue analisi.