Classificazione con il Perceptron di Rosenblatt

Classificazione Perceptron Rosenblatt

Il “hello-world” del machine learning

Foto di Lucie Morel su Unsplash

Recentemente mi stavo chiedendo quale potesse essere l’introduzione più basilare al machine learning. Volevo un compito semplice, come la classificazione binaria, e un algoritmo sufficientemente semplice da poter essere costruito da zero e spiegato in un breve articolo. Se l’algoritmo avesse avuto una certa storia, ancora meglio. Non è stato difficile trovare il candidato: il percettrone. Il percettrone ci porta all’inizio del machine learning. È stato introdotto da Frank Rosenblatt più di 60 anni fa. Come un neurone, la regola del percettrone prende in input molteplici caratteristiche e adatta i pesi che, moltiplicati con il vettore delle caratteristiche di input, consentono di prendere una decisione su se il neurone emette o meno un segnale, o in un contesto di classificazione del machine learning se l’output è 0 o 1. Il percettrone è probabilmente il classificatore binario più semplice e non conosco casi d’uso pratici del machine learning che possano essere affrontati con esso al giorno d’oggi. Tuttavia, ha un significativo valore educativo e storico poiché ha aperto la strada alle reti neurali.

Lo scopo di questo articolo è quello di presentare il percettrone e utilizzarlo in un semplice compito di classificazione binaria. Il percettrone è stato implementato in scikit-learn, ma anziché fare affidamento su questo, lo costruiremo da zero. Creeremo anche una serie di visualizzazioni per capire come l’algoritmo stabilisce il suo confine decisionale e dare uno sguardo alla sua convergenza. Il percettrone è un modello lineare composto da pesi e un termine di bias che vengono simultaneamente e iterativamente aggiornati durante il processo di adattamento. Tuttavia, non ha una funzione di perdita continua come il suo forse successore immediato nella storia del machine learning, l’algoritmo del neurone lineare adattivo (Adaline) che è anche una rete neurale a singolo strato. L’adattamento del percettrone si basa semplicemente sulla rilevazione di campioni classificati erroneamente e i pesi e il bias vengono aggiornati immediatamente non appena si verifica un campione classificato erroneamente e non una volta per epoca (epoca che rappresenta un passaggio completo attraverso l’insieme di addestramento). Pertanto, l’algoritmo non ha nemmeno bisogno di un ottimizzatore. Oserei dire che è così semplice ed elegante da diventare bello. Se sei curioso di vedere come funziona, resta sintonizzato!

Teoria del percettrone

Il percettrone, come altri modelli lineari, utilizza un insieme di pesi, uno per ciascuna delle caratteristiche, e per generare una previsione calcola il prodotto scalare dei pesi e dei valori delle caratteristiche e aggiunge un bias

Il risultato di questa funzione lineare, nota anche come input netto, viene alimentato a una funzione di attivazione f(z) che, nel caso del percettrone, è una semplice funzione a gradino, ovvero f(z) assume il valore di 1 se z≥0 e 0 altrimenti. Il ruolo della funzione di attivazione è mappare l’input netto su due valori, ovvero 0 e 1. Fondamentalmente, quello che abbiamo fatto è semplicemente definire un iperpiano. I punti che si trovano dallo stesso lato dell’iperpiano appartengono alla stessa classe. I pesi definiscono il vettore perpendicolare all’iperpiano, ovvero l’orientamento dell’iperpiano, e il bias la distanza dell’iperpiano dall’origine. Quando inizia il processo di adattamento, abbiamo un iperpiano orientato casualmente a una distanza casuale dall’origine. Ogni volta che incontriamo un campione classificato erroneamente, spostiamo leggermente l’iperpiano e ne cambiamo l’orientamento e la posizione in modo che nella prossima epoca il campione si trovi dal lato corretto dell’iperpiano. Possiamo decidere quanto spostare l’iperpiano, ovvero quale dovrebbe essere il tasso di apprendimento.

Di solito è necessario passare attraverso tutti i campioni alcune volte (epoche) fino a quando nessun punto è classificato erroneamente, o per essere più precisi fino a quando non si può fare più progressi. In ogni epoca, scorriamo tutti i campioni i = 1,.., nₛₐₘₚₗₑₛ nell’insieme di addestramento e utilizzando i pesi e il bias correnti esaminiamo se il modello classifica erroneamente e se lo fa aggiorniamo tutti i pesi j=1,.., nfₑₐₜᵤᵣₑₛ utilizzando un tasso di apprendimento η:

dove

con cappello che indica l’output di previsione. Aggiorniamo anche il bias con

dove

È concettualmente facile capire perché facciamo queste operazioni. Supponiamo che il modello preveda la classe 0, mentre quella corretta è 1. Se xⱼ è positivo, allora il peso verrà aumentato in modo che l’input netto aumenti. Se xⱼ è negativo, allora il peso verrà ridotto in modo che l’input netto aumenti ancora una volta (indipendentemente dal segno del peso). Allo stesso modo, il bias verrà aumentato portando a ulteriori aumenti dell’input netto. Con questi cambiamenti è più probabile prevedere la classe corretta per il campione non classificato correttamente nella prossima epoca. La logica è simile quando il modello prevede la classe 1, mentre quella corretta è 0, con l’unica differenza che tutti i segni sono invertiti.

