Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Suddivisione Train-Test e Cross Validation | Sezione
Practice
Projects
Quizzes & Challenges
Quiz
Challenges
/
Fondamenti di Apprendimento Supervisionato

bookSuddivisione Train-Test e Cross Validation

Nei capitoli precedenti, sono stati costruiti i modelli e previsti nuovi valori. Tuttavia, non è ancora chiaro quanto il modello sia performante e se tali previsioni siano affidabili.

Suddivisione Train-Test

Per valutare le prestazioni del modello, è necessario disporre di un sottoinsieme di dati etichettati che il modello non ha mai visto. Pertanto, tutti i dati etichettati vengono suddivisi casualmente in training set e test set.

Questo è possibile utilizzando la funzione train_test_split() di sklearn.

Argomenti:

  • X — array dei valori delle feature;
  • y — array dei valori target;
  • test_size — proporzione del test set;

Restituisce:

  • X_train, X_test, y_train, y_test — array dello stesso tipo di dato di X e y.

Di solito, si suddivide il modello con circa 70-90% per il set di addestramento e 10-30% per il set di test.

Note
Nota

Quando il tuo dataset contiene milioni di istanze, utilizzare solo alcune migliaia per il test è generalmente più che sufficiente. In questi casi, è possibile riservare anche meno del 10% dei dati per il test.

Ora è possibile addestrare il modello utilizzando il set di addestramento e valutarne l'accuratezza sul set di test.

123456789101112131415161718192021
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] # Splitting the data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) knn = KNeighborsClassifier(n_neighbors=3).fit(X_train_scaled, y_train) # Printing the accuracy on the test set print(knn.score(X_test_scaled, y_test))
copy

Tuttavia, questo approccio presenta alcune criticità:

  • Non si utilizza tutti i dati disponibili per l'addestramento, il che potrebbe migliorare il modello;
  • Poiché si valuta l'accuratezza del modello su una piccola porzione di dati (test set), questo valore di accuratezza può essere inaffidabile su dataset di piccole dimensioni. È possibile eseguire il codice sopra più volte e osservare come l'accuratezza cambi ogni volta che viene campionato un nuovo test set.

Cross-Validation

La cross-validation è progettata per affrontare il problema dell'overfitting e garantire che il modello possa generalizzare bene su nuovi dati non visti. Si può considerare come un addestramento in aula per il modello — aiuta il modello ad apprendere in modo più equilibrato prima di affrontare il vero test finale.

L'idea è di mescolare l'intero dataset e suddividerlo in n parti uguali, chiamate fold. Successivamente, il modello esegue n iterazioni. In ogni iterazione, n-1 fold vengono utilizzati per l'addestramento e 1 fold viene utilizzato per la validazione. In questo modo, ogni parte dei dati viene utilizzata una volta per la validazione e si ottiene una stima più affidabile delle prestazioni del modello.

È importante ricordare che la cross-validation non sostituisce il test set. Dopo aver utilizzato la cross-validation per scegliere e ottimizzare il modello, è necessario valutarlo su un test set separato per ottenere una valutazione imparziale delle sue prestazioni nel mondo reale.

Note
Nota

Una scelta comune per il numero di fold è 5. In questo caso, un fold verrà utilizzato come set di test, mentre i restanti 4 fold verranno utilizzati per l'addestramento.

Si addestrano cinque modelli con sottoinsiemi leggermente diversi. Per ciascun modello, si calcola la precisione sul set di test:

accuracy=predicted correctlypredicted correctly+predicted incorrectly\text{accuracy} = \frac{\text{predicted correctly}}{\text{predicted correctly} + \text{predicted incorrectly}}

Una volta fatto ciò, è possibile calcolare la media di questi 5 punteggi di accuratezza, che rappresenterà il nostro punteggio di accuratezza della cross-validation:

accuracyavg=accuracy1+accuracy2+...+accuracy55\text{accuracy}_{avg} = \frac{\text{accuracy}_1+\text{accuracy}_2+...+\text{accuracy}_5}{5}

È più affidabile perché abbiamo calcolato il punteggio di accuratezza utilizzando tutti i nostri dati - semplicemente suddivisi in modo diverso in cinque iterazioni.

Ora che sappiamo quanto bene si comporta il modello, possiamo riaddestrarlo utilizzando l'intero dataset.

Fortunatamente, sklearn fornisce la funzione cross_val_score() per valutare il modello tramite cross-validation, quindi non è necessario implementarla manualmente:

Argomenti:

  • estimator — l'oggetto modello;
  • X — un array di valori delle feature;
  • y — un array di valori target;
  • cv — il numero di fold (5 di default);
  • scoring — la metrica (accuratezza di default);

Restituisce:

  • scores — un array di punteggi per ogni iterazione.

Ecco un esempio di come utilizzare la cross-validation con un modello k-NN addestrato sul dataset delle valutazioni di Star Wars:

12345678910111213141516171819
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import cross_val_score df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] scaler = StandardScaler() X = scaler.fit_transform(X) knn = KNeighborsClassifier(n_neighbors=3) # Calculating the accuracy for each split scores = cross_val_score(knn, X, y, cv=5) print('Scores: ', scores) print('Average score:', scores.mean())
copy

Il punteggio utilizzato di default per la classificazione è accuracy.

question mark

Seleziona tutte le affermazioni corrette.

