Nel machine learning la generalizzazione è un concetto fondamentale, in quanto l’obiettivo finale di qualsiasi modello è di funzionare bene non solo sui dati di addestramento, ma soprattutto su dati nuovi.
Infatti, se un modello ha un’eccellente performance sul training set ma non riesce a mantenere un livello simile di accuratezza sul test set o su dati mai visti prima, si dice che soffre di overfitting, ovvero il modello apprende troppo bene i dettagli e il rumore nel set di addestramento al punto da avere difficoltà a generalizzare su dati nuovi.
In altre parole, un modello ben generalizzato è capace di applicare le conoscenze apprese durante l’addestramento per fare inferenze (previsioni) corrette su dati nuovi o sconosciuti.
Per valutare l’abilità di un modello di generalizzare su un set di dati non visti durante l’addestramento si può utilizzare la cross validation. Ora ti spiego in dettaglio come funziona.
Cos’è la cross validation
La cross validation, come puoi intuire dal nome stesso, è una tecnica di validazione incrociata che valuta l’efficacia di un modello predittivo, con l’obiettivo principale di minimizzare il rischio di overfitting.
La tecnica di cross validation più popolare è quella definita cross validation a K-folds e funziona nel seguente modo:
- Il dataset iniziale viene suddiviso in K fold (gruppi) di porzioni uguali. Ad esempio, con un dataset di 1000 osservazioni e k=10, ogni fold avrà circa 100 osservazioni;
- Seguono k iterazioni, dove per ogni iterazione viene selezionato di volta in volta un fold diverso come test set e tutti gli altri come set di addestramento. Per ogni iterazione vengono registrate le prestazioni del modello (come accuratezza, precisione, recall, ecc…);
- Al termine delle k iterazioni viene calcolata la media delle prestazioni del modello registrate in ogni iterazione, al fine di fornire una stima unica delle prestazioni del modello.
In questo modo si ha una visione più bilanciata delle prestazioni del modello, indipendentemente dalla particolare divisione dei dati in train e test set. Infatti, devi tenere in considerazione che il partizionamento del dataset di partenza può influenzare significativamente le valutazioni dei modelli di machine learning.
Di fatto diverse divisioni possono produrre stime diverse delle prestazioni di un modello (problema della varianza delle prestazioni) oppure nel caso dei dataset con dipendenze temporali (come serie temporali o dati sequenziali), la scelta casuale dei dati per il train e il test set può rompere le dipendenze temporali, portando a valutazioni non realistiche delle prestazioni del modello.
Lo svantaggio principale è che eseguire l’addestramento e la validazione k volte può essere computazionalmente costoso, specialmente per dataset grandi o modelli complessi.
Tipologie di cross validation
Oltre alla K-cross validation, ne esistono anche altre tipologie, delle quali non entrerò in dettaglio, riportate di seguito:
- Stratified K-Fold Cross-Validation, in questo caso i fold sono stratificati in modo tale da mantenere la stessa proporzione di categorie target in ogni fold;
- Leave-One-Out (LOO) Cross-Validation, dove K è uguale al numero di osservazioni nel dataset. Questo vuol dire che il test set ad ogni iterazione è formato da un singolo elemento (ONE-OUT);
- Leave-P-Out (LPO) Cross-Validation, come il precedente, ma il test set ad ogni iterazione è formato da P elementi (P-OUT);
- Time Series Cross-Validation, variante specializzata per dati temporali. I dati vengono divisi in fold in modo tale che la divisione rispetti l’ordine cronologico;
- Group K-Fold Cross-Validation, in cui i dati vengono divisi in modo che non ci siano dati dello stesso gruppo in entrambi training set e test set.
Come implementare la K-cross validation in Ptyhon
Sappi che per implementare la k-cross validation in Python puoi utilizzare la libreria scikit-learn.
Ecco un esempio di codice:
from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import cross_val_score import numpy as np # Carica il dataset Iris iris = load_iris() X, y = iris.data, iris.target # Inizializza il modello di albero decisionale clf = DecisionTreeClassifier(random_state=42) # Lista delle metriche di valutazione che vogliamo utilizzare metrics = ['accuracy', 'precision_macro', 'recall_macro', 'f1_macro'] # Esegui la cross-validation per ogni metrica e stampa i risultati for metric in metrics: scores = cross_val_score(clf, X, y, cv=5, scoring=metric) print(f"{metric.capitalize()} (media +/- dev.std): {np.mean(scores):.2f} +/- {np.std(scores):.2f}")
Nel caso in esempio si prende in considerazione il dataset iris fornito dalla libreria scikit-learn. Il modello di classificazione scelto è l’albero decisionale, sul quale vengono valutate le varie metriche (accuracy, precision, recall, f1) tramite k-cross validation con k fissato a 5 (sarebbe il parametro cv all’interno di cross_val_score).