• Home
  • Chi sono
  • Risorse
  • Contatti
  • Approfondimenti
  • Cerca nel sito

Lorenzo Govoni

Business e Tecnologia

  • Big Data
  • Business
  • Excel
  • Intelligenza Artificiale

Algoritmo SMOTE: cos’è e come funziona?

SMOTE

Nei problemi di machine learning è difficile trovare la stessa distribuzione dei dati bilanciata: generalmente si verifica che le osservazioni in una delle classi sono molto più alte o più basse delle altre classi.

Per definizione, un set di dati è sbilanciato se le classi non sono rappresentate in modo approssimativamente uguale.

Ipotizziamo di avere un piccolo dataset di 300 istanze, cui la classe da prevedere è un frutto tra mela (definita da 50 istanze) pera (definita da 100 istanze) e arancia (definita dalle altre 150 istanze).

La classe mela è minore sia di quella di pera che di quella di arancia: in questo contesto ci troviamo a risolvere un problema di classificazione sbilanciata.

Poiché gli algoritmi di Machine Learning tendono ad aumentare la precisione riducendo l’errore, non prendono in considerazione la distribuzione delle classi.

La sfida di lavorare con set di dati sbilanciati è che la maggior parte delle tecniche di apprendimento automatico ignorerà questa casistica e a sua volta avrà scarse prestazioni sulla classe di minoranza, sebbene in genere siano le prestazioni della classe di minoranza ad essere più importanti.

In questo articolo vedremo un modo per gestire i dataset sbilanciati, tramite la tecnica SMOTE.

Vediamo subito cos’è e come può essere utilizzata. In seguito vedremo un esempio in python.

 

Synthetic Minority Oversampling Technique (SMOTE)

SMOTE (tecnica di sovracampionamento minoritario sintetico o dall’inglese Synthetic Minority Oversampling TEchnique) è uno dei metodi di sovracampionamento più comunemente utilizzati per risolvere il problema dello sbilanciamento delle classi.

Smote risolve questo problema andando a “sovracampionare” gli esempi nella classe di minoranza, in modo casuale.

Nella pratica funziona utilizzando un algoritmo k-nearest neighbors per creare dati sintetici. Inizia prima scegliendo dati casuali dalla classe minoritaria, successivamente vengono impostati i k vicini più prossimi da tali osservazioni (ad esempio se k = 5 i 5 valori più vicini all’osservazione). I dati sintetici sarebbero quindi creati tra i dati casuali e il vicino k più prossimo selezionato casualmente, tramite interpolazione lineare.

Matematicamente, per una data osservazione di minoranza xi, viene generata una nuova osservazione (detta sintetica) interpolando tra uno dei vicini k più prossimi, xzi:

xnew = xi + λ (xzi − xi)

dove λ è un numero casuale compreso nell’intervallo [0,1]. Questa interpolazione creerà un campione sulla linea tra xi e xzi.

Per fare un esempio, sia (6, 4) un’osservazione di classe minoritaria scelta dall’algoritmo e (4, 3) il valore k più vicino scelto anch’esso causalmente. Viene dapprima definito un numero casuale compreso tra 0 e 1, lambda per ipotesi pari a 0,2. Il punto sintetico generato secondo queste condizioni sarà (6 + 0,2 * (4 – 6), 4 + 0,2 * (3 – 4)), ossia (5.6,3.8).

La procedura di sovracampionamento viene ripetuta abbastanza volte fino a quando la classe di minoranza ha la stessa proporzione della classe di maggioranza.

Una volta che si conclude questo processo, i dati vengono ricostruiti e diversi modelli di classificazione possono essere applicati ai dati elaborati.

Versioni differenti di SMOTE

L’algoritmo SMOTE prevede alcune estensioni. Tra le più comuni abbiamo:

  1. Borderline SMOTE: versione alternativa allo standard SMOTE. Questo algoritmo inizia classificando le osservazioni della classe di minoranza. Classifica qualsiasi osservazione di minoranza come un punto di “rumore” (outlier) se tutti i punti più prossimi appartengono alla classe maggioritaria e tale osservazione viene ignorata durante la creazione di dati sintetici.

    Inoltre, classifica alcuni punti come “punti di confine” (borderline appunto) che hanno sia la classe di maggioranza che quella di minoranza come valori più prossimi e ricampiona completamente da questi punti.

  2. SVM SMOTE: l’algoritmo KNN viene sostituito da un algoritmo Support Vector Machine (SVM), il quale permette di individuare il confine decisionale definito dai vettori di supporto e di generare i dati sintetici dalle osservazioni xi vicini a questi punti.

 

Vantaggi e svantaggi

