Machine Learning Con Python 4
Machine Learning Con Python 4
- Un algoritmo che sulla base delle informazioni, reagisce in modo diverso in base ai diversi input,
date regole specifiche precedentemente assegnate:
Immaginiamo di creare un algoritmo sui mercati e di dover testare una strategia di acquisto long-
term sul Nasdaq. Mettiamo che stiamo cercando di testare una strategia dove ogni volta che il
prezzo superi la 2ª deviazione del prezzo in negativo (per chi non è comune al settore lo potremmo
semplificare come un movimento insolito del prezzo verso il basso) si acquisti. Potremmo usare
come etichetta il raggiungimento della seconda deviazione da parte del prezzo, e impostare un
acquisto proporzionale alla “discesa” del prezzo.
2) Addestramento e scelta di un modello predittivo: Dato che non tutti i modelli devono
risolvere lo stesso tipo di problemi, sarà necessario addestrarlo rispetto uno specifico
problema. Possiamo mettere in relazione questo concetto a un detto popolare “suppongo sia
normale avendo a disposizione solo un martello, trattare ogni cosa come un chiodo”
(Abraham Maslow, 1966). Sarà necessario quindi confrontare differenti algoritmi col fine di
trovare l’algoritmo che offre il comportamento migliore.
3) Misurazione dell’errore e predizioni su istanze mai viste: Per costruire un modello predittivo
si parte da dati puliti e numerici, trasformati in una matrice equilibrata; si sceglie la forma
del modello (lineare, ad albero, rete, ecc.), si definisce come misurare l’errore (cosa
definiamo come giusto e cosa come sbagliato), e si ottimizzano i parametri affinché l’errore
sia minimo. Durante l’addestramento si controlla che il modello non impari solo i dati visti,
ma che riesca a operare anche su dati nuovi (overfitting) e, confrontando diverse opzioni, si
sceglie quello che funziona meglio sui dati nuovi, pronto per fare predizioni affidabili.
Neuroni Artificiali
Un neurone artificiale è un piccolo calcolatore che prende dei numeri in input e produce un numero
in output. Si ispira vagamente ai neuroni biologici, ma in realtà è solo matematica.
Ogni input ha un “peso” [w] che dice quanto è importante.
Esempio: se il neurone riceve Età e Reddito, potrebbe pesare di più il Reddito se è più rilevante, un
esempio potrebbe essere: input1×peso1 + input2×peso2 + …
Il Perceptron è un tipo di neurone artificiale semplice, inventato da Frank Rosenblatt negli anni
’50. Questo è usato per classificare i dati in due categorie (ad esempio “sì” o “no”, “rosso” o
“blu”), e attualmente è la base delle reti neurali moderne, anche se molto più semplice.
Provando a dividere il funzionamento a fasi uscirebbe una cosa di questo tipo:
1️) Il perceptron riceve diversi numeri come informazioni in ingresso. Ogni numero rappresenta
una caratteristica del problema. Ad esempio, se vuoi decidere se portare l’ombrello, gli input
potrebbero essere: “probabilità di pioggia” e “nuvolosità”.
2️) Dare peso agli input. Non tutti gli input sono uguali. Il perceptron assegna un peso a ciascun
input, cioè quanto quell’informazione conta nella decisione. Più il peso è grande, più
quell’informazione “spinge” la decisione.
Ad esempio, la probabilità di pioggia potrebbe avere peso alto, la nuvolosità un po’ meno.
3️) Il perceptron fa una somma di tutti gli input moltiplicati per i loro pesi, e aggiunge una sorta di
“spinta extra” chiamata bias. Questo totale indica quanto il perceptron è “convinto” di dire sì o no.
Poi confronta questo totale con una soglia:
Se supera la soglia → output = 1 (ad esempio: “porto l’ombrello”)
Se non supera la soglia → output = 0 (“non lo porto”)
In altre parole, decide come una bilancia: pesa tutto, somma, e decide se l’equilibrio pende da una
parte o dall’altra.
4) imparare dagli errori
Se il perceptron sbaglia la decisione: Guarda quanto si è sbagliato
Aggiusta i pesi degli input in modo che la prossima volta possa fare meglio
Ripete questo processo molte volte con dati diversi finché non impara a classificare correttamente
tutti i casi se possibile.
È da notare che il perceptron può risolvere solo problemi lineari, cioè quelli che se posti
graficamente è possibile tracciare una linea che divide le due categorie, come nella seconda foto.
Regressione Logistica
La regressione logistica prende input numerici (come nuvolosità e probabilità di pioggia), li
combina con pesi e bias, applica la sigmoide per ottenere una probabilità e decide la classe finale.
Rispetto al perceptron, l’output è continuo e probabilistico; rispetto ad Adaline, lavora su
classificazione invece che su stima lineare. Con Scikit-learn, tutti i calcoli di output, probabilità,
aggiornamento pesi tramite SGD e gestione delle epoche sono fatti automaticamente, mentre noi
possiamo concentrarci su pre-elaborazione, scelta del modello e interpretazione dei risultati,
rendendo l’approccio scalabile a dataset grandi proprio come negli esempi precedenti dell’ombrello
e di Adaline.
Nel perceptron, la somma pesata degli input viene confrontata con una soglia fissa. Se la supera, il
modello decide di portare l’ombrello, altrimenti no. Il risultato è una decisione netta, senza
sfumature o incertezze. Il perceptron impara modificando i pesi solo quando sbaglia la decisione,
quindi il suo apprendimento è brusco e discontinuo. Questo lo rende semplice e intuitivo, ma poco
adatto a situazioni ambigue, come quando il cielo è solo parzialmente nuvoloso.
Adaline usa la stessa somma pesata, ma non applica subito una soglia. Il valore che produce è
continuo e può essere interpretato come una misura di quanto le condizioni meteo spingano verso la
scelta di portare l’ombrello. Durante l’addestramento, Adaline aggiorna sempre i pesi in base
all’errore, anche quando la previsione è solo leggermente sbagliata, rendendo l’apprendimento più
stabile rispetto al perceptron. Tuttavia, il valore prodotto non è una probabilità e non ha limiti
naturali, quindi serve comunque una soglia esterna per prendere una decisione finale.
La regressione logistica parte dallo stesso calcolo di Adaline, ma applica una funzione sigmoide che
trasforma il risultato in un numero compreso tra zero e uno. Questo numero rappresenta
direttamente la probabilità che serva l’ombrello. In questo modo il modello non dice solo se portarlo
o no, ma quanto è probabile che sia necessario. La decisione finale viene presa applicando una
soglia, di solito 0.5, ma l’informazione probabilistica rimane disponibile. L’apprendimento avviene
correggendo i pesi in modo graduale, minimizzando una funzione di errore specifica per la
classificazione, ed è per questo che la regressione logistica è molto usata nei problemi reali.
Quando questi modelli vengono usati in pratica con librerie come Scikit-learn, il meccanismo di
apprendimento è lo stesso concettualmente, ma viene eseguito in modo efficiente tramite la discesa
stocastica del gradiente. I pesi vengono aggiornati un esempio alla volta, permettendo di lavorare
anche con dataset molto grandi. La differenza fondamentale, quindi, non sta nella struttura
matematica di base, che è simile per tutti, ma nel significato dell’output: il perceptron prende una
decisione secca, Adaline fornisce una valutazione continua, mentre la regressione logistica
restituisce una probabilità interpretabile, che rende il modello più flessibile e realistico per problemi
decisionali come quello dell’ombrello.
Nella regressione logistica non basta indovinare la classe giusta, l’obiettivo è assegnare una
probabilità sensata. Questo è il primo grande salto rispetto al perceptron. Dire “ombrello sì” quando
piove è corretto, ma dire “ombrello sì con probabilità 0.99” quando in realtà non piove è una
pessima previsione, anche se la classe sarebbe formalmente giusta. La regressione logistica tiene
conto proprio di questo.
Il modello prende gli input, come nuvolosità e probabilità di pioggia, e fa quello che fanno tutti i
modelli lineari: li combina con dei pesi e aggiunge un bias. Il risultato di questa combinazione è un
numero reale qualsiasi, che da solo non ha ancora un significato probabilistico. A questo punto
entra in gioco la funzione sigmoide. La sigmoide non serve a “decidere”, ma a reinterpretare quel
numero come probabilità, comprimendolo tra zero e uno. Valori molto negativi diventano
probabilità vicine a zero, valori molto positivi diventano probabilità vicine a uno, valori intorno a
zero diventano probabilità intermedie. Questo passaggio è fondamentale: è qui che il modello
smette di essere solo un classificatore lineare e diventa un modello probabilistico.
Una volta ottenuta la probabilità, il modello la confronta con ciò che è realmente successo. Se in
quella giornata hai portato l’ombrello, il valore vero è uno; se non l’hai portato, è zero. La funzione
di costo logistico misura quanto è coerente la probabilità prevista con il risultato reale. Se il modello
assegna una probabilità alta a qualcosa che poi non accade, la penalità è molto grande. Questo
perché il modello era “sicuro” e ha sbagliato. Se invece assegna una probabilità intermedia e
sbaglia, la penalità è più bassa, perché stava esprimendo incertezza. Questo è il motivo per cui la
log-loss non punisce tutti gli errori allo stesso modo: punisce soprattutto le certezze sbagliate.
Ora veniamo all’apprendimento vero e proprio. Il modello vuole ridurre questo costo, cioè vuole
produrre probabilità che siano coerenti con la realtà. Per capire come farlo, si chiede: “quanto ha
influito ciascun peso sull’errore che ho appena commesso?”. Questa domanda è il gradiente. Il
gradiente dice se aumentando o diminuendo un certo peso il costo aumenterebbe o diminuirebbe. Se
un peso ha spinto la probabilità nella direzione sbagliata, il gradiente segnala che va ridotto; se ha
aiutato, segnala che va rafforzato. La discesa del gradiente è semplicemente il meccanismo che usa
questa informazione per correggere i pesi passo dopo passo.
Nella versione stocastica, questo processo avviene usando un esempio alla volta. Il modello vede
una giornata, fa una previsione, misura l’errore, aggiorna subito i pesi, poi passa alla giornata
successiva. Non aspetta di vedere tutti i dati insieme. Questo rende l’apprendimento più reattivo e
adatto a grandi quantità di dati. È come imparare dall’esperienza giorno per giorno, invece che
aspettare la fine dell’anno per fare un bilancio.
Torniamo all’ombrello per chiudere il cerchio. Se il modello vede una giornata molto nuvolosa e
con alta probabilità di pioggia, ma assegna una probabilità bassa all’uso dell’ombrello, la funzione
di costo reagisce con un errore elevato. Questo errore spinge ad aumentare i pesi legati a nuvolosità
e pioggia. Se invece il modello assegna una probabilità alta in una giornata effettivamente piovosa,
il costo è basso e i pesi cambiano poco. Ripetendo questo processo molte volte, il modello non
impara solo “da che parte sta il confine”, come fa il perceptron, ma impara come cambia la
probabilità nello spazio degli input. È per questo che si dice che la regressione logistica impara una
superficie di probabilità e non solo una linea di separazione.
L’Overfitting
L’overfitting succede quando un modello impara troppo bene i dati di addestramento, al punto da
memorizzarli, ma perde la capacità di generalizzare su dati nuovi. In altre parole, il modello non sta
imparando la regola generale che lega input e output, ma sta adattando i pesi per spiegare anche il
rumore, le eccezioni e gli errori presenti nei dati di training. Quando poi vede dati nuovi, le sue
previsioni peggiorano.
Riprendendo l’esempio dell’ombrello, un modello in overfitting non impara una regola del tipo “più
nuvoloso e più alta è la probabilità di pioggia, più conviene portare l’ombrello”, ma impara dettagli
troppo specifici come “in quella giornata particolare con nuvolosità media e pioggia 0.47 non ho
portato l’ombrello”. Queste regole sono vere per il passato, ma inutili per il futuro.
L’overfitting è più probabile quando il modello è troppo complesso rispetto alla quantità di dati,
quando i dati sono rumorosi o quando il modello viene addestrato troppo a lungo. Anche modelli
semplici come la regressione logistica possono andare in overfitting se hanno molte variabili o se i dati
sono pochi e poco rappresentativi. L’opposto dell’overfitting è l’underfitting, in cui il modello è
troppo semplice e non riesce nemmeno a catturare la struttura di base dei dati.
Dal punto di vista della funzione di costo, durante l’addestramento il costo sui dati di training continua
a diminuire, ma quello sui dati nuovi o di validazione smette di migliorare o addirittura
aumenta. Questo è il segnale classico che il modello sta iniziando a memorizzare invece di imparare. In
termini di probabilità, il modello diventa troppo sicuro delle sue previsioni sul training set, assegnando
probabilità estreme anche quando non dovrebbe.
Per evitare l’overfitting si usano varie strategie. La più importante è la regolarizzazione, che aggiunge
una penalità ai pesi troppo grandi, costringendo il modello a preferire soluzioni più semplici e stabili.
Un’altra strategia è fermare l’addestramento prima che il modello inizi a sovra-adattarsi, osservando le
prestazioni su un set di validazione. Anche avere più dati o meno variabili aiuta, perché rende più
difficile per il modello “imparare a memoria”.
Il collegamento con Scikit-learn è diretto: quando usi modelli come la regressione logistica, la
regolarizzazione è attiva di default proprio per prevenire l’overfitting. Anche se non la vedi
esplicitamente, la libreria sta già limitando la complessità del modello mentre ottimizza i pesi con la
discesa del gradiente.
L’idea centrale delle Support Vector Machine (SMV) non è stimare una probabilità come nella
regressione logistica, né semplicemente separare le classi come fa il perceptron, ma trovare il
confine di decisione più “robusto” possibile. Robusto significa che non basta separare
correttamente i dati di training: il confine deve essere il più lontano possibile dai punti di entrambe
le classi. Questa distanza si chiama margine, e massimizzarla è il vero obiettivo delle SVM.
Riprendiamo ancora l’esempio dell’ombrello. Immagina di disegnare su un piano i giorni in cui hai
portato l’ombrello e quelli in cui non l’hai portato, usando nuvolosità e probabilità di pioggia come
assi. Ci sono infinite rette che separano i due gruppi di punti. Il perceptron si accontenta di trovarne
una qualunque che non sbagli. La regressione logistica ne trova una che produce buone probabilità.
La SVM invece cerca quella retta che lascia la “zona di sicurezza” più ampia possibile tra i due
gruppi. Più questa zona è larga, meno il modello è sensibile a piccole variazioni o rumore nei dati, e
quindi meno tende all’overfitting.
Il margine è definito come la distanza tra la retta di separazione e i punti più vicini a essa. Questi
punti speciali si chiamano support vectors. Sono pochissimi rispetto al totale dei dati, ma sono gli
unici che contano davvero: se sposti un punto lontano dal confine, la soluzione non cambia; se
sposti un support vector, il confine cambia. Questo è un altro aspetto cruciale delle SVM: il modello
finale dipende solo da una piccola parte dei dati.
Rispetto a quanto hai visto prima, la differenza concettuale è forte. Il perceptron guarda solo se un
punto è dalla parte giusta o sbagliata. La regressione logistica guarda quanto è probabile che un
punto appartenga a una classe. La SVM guarda quanto è lontano dal confine, e costruisce il
modello per massimizzare questa distanza minima. È per questo che si dice che la SVM implementa
il principio della massimizzazione del margine: invece di adattarsi ai dati, cerca la separazione più
stabile possibile.
Nel riquadro Perceptron (in alto a sinistra) si vede una linea netta chiamata “confine netto”. Il
perceptron decide in modo secco: da una parte sì ombrello, dall’altra no. Non esistono sfumature né
probabilità. Se un punto cade a destra della linea, la decisione è “ombrello”, se cade a sinistra è
“niente ombrello”. Questo rende il modello semplice ma rigido: basta poco per cambiare
completamente la decisione.
Nel riquadro Adaline (in alto a destra) la linea di separazione esiste ancora, ma attorno a essa
compare una zona sfumata colorata. Questo significa che Adaline non ragiona solo in termini di
giusto/sbagliato, ma considera quanto è lontano un punto dalla linea. Più un punto è verso il rosso,
più il modello è “convinto” di prendere l’ombrello; più è verso il blu, più è convinto del contrario.
Qui l’apprendimento è più stabile perché l’errore viene misurato in modo continuo.
Nel riquadro Regressione Logistica (in basso a sinistra) la linea non è più solo un confine, ma una
soglia di probabilità, indicata come “soglia 0.5”. La zona colorata rappresenta una vera mappa di
probabilità: vicino al blu la probabilità di prendere l’ombrello è bassa, vicino al rosso è alta. Un
punto vicino alla linea non è semplicemente classificato, ma ha una probabilità vicina al 50%.
Questo modello non dice solo “sì o no”, ma “quanto è probabile che tu prenda l’ombrello”.
Nel riquadro SVM (in basso a destra) si vede invece una linea centrale e due linee tratteggiate
parallele: questo è il margine. La SVM non cerca solo di separare i punti, ma di farlo nel modo più
robusto possibile, massimizzando la distanza tra le classi. I punti cerchiati sono i vettori di
supporto, cioè i giorni critici più vicini al confine: sono loro che determinano la posizione della
linea. Tutti gli altri punti contano meno o per niente.
Qui entra in gioco il kernel. L’idea chiave è questa: invece di forzare una separazione complicata
nello spazio originale, la SVM trasforma implicitamente i dati in uno spazio di dimensione più
alta, dove la separazione diventa semplice e lineare. Per esempio, da un piano si può passare a uno
spazio tridimensionale, o a uno spazio con moltissime dimensioni. In questo nuovo spazio, ciò che
prima era una curva o una forma complicata diventa un iperpiano.
È importante capire che la SVM non costruisce esplicitamente questo spazio più grande. Non
calcola davvero nuove coordinate gigantesche. Usa invece una scorciatoia matematica chiamata
kernel trick: una funzione kernel permette di calcolare direttamente il prodotto scalare nello spazio
trasformato, senza mai rappresentarlo. In pratica, la SVM si comporta come se i dati fossero stati
“sollevati” in uno spazio più ricco, ma senza pagarne il costo computazionale.
Torniamo all’esempio dell’ombrello. Immagina che le decisioni non dipendano solo linearmente da
nuvolosità e probabilità di pioggia, ma da una combinazione più complessa: per esempio prendi
l’ombrello solo quando entrambe sono alte, ma non quando una è alta e l’altra bassa. Sul piano
questo disegna una forma curva, impossibile da separare con una retta. Applicando un kernel, la
SVM introduce nuove dimensioni implicite che catturano queste interazioni. In quello spazio più
alto, esiste un iperpiano che separa bene i giorni “ombrello” dai giorni “no ombrello”. Quando poi
riporti la decisione nello spazio originale, l’iperpiano appare come una frontiera curva.
Diversi kernel corrispondono a diversi modi di arricchire lo spazio. Il kernel polinomiale permette
separazioni che tengono conto di potenze e interazioni tra variabili. Il kernel RBF (gaussiano) crea
regioni di influenza attorno ai punti e consente confini molto flessibili. Il kernel lineare, invece, non
trasforma nulla ed è equivalente a una SVM classica a margine massimo.
Il punto cruciale è che, anche con i kernel, la filosofia della SVM non cambia: si cerca sempre un
iperpiano che massimizza il margine. Cambia solo lo spazio in cui questo iperpiano vive. È per
questo che le SVM con kernel riescono a risolvere problemi complessi senza perdere il controllo
sull’overfitting: il margine e i parametri del kernel regolano quanto il modello può piegarsi ai dati.
Ecco 2 visioni della stessa separazione, la prima sotto sempre 2 dimensioni, la seconda aumentando
di una dimensione.
Apprendimento ad alberi Decisionali
Un albero decisionale non cerca un confine lineare o una probabilità continua: ragiona come un
processo decisionale a domande sequenziali. Immagina di avere un albero vero, dove ogni nodo è
una domanda e le foglie sono le decisioni finali (“ombrello sì” o “ombrello no”). Ogni volta che
devi fare una previsione, parti dalla radice e scendi lungo l’albero seguendo le risposte fino a
raggiungere una foglia.
Nel nostro esempio dell’ombrello, un nodo potrebbe chiedere: “La nuvolosità è superiore al 60%?”.
Se sì, vai a destra; se no, vai a sinistra. Un altro nodo successivo potrebbe chiedere: “La probabilità
di pioggia prevista è superiore al 40%?”. Continuando così, alla fine si arriva a una decisione
chiara.
L’apprendimento dell’albero consiste nel costruire l’albero migliore dai dati di training.
L’algoritmo valuta tutte le possibili domande (soglie per ogni variabile) e sceglie quella che divide
meglio i dati, cioè quella che rende più puri i gruppi risultanti. La purezza si misura con metriche
come l’entropia o l’indice di Gini: un gruppo è puro se contiene quasi solo esempi di una classe.
L’albero cresce fino a ottenere foglie molto pure, ma senza esagerare, altrimenti rischia overfitting.
A differenza dei modelli lineari, l’albero può facilmente catturare relazioni non lineari e
interazioni complesse tra le variabili, perché ogni nodo applica una soglia diversa. Questo lo rende
intuitivo e interpretabile: puoi leggere le domande e capire perché il modello ha preso quella
decisione. Inoltre, non richiede di normalizzare o scalare i dati come facevamo per il perceptron o
la regressione logistica.
Come tutti i modelli, anche gli alberi possono overfittare se diventano troppo profondi. Per evitarlo
si usano strategie come limitare la profondità, richiedere un numero minimo di esempi per
foglia, o creare forest ensemble (Random Forest) per mediare più alberi insieme.
Uso combinato di più alberi decisionali a formare foreste decisionali
Un singolo albero decisionale, come abbiamo detto, prende decisioni sequenziali facendo domande
sui dati. È molto potente e può catturare anche relazioni non lineari tra variabili. Tuttavia, un
singolo albero ha un grosso limite: è instabile e soggetto a overfitting. Piccole variazioni nei dati
possono cambiare completamente la struttura dell’albero e le decisioni finali.
La foresta casuale risolve questo problema combinando molti alberi decisionali indipendenti.
L’idea è semplice: invece di fidarsi di un solo albero, crei tanti alberi diversi e poi fai una votazione
collettiva sulle previsioni. Per ogni esempio nuovo, ogni albero dice “ombrello sì” o “ombrello no”,
e la foresta prende la decisione che ha più voti. Questo approccio riduce drasticamente l’overfitting,
perché gli errori casuali di alcuni alberi vengono annullati dalla maggioranza degli altri.
Tornando all’esempio dell’ombrello: immagina di avere 100 alberi. Alcuni guardano prima la
nuvolosità, altri la probabilità di pioggia, altri combinazioni di entrambe. Ogni albero prende la sua
decisione per una giornata specifica. La foresta poi prende la decisione finale come voto della
maggioranza. Anche se un albero sbaglia perché un punto è un po’ anomalo, la previsione finale
resta corretta grazie alla saggezza della maggioranza.
Il risultato è un modello molto più stabile e preciso rispetto a un singolo albero. Inoltre, la foresta
casuale conserva l’interpretabilità parziale: puoi ancora vedere quali variabili sono più influenti e,
se vuoi, esplorare alcuni alberi individuali per capire le decisioni.
K-Nearest Neighbor
Per esempio, immaginiamo che oggi il cielo sia al 70% di nuvolosità e la probabilità di pioggia sia
50%. K-NN cerca i K giorni nel passato più vicini a questi valori. Se scegliamo K=3 e tra questi tre
giorni due hanno portato l’ombrello e uno no, allora il modello predice “ombrello sì”. Se K fosse 5
e la maggioranza dei cinque vicini non avesse portato l’ombrello, la predizione sarebbe “ombrello
no”.
Riprendendo il filo dei modelli precedenti: K-NN non costruisce confini lineari come il perceptron
o la regressione logistica, non massimizza margini come la SVM, e non costruisce sequenze di
regole come gli alberi decisionali. Si limita a “guardare chi è vicino e copiare la decisione”, eppure
funziona sorprendentemente bene in molti problemi reali, soprattutto quando le relazioni tra
variabili sono complicate e non lineari.
Il problema dei dati mancanti
Nel machine learning, i dati mancanti sono quei valori assenti in un dataset per alcune
osservazioni. Ad esempio, in un dataset meteo per prevedere l’uso dell’ombrello, potrebbe mancare
la registrazione della probabilità di pioggia o della nuvolosità per alcuni giorni. Questi vuoti
rappresentano un problema concreto: la maggior parte degli algoritmi non può operare direttamente
su celle vuote e, se le ignori, il modello può produrre previsioni distorte o imparare regole errate. In
sostanza, i dati mancanti introducono incertezza e possono compromettere la capacità del modello
di generalizzare su dati nuovi.
Esistono diversi motivi per cui i dati possono mancare: a volte è completamente casuale, altre
volte la mancanza dipende da altre variabili note, e altre volte dipende dal valore stesso che manca.
Questo distingue il problema in tre categorie principali (MCAR, MAR, MNAR) e aiuta a decidere
quali strategie applicare.
Il concetto di regolarizzazione, che abbiamo visto per perceptron, regressione logistica e SVM, è
strettamente collegato al problema dei dati mancanti. La regolarizzazione serve a limitare la
complessità del modello, evitando che si adatti troppo ai dettagli del dataset, riducendo così
l’overfitting. Allo stesso modo, i dati mancanti rappresentano una forma di “informazione
incompleta” che, se gestita male, può portare il modello a compensare eccessivamente, generando
decisioni instabili. In questo senso, gestire correttamente i dati mancanti è come applicare una
regolarizzazione preventiva sui dati stessi, stabilizzando l’apprendimento e prevenendo errori
futuri.
Nel mondo reale si usano diverse tecniche, dalla più semplice alla più sofisticata.
Immagina di avere un dataset dei giorni in cui porti o meno l’ombrello, con due caratteristiche
principali: nuvolosità e probabilità di pioggia. Se per alcuni giorni non registri la probabilità di
pioggia, non puoi semplicemente ignorare quei giorni, altrimenti il modello potrebbe imparare
regole sbagliate, come non prendere l’ombrello in giornate piovose. Potresti sostituire la probabilità
mancante con la media degli altri giorni, oppure stimarla usando i giorni più simili (K-NN), oppure
aggiungere una colonna “dato mancante sì/no” in modo che il modello sappia che quel valore era
assente.
In tutti i casi, l’obiettivo è ridurre l’incertezza introdotta dai dati mancanti, stabilizzare il
modello e permettergli di generalizzare correttamente. Curare i dati mancanti è quindi un passo
cruciale, spesso tanto importante quanto la scelta dell’algoritmo o la regolarizzazione dei pesi.
La Principal Component Analysis (PCA) è un metodo per semplificare i dati riducendo il numero di
variabili, senza perdere le informazioni più importanti. In pratica, PCA prende tutte le
caratteristiche del dataset e cerca delle nuove direzioni, chiamate componenti principali, lungo le
quali i dati cambiano di più. La prima componente principale è la direzione in cui i dati variano di
più, la seconda è una direzione perpendicolare alla prima che cattura ancora un po’ di variazione, e
così via.
Il processo pratico funziona così: prima si uniformano i dati, così tutte le caratteristiche sono sulla
stessa scala; poi si calcola la matrice di covarianza, che dice come le variabili cambiano insieme;
successivamente si trovano gli autovettori e autovalori della matrice, che indicano le direzioni
principali e quanta varianza contengono; infine si proiettano i dati originali su queste nuove
direzioni, ottenendo una versione più compatta del dataset.
La Linear Discriminant Analysis (LDA) è una tecnica di riduzione della dimensionalità simile
alla PCA, ma con una differenza fondamentale: mentre la PCA cerca le direzioni in cui i dati
variano di più senza guardare le etichette, la LDA cerca le direzioni che separano meglio le
classi. In altre parole, LDA è supervisionata: usa le informazioni sulle classi dei dati per trovare gli
assi che rendono più chiara la differenza tra di esse.
Il processo pratico della LDA funziona così: prima si calcolano i centri delle classi e la dispersione
dei punti all’interno di ciascuna classe, poi si cerca una combinazione lineare delle caratteristiche
che massimizzi la distanza tra i centri delle classi e minimizzi la dispersione interna. Infine, i dati
vengono proiettati su questi nuovi assi, ottenendo una rappresentazione più compatta in cui le
classi sono più facilmente distinguibili.
La Kernel Principal Component Analysis (Kernel PCA) è un’estensione della PCA pensata per
gestire dati non lineari, cioè quando le relazioni tra le variabili non possono essere catturate da
semplici combinazioni lineari. Mentre la PCA classica trova nuove direzioni lineari lungo cui i dati
variano di più, la Kernel PCA prima trasforma i dati in uno spazio a dimensione più alta usando
una funzione chiamata kernel, in cui le strutture complesse diventano lineari. Su questo nuovo
spazio, poi, viene applicata la PCA tradizionale per trovare le componenti principali.
Nel pratico, il procedimento funziona così: si sceglie un kernel adatto (come RBF o polinomiale)
che calcola la similarità tra ogni coppia di punti; questa trasformazione permette di “stirare” lo
spazio dei dati in modo che pattern curvi o complicati diventino lineari; quindi si applica la PCA
come prima, trovando gli assi principali nello spazio trasformato.
Riprendendo l’esempio dell’ombrello, immaginiamo che i giorni in cui porti l’ombrello non siano
separabili facilmente da nuvolosità e probabilità di pioggia in modo lineare: i punti “ombrello sì” e
“ombrello no” potrebbero formare delle curve o cluster intrecciati. La Kernel PCA li trasforma in
uno spazio dove queste curve diventano separabili linearmente, permettendo di comprimere i dati e
visualizzare chiaramente la struttura complessa senza perdere informazioni rilevanti.
Nel machine learning le pipeline servono a semplificare e rendere sicuro il flusso di lavoro, cioè la
sequenza di operazioni che porta dai dati grezzi al modello addestrato. In pratica, invece di gestire
manualmente ogni passaggio (pulizia dei dati, normalizzazione, riduzione della dimensionalità,
addestramento del modello), una pipeline li incapsula in un’unica catena ordinata, dove l’output di
uno step diventa automaticamente l’input del successivo. Questo è fondamentale perché nel lavoro
reale i dati devono essere trattati sempre nello stesso modo, sia in fase di addestramento sia quando
il modello viene usato su nuovi dati: senza pipeline è facile dimenticare un passaggio o applicarlo in
modo incoerente.
Un altro vantaggio cruciale è che le pipeline prevengono errori concettuali, come il data leakage: ad
esempio, la normalizzazione o la PCA devono essere “imparate” solo sui dati di training e poi
applicate ai dati di test con gli stessi parametri. Con una pipeline questo avviene automaticamente,
mentre farlo a mano è rischioso. Inoltre, le pipeline rendono il codice più leggibile, riproducibile e
facilmente confrontabile: puoi cambiare il modello finale (per esempio regressione logistica, SVM,
k-NN) lasciando invariata tutta la parte di pre-elaborazione, oppure fare cross-validation sull’intero
processo come se fosse un unico oggetto.
Tornando all’esempio dell’ombrello, una pipeline tipica potrebbe essere: prendere i dati meteo
grezzi, riempire i valori mancanti, standardizzare le variabili, ridurre la dimensionalità con PCA e
infine addestrare un classificatore. Tutto questo viene visto come un solo flusso coerente, non come
pezzi separati. In sintesi, le pipeline non introducono nuovi algoritmi, ma sono uno strumento
chiave per organizzare, rendere affidabile e scalabile l’intero processo di machine learning, ed è per
questo che sono considerate una best practice professiona