Select all correct answers

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 1. Capitolo 19

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

bookSuddivisione Train-Test e Cross Validation

Scorri per mostrare il menu

Nei capitoli precedenti, sono stati costruiti i modelli e previsti nuovi valori. Tuttavia, non è ancora chiaro quanto il modello sia performante e se tali previsioni siano affidabili.

Suddivisione Train-Test

Per valutare le prestazioni del modello, è necessario disporre di un sottoinsieme di dati etichettati che il modello non ha mai visto. Pertanto, tutti i dati etichettati vengono suddivisi casualmente in training set e test set.

Questo è possibile utilizzando la funzione train_test_split() di sklearn.

Argomenti:

  • X — array dei valori delle feature;
  • y — array dei valori target;
  • test_size — proporzione del test set;

Restituisce:

  • X_train, X_test, y_train, y_test — array dello stesso tipo di dato di X e y.

Di solito, si suddivide il modello con circa 70-90% per il set di addestramento e 10-30% per il set di test.

Note
Nota

Quando il tuo dataset contiene milioni di istanze, utilizzare solo alcune migliaia per il test è generalmente più che sufficiente. In questi casi, è possibile riservare anche meno del 10% dei dati per il test.

Ora è possibile addestrare il modello utilizzando il set di addestramento e valutarne l'accuratezza sul set di test.

123456789101112131415161718192021
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] # Splitting the data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) knn = KNeighborsClassifier(n_neighbors=3).fit(X_train_scaled, y_train) # Printing the accuracy on the test set print(knn.score(X_test_scaled, y_test))
copy

Tuttavia, questo approccio presenta alcune criticità:

  • Non si utilizza tutti i dati disponibili per l'addestramento, il che potrebbe migliorare il modello;
  • Poiché si valuta l'accuratezza del modello su una piccola porzione di dati (test set), questo valore di accuratezza può essere inaffidabile su dataset di piccole dimensioni. È possibile eseguire il codice sopra più volte e osservare come l'accuratezza cambi ogni volta che viene campionato un nuovo test set.

Cross-Validation

La cross-validation è progettata per affrontare il problema dell'overfitting e garantire che il modello possa generalizzare bene su nuovi dati non visti. Si può considerare come un addestramento in aula per il modello — aiuta il modello ad apprendere in modo più equilibrato prima di affrontare il vero test finale.

L'idea è di mescolare l'intero dataset e suddividerlo in n parti uguali, chiamate fold. Successivamente, il modello esegue n iterazioni. In ogni iterazione, n-1 fold vengono utilizzati per l'addestramento e 1 fold viene utilizzato per la validazione. In questo modo, ogni parte dei dati viene utilizzata una volta per la validazione e si ottiene una stima più affidabile delle prestazioni del modello.

È importante ricordare che la cross-validation non sostituisce il test set. Dopo aver utilizzato la cross-validation per scegliere e ottimizzare il modello, è necessario valutarlo su un test set separato per ottenere una valutazione imparziale delle sue prestazioni nel mondo reale.

Note
Nota

Una scelta comune per il numero di fold è 5. In questo caso, un fold verrà utilizzato come set di test, mentre i restanti 4 fold verranno utilizzati per l'addestramento.

Si addestrano cinque modelli con sottoinsiemi leggermente diversi. Per ciascun modello, si calcola la precisione sul set di test:

accuracy=predicted correctlypredicted correctly+predicted incorrectly\text{accuracy} = \frac{\text{predicted correctly}}{\text{predicted correctly} + \text{predicted incorrectly}}

Una volta fatto ciò, è possibile calcolare la media di questi 5 punteggi di accuratezza, che rappresenterà il nostro punteggio di accuratezza della cross-validation:

accuracyavg=accuracy1+accuracy2+...+accuracy55\text{accuracy}_{avg} = \frac{\text{accuracy}_1+\text{accuracy}_2+...+\text{accuracy}_5}{5}

È più affidabile perché abbiamo calcolato il punteggio di accuratezza utilizzando tutti i nostri dati - semplicemente suddivisi in modo diverso in cinque iterazioni.

Ora che sappiamo quanto bene si comporta il modello, possiamo riaddestrarlo utilizzando l'intero dataset.

Fortunatamente, sklearn fornisce la funzione cross_val_score() per valutare il modello tramite cross-validation, quindi non è necessario implementarla manualmente:

Argomenti:

  • estimator — l'oggetto modello;
  • X — un array di valori delle feature;
  • y — un array di valori target;
  • cv — il numero di fold (5 di default);
  • scoring — la metrica (accuratezza di default);

Restituisce:

  • scores — un array di punteggi per ogni iterazione.

Ecco un esempio di come utilizzare la cross-validation con un modello k-NN addestrato sul dataset delle valutazioni di Star Wars:

12345678910111213141516171819
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import cross_val_score df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] scaler = StandardScaler() X = scaler.fit_transform(X) knn = KNeighborsClassifier(n_neighbors=3) # Calculating the accuracy for each split scores = cross_val_score(knn, X, y, cv=5) print('Scores: ', scores) print('Average score:', scores.mean())
copy

Il punteggio utilizzato di default per la classificazione è accuracy.

question mark

Seleziona tutte le affermazioni corrette.

Select all correct answers

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 1. Capitolo 19
some-alt