Tra i principali vantaggi di questa metodologia abbiamo:

  • la riduzione dell’overfitting causato dal sovracampionamento casuale poiché vengono generati esempi sintetici anziché la replica delle istanze;
  • Nessuna perdita di informazioni;
  • È semplice da implementare e interpretare.

La tecnica SMOTE d’altronde non ha solo dei vantaggi. Tra i difetti principali troviamo che:

  • Durante la generazione di esempi sintetici, SMOTE non prende in considerazione esempi vicini che possono provenire da altre classi. Ciò può aumentare la sovrapposizione delle classi e può introdurre ulteriore rumore.
  • SMOTE non è molto pratico per dati ad alta dimensione.

 

Esempio SMOTE in python

L’esempio che vedremo nel proseguo dell’articolo tratta una classificazione di una tipologia di vetro. Il dataset è composto da sei classi e dai seguenti attributi:

  1. Id: numero da 1 a 214;
  2. RI: Refractive Index, o indice di rifrazione. È un numero adimensionale che descrive la velocità con cui la luce viaggia attraverso il materiale.
  3. Na: Sodio;
  4. Mg: Magnesio;
  5. Al: Alluminio;
  6. Si: Silicone;
  7. K: Potassio;
  8. Ca: Calcio;
  9. Ba: Bario;
  10. Fe: Ferro;
  11. Type: tipo di bicchiere (classe 1 identifica delle finestre di edifici elaborate con metodo float, classe 2 identifica delle finestre di edifici non elaborate con il metodo float, classe 3 identifica dei finestrini di veicoli elaborati con metodo float, 4 identifica dei finestrini di veicoli non elaborati con metodo float (nessuno in questo database), 5 identifica dei contenitori, 6 identifica dei bicchieri, 7 identifica dei fari).

P.S. Per maggiori informazioni si veda la produzione di vetro float, un metodo tra i più diffusi nella produzione del vetro definito “galleggiante”. 

In base agli attributi chimici l’obiettivo è predire correttamente il tipo di vetro analizzato nel dataset. Vedremo che le classi sono tra loro sbilanciate, quindi per applicare SMOTE abbiamo bisogno di installare la libreria imbalanced learn.

Installare la libreria imbalanced learn

Il modo più veloce per installare questa libreria in Windows è aprire il prompt dei comandi, posizionarsi nella cartella dove è installato python e digitare:

pip install imbalanced-learn

Allo stesso modo se hai già installato anaconda, puoi installarlo direttamente dall’anaconda Prompt utilizzando il comando

conda install -c conda-forge imbalanced-learn

Per maggiori informazioni puoi vedere direttamente il link di anaconda.

 

Importare le librerie

Come primo passo per l’esecuzione dell’algoritmo dobbiamo importare le librerie che utilizzeremo. Esse sono rappresentate nella successiva immagine:

A parte pandas e numpy, due delle librerie standard in python per il machine learning, abbiamo:

  • Train_test_split: per suddividere il set di dati in addestramento e test;
  • LogisticRegression: per applicare l’algoritmo di regressione logistica.
  • SMOTE: per utilizzare l’algoritmo SMOTE e sovracampionare le classi di minoranza;
  • Confusion_Matrix e Classification_report: la matrice di confusione e i report di classificazione per valutare il risultato del modello.

 

Importare il dataset

Carichiamo il dataset, utilizzando il metodo read_csv (siccome il file è salvato in tale formato). I due puntini stanno ad indicare che si deve indicare il percorso corretto dove è salvato il file:

Vediamo estratte le prime 5 righe del dataset:

 

Analizzare il dataset

Per visualizzare lo sbilanciamento delle classi associamo alla y il valore di queste ultime, mentre alla X il valore degli attributi, nel seguente modo:

Visualizziamo il numero di record molto piccolo, formato da 214 righe e 11 colonne, e salviamo nella variabile classi, le classi composte dal dataset utilizzando la funzione di numpy.unique():

Per visualizzare il numero di classi si può richiamare la funzione len() assegnandoli la variabile classi appena definita. Vediamo i risultati di quanto estratto dalle precedenti righe di codice:

Di seguito visualizziamo la distribuzione delle classi all’interno del dataset:

Suddividiamo ora le X e le y nel set di dati di addestramento e di test. Per semplicità, scegliamo come percentuale un valore standard del 30%:

 

Creare il modello

Come primo modello utilizziamo la regressione logistica col parametro multi_class settato a ‘ovr’: ciò significa che tratteremo il problema multiclasse come One-Vs-Rest, suddividendo il set di dati multiclasse in più problemi di classificazione binaria. Per maggiori informazioni consiglio la lettura di questo articolo.

Scegliamo un numero di iterazioni pari a 1000 per evitare che si raggiunga il numero massimo di iterazioni senza che l’algoritmo converga ad una soluzione.

