
I problemi di classificazione sono tra i più diffusi nel machine learning. È possibile eseguire una regressione logistica, utilizzare alberi decisionali o costruire una rete neurale per ottenere una buona soluzione.
Un altro strumento di classificazione fu inventato nel 1963, da Vladimir Vapnik e Alexey Chervonenkis: il support vector machine o, in italiano, la macchina a vettori di supporto. Tale tecnica fu perfezionata dallo stesso Vapnik negli anni ’90 e oggi viene spesso utilizzata.
Per maggiori informazioni in merito a come l’algoritmo funziona consiglio la lettura di questo articolo.
In questa sezione, invece, voglio mostrare un esempio di questo algoritmo risolvibile tramite linguaggio Python e scikit-learn.
Scelta del dataset
La scelta del dataset riguarda un esempio tratto dal libro “Python Data Science Handbook: Tools and Techniques for Developers” di Jake VanderPlas.
In particolare scegliamo un dataset di immagini (fetch_lfw_people) per eseguire il riconoscimento facciale. Tale dataset consiste di diverse migliaia di foto collazionate di varie figure pubbliche, tra cui Colin Powell, George W Bush, Ariel Sharon, e così via.
Importare le librerie
Il primo step da eseguire riguarda quello di importare le varie librerie necessarie all’esecuzione dell’algoritmo.
In questo caso viene importato solamente matplotlib e seaborn le due librerie di visualizzazione dei dati. In aggiunta come visto anche per l’algoritmo Naive Bayes, viene importato il dataset fetch_lfw_people già presente in scikit-learn.
Questo set di dati è una raccolta di immagini JPEG di personaggi famosi raccolti su Internet: ogni immagine rappresenta una singola faccia.
L’obiettivo che si vuole raggiungere è quello di riconoscimento facciale: utilizzando un classificatore support vector machine, data l’immagine del volto di una persona sconosciuta, esso cerca di identificare il nome della persona facendo riferimento a una galleria di immagini precedentemente analizzate di persone identificate.
Dopo aver importato le librerie, creiamo l’attributo faces, che considera solamente “persone” che appaiono in un minimo di 60 foto. Visualizziamo poi i personaggi del dataset:
Visualizziamo ora la forma delle immagini:
E come esse appaiono. Digitando le seguenti righe di codice potrai ottenere i seguenti volti:
Ogni immagine contiene 62 × 47 o quasi 3.000 pixel. Potremmo procedere semplicemente usando ciascun valore di pixel come caratteristica, ma spesso è più efficace usare una sorta di preprocessore per estrarre più caratteristiche significative.
Creazione del modello
Richiamiamo subito il modello di support vector machine per importare il classificatore dei vettori di supporto (SVC). Definiamo per esso un Kernel di tipo gaussiano, e parametro class_weight = balanced per assegnare a svc un valore proporzionale all’inverso della frequenza delle classi dei dati di input (vedi documentazione per maggiori informazioni). Basta digitare le seguenti righe di codice:
Oltre al modello importiamo il PCA (Principal Component Analysis), un metodo più comune per accelerare un algoritmo di apprendimento automatico.
Nei casi in cui l’algoritmo di apprendimento sia troppo lento perché la dimensione di input è troppo alta, è possibile usare un’analisi delle componenti principali per accelerarlo. Questa è probabilmente l’applicazione più comune di PCA. Non entreremo in questa sede nel dettaglio del suo funzionamento.
Nell’esempio proposto tramite un’analisi delle componenti principali si estraggono 150 componenti fondamentali da inserire nel classificatore di macchine vettoriali di supporto. E’ possibile farlo in modo molto semplice confezionando il preprocessore e il classificatore attraverso il metodo make_pipeline().
Test Train split
Il test train split è il metodo che permette di suddividere il set di dati in set di addestramento e test per far esercitare il modello.
In questo caso è opportuno eseguire le seguenti righe di codice:
Si noti che in questo caso il metodo viene eseguito anche dopo la creazione del modello, senza problemi.
Determinare il modello migliore
Arrivati a questo punto possiamo utilizzare una convalida incrociata per esplorare le varie combinazioni di parametri e scegliere la migliore. Qui viene regolata C (che controlla la durezza del margine) e gamma (che controlla la dimensione del kernel della funzione di base radiale) e tramite esse è possibile determinare il modello migliore:
Tramite l’ultima riga è possibile vedere i valori dei parametri ottimali: svc_C = 5 e svc_gamma = 0.001.
I valori ottimali cadono verso il centro della griglia; se cadessero ai bordi, vorremmo espandere la griglia per assicurarci di aver trovato il vero valore ottimo. Ora attraverso questo modello con convalida incrociata, possiamo prevedere le etichette per i dati di test, che il modello non ha ancora visto:
Diamo un’occhiata ad alcune delle immagini di prova insieme ai loro valori previsti:
Ed ecco il risultato:
- Le etichette in nero prevedono valori previsti correttamente dal classificatore;
- Le etichette in rosso prevedono valori previsti erroneamente dal classificatore.
Da questo piccolo campione, il nostro stimatore ottimale ha erroneamente etichettato solo una faccia (la faccia di Bush nella riga in basso era etichettata come Blair).
Valutazione del modello
Possiamo avere un’idea migliore delle prestazioni dello stimatore utilizzando il report di classificazione, che elenca le statistiche di recupero etichetta per etichetta. Il codice da digitare è il seguente:
E ora viene rappresentata la matrice di confusione sotto forma di mappa di calore, richiamando la libreria seaborn.
Questo ci aiuta a capire quali etichette saranno probabilmente confuse dallo stimatore.
Per un compito di riconoscimento facciale del mondo reale, in cui le foto non vengono preritagliate in griglie piacevoli, l’unica differenza nello schema di classificazione facciale è la selezione delle caratteristiche: sarà necessario utilizzare un algoritmo più sofisticato per trovare i volti, ed estrarre le caratteristiche che sono indipendenti dai pixel delle immagini.
Per questo tipo di applicazione, una buona opzione consiste nell’utilizzare OpenCV, una libreria software multipiattaforma nell’ambito della visione artificiale in tempo reale. Tra le altre cose, include implementazioni pre-addestrate di strumenti di estrazione delle caratteristiche all’avanguardia per le immagini e le facce in particolare.
Conclusione
In quest’articolo abbiamo visto un esempio di come utilizzare l’algoritmo di classificazione support vector machine in python.
Gli SVM sono molto buoni quando non abbiamo idea dei dati, e nei casi in cui si ha a che fare con dati non strutturati e semi strutturati come testo, immagini e alberi.
Il trucco del kernel è la sua vera forza. Con una funzione del kernel appropriata, è possibile risolvere qualsiasi problema complesso, in quanto garantiscono un rischio di sovraddattamento (conosciuto meglio col termine overfitting) inferiore rispetto ad altri algoritmi.
Di contro, non è semplice scegliere quale funzione kernel utilizzare se non si conosce bene il loro principio di funzionamento ed è importante tenere presente che l’addestramento richiede tempi elevati per grandi dataset.
Utilizzare questo algoritmo richiede prudenza ed esperienza, per evitare di non perdere i preziosi vantaggi che esso può fornire, e di conseguenza ridurre drasticamente le prestazioni del modello.