Se osservi attentamente, i pesi e il bias possono essere aggiornati più volte nello stesso epoca, una volta per ogni campione non classificato correttamente. Ogni classificazione errata riorienta e riposiziona l’iperpiano di confine decisionale in modo che il campione venga previsto correttamente nella prossima epoca.

Preparazione dei dati

Utilizzeremo un set di dati sintetico composto da due distribuzioni gaussiane. Il perceptron può essere utilizzato con caratteristiche di qualsiasi dimensione, ma per scopi di questo articolo ci limiteremo a due dimensioni per facilitare la visualizzazione.

che produce la seguente figura

Scatterplot delle due classi nel set di dati sintetico. Immagine dell'autore.

Le due distribuzioni gaussiane sono allungate e messe più lontane apposta scegliendo medie e covarianze appropriate. Torneremo su questo più tardi.

Implementazione e utilizzo del Perceptron

L’implementazione del Perceptron può essere trovata di seguito. Utilizziamo lo stile scikit-learn per inizializzare il modello, addestrarlo e infine eseguire una previsione

Il metodo di inizializzazione imposta il tasso di apprendimento, il numero massimo di iterazioni e il seme del generatore di numeri casuali per scopi di riproducibilità. Il metodo fit crea un generatore di numeri casuali che viene quindi utilizzato per impostare i pesi su alcuni numeri piccoli campionati da una distribuzione uniforme, mentre il bias viene inizializzato a zero. Iteriamo quindi per un numero massimo di epoche. Per ogni epoca contiamo il numero di classificazioni errate in modo da poter monitorare la convergenza e terminare anticipatamente se possibile. Per ogni campione non classificato correttamente aggiorniamo i pesi e il bias come descritto nella sezione precedente. Se il numero di classificazioni errate è zero, allora non è possibile apportare ulteriori miglioramenti e quindi non c’è bisogno di continuare con la prossima epoca. Il metodo predict calcola semplicemente il prodotto scalare dei pesi e dei valori delle caratteristiche, aggiunge il bias e applica la funzione di passaggio.

Se utilizziamo la classe Perceptron sopra con il set di dati sintetico

possiamo vedere che la convergenza è stata raggiunta in 24 epoche, cioè non è stato necessario esaurire il numero massimo di epoche specificato

Convergenza del Perceptron. Immagine dell'autore.

Il confine decisionale può essere facilmente visualizzato utilizzando la funzione di utilità del confine decisionale di scikit-learn. Per utilizzare questa funzione generiamo una griglia di punti 200×200 che copre l’intervallo dei valori delle caratteristiche nel set di addestramento. Fondamentalmente costruiamo un grafico a contorno con la classe prevista e sovrapponiamo i campioni come un grafico a dispersione colorato utilizzando le etichette vere. Questo modo di tracciare il confine decisionale è abbastanza generico e può essere utile con qualsiasi classificatore bidimensionale.

Le due distribuzioni gaussiane costruite sinteticamente sono state perfettamente separate utilizzando un modello che potrebbe essere codificato da zero in poche righe di codice. La semplicità e l’eleganza di questo metodo lo rendono un brillante esempio introduttivo e motivazionale per l’apprendimento automatico.

Frontiera decisionale del modello perceptron adattato. Immagine dell'Autore.

Possiamo anche visualizzare l’evoluzione della frontiera decisionale nelle diverse epoche, interrompendo prematuramente il processo di adattamento del modello. Ciò può essere fatto praticamente adattando il modello utilizzando un valore di interruzione crescente per il numero massimo di epoche. Ad ogni tentativo utilizziamo i pesi e il bias del modello adattato (possibilmente non convergente) e tracciamo la frontiera decisionale come una linea. Le linee sono annotate utilizzando il numero di epoche. Ciò avrebbe potuto essere implementato in modo più elegante utilizzando un warm start, ma l’adattamento del modello è molto rapido e quindi non vale la pena aumentare la complessità aggiuntiva.

L’evoluzione della frontiera decisionale per le varie epoche è mostrata nella figura sottostante. Inizialmente, un piccolo numero di campioni di classe 0 viene classificato erroneamente, causando cambiamenti graduali nella pendenza e nell’intercetta della linea della frontiera decisionale. Possiamo vedere che la convergenza è stata raggiunta in 24 epoche, che è coerente con la figura di convergenza sopra. L’adattamento si interrompe una volta che la frontiera decisionale raggiunge una separazione perfetta delle classi, indipendentemente da quanto la frontiera sia vicina ai campioni nelle sue vicinanze.

Alcune note di cautela. La convergenza del perceptron non può essere considerata scontata e per questo motivo è importante impostare un numero massimo di iterazioni. Infatti, è possibile dimostrare matematicamente che la convergenza è garantita per classi linearmente separabili. Se le classi non sono linearmente separabili, i pesi e il bias continueranno ad essere aggiornati fino a raggiungere il numero massimo di iterazioni. Questo è il motivo per cui le due gaussiane sono state spostate più lontano nel dataset sintetico.

Un’altra nota importante è che il perceptron non ha una soluzione unica. Tipicamente esisterà un numero infinito di iperpiani che possono separare classi linearmente separabili e il modello convergerà casualmente su uno di essi. Ciò significa anche che misurare la distanza dalla frontiera decisionale non è deterministico e quindi non così utile. Le macchine a supporto vettoriale affrontano questa limitazione.

Il perceptron è essenzialmente una rete neurale a singolo strato. Comprendere come funziona è utile prima di passare a reti neurali multistrato e all’algoritmo di retropropagazione che può essere utilizzato per problemi non lineari.