Adattiamo il modello al set di dati di addestramento ed eseguiamo una previsione (associandola alla variabile y_pred).

Costruiamo la matrice di confusione confrontando i dati delle classi del set di test con i dati appena previsti e visualizziamo il risultato:

Il modello fa più errori nella previsione della classe 2 e 3 (rispettivamente 2 errori contro 5): per le altre classi le previsioni sono corrette.

Infine visualizziamo i report di classificazione per avere un’idea maggiore di come è andata la classificazione:

Abbiamo un’accuratezza generale di quasi il 90% (89,2%): il dataset è molto piccolo, ma in questo momento ci interessa vedere cosa cambia sovracampionando le classi di minoranza.

 

Utilizzare SMOTE per bilanciare le classi

Verifichiamo cosa succede utilizzando l’algoritmo SMOTE. Per implementarlo ci serve richiamare il metodo fit_resample():

Dopo l’applicazione di SMOTE le classi sono ribilanciate e formate tutte e 6 da 55 valori:

Questo valore lo possiamo visualizzare anche utilizzando la funzione di numpy.bincount(), che per i valori delle classi mi dice quanti record trova disponibile (la classe 0, non esiste quindi ci dà valore pari a 0, idem per la classe 4 che per il dataset in oggetto è inesistente):

Applichiamo ora lo stesso modello di regressione logistica con i parametri impostati in precedenza: cambierà solo che l’adattamento del modello viene fatto su una distribuzione delle classi egualitaria, quindi ogni classe avrà lo stesso peso e non sarà trattata diversamente rispetto alle altre.

NB: Tengo a precisare che il bilanciamento delle classi viene fatto nel training set, quindi in fase di addestramento, e che una corretta previsione è giusto farla su dati inosservati, per l’appunto il test set.

Come prima, calcoliamo la matrice di confusione e visualizziamo il risultato:

A differenza della prima matrice, troviamo cinque errori tutti relativi alla seconda classe.

Visualizziamo ora il report di classificazione:

Il report di classificazione permette di interpretare i risultati del problema di classificazione mostrando più informazioni rispetto che una singola metrica come accuracy_score o f1_score.

In quest’analisi possiamo disporre delle macro average e delle weighted average per ogni metrica. La prima rappresenta la media delle metriche ottenuta per ogni classe. La macro average della metrica precision è pari a 0,863 ed è data dalla somma delle metriche per ogni classe divisa dal numero delle classi ((1 +1 +0,778 +0,400 +1 +1 )/ 6).

Lo stesso si può dire per la macro average del recall e f1-score. 

Per quanto riguarda invece la metrica weighted avg essa rappresenta una media pesata, in base al numero di ogni classe presente nel set di test, per ogni punteggio ottenuto. Quindi la weighted average della metrica precision sarà pari a:

(25 * 1 + 21 * 1 + 7 * 0,778 + 2 * 0,4 + 1 * 1 + 1 * 9) / 65 = 0,958

Allo stesso modo modificando i punteggi alla formula sopra si possono ottenere anche gli altri valori di weighted recall e weighted f1-score.

L’accuratezza del modello è complessivamente del 92,3% contro l’89,2% senza il bilanciamento delle classi. SMOTE in quest’occasione ha dato un contributo a migliorare il modello.

 

Conclusione

I set di dati sbilanciati sono sottorappresentati in molti programmi di scienza dei dati, contrariamente alla loro prevalenza e importanza in molte applicazioni di apprendimento automatico industriale.

È compito del data scientist essere in grado di riconoscere quando un set di dati è squilibrato e seguire procedure e utilizzare metriche che consentano di comprendere e controllare a sufficienza questo squilibrio.

Una tecnica che si può certamente valutare di applicare per set di dati sbilanciati è SMOTE, che permette di sovracampionare la classe di minoranza.

In questo modo è possibile trattare le classi in modo ugualitario da parte dell’algoritmo che andrà ad addestrare il modello e per lo meno non dare importanza differente alle varie classi, al fine di rendere più “equilibrata” e precisa la previsione del modello.

  • Come l’Algoritmo Apriori misura le regole di associazione
    Come l’Algoritmo Apriori misura le regole di associazione
  • Classificazione multiclasse tramite i metodi OvO e OvR
    Classificazione multiclasse tramite i metodi OvO e OvR
  • Gradient Boosting per problemi di classificazione
    Gradient Boosting per problemi di classificazione
  • 8 algoritmi diffusi nel machine learning
    8 algoritmi diffusi nel machine learning
Share
Pin
Share
Tweet

Intelligenza Artificiale Machine Learning, Python

  • Home
  • Archivio
  • Risorse
  • Newsletter
  • Cerca nel sito

Copyright © 2021 · Lorenzo Govoni - Privacy Policy