Validation Croisée avec Scikit-learn

scikit-learnBeginner
Pratiquer maintenant

Introduction

En apprentissage automatique (machine learning), nous divisons souvent nos données en un ensemble d'entraînement (training set) et un ensemble de test (testing set) pour évaluer la performance d'un modèle. Cependant, cette évaluation peut dépendre fortement des points de données qui se retrouvent dans l'ensemble d'entraînement par rapport à l'ensemble de test. Une méthode plus robuste est la validation croisée (cross-validation, CV).

Pourquoi la validation croisée ?

  • Réduit le risque de surapprentissage (overfitting) : Teste le modèle sur plusieurs divisions de données.
  • Meilleure estimation de la généralisation : Performance plus fiable sur des données non vues.
  • Maximise l'utilisation des données : Chaque échantillon est utilisé à la fois pour l'entraînement et le test.

La validation croisée consiste à diviser le jeu de données en plusieurs "plis" (folds), puis à entraîner et évaluer le modèle plusieurs fois, en utilisant un pli différent pour le test à chaque fois. Cela nous donne une estimation plus fiable de la performance du modèle sur des données non vues.

Dans ce laboratoire, vous apprendrez à utiliser les fonctions puissantes et pratiques de scikit-learn pour effectuer une validation croisée sur un classifieur en utilisant le célèbre jeu de données Iris. Vous apprendrez à utiliser cross_val_score pour obtenir des scores de performance, puis à calculer leur moyenne et leur écart type pour mieux comprendre la stabilité et la précision globale du modèle.

Importer cross_val_score depuis sklearn.model_selection

Dans cette étape, vous commencerez par importer la fonction nécessaire pour effectuer la validation croisée. La fonction cross_val_score est l'outil principal dans scikit-learn à cet effet. Elle simplifie le processus de division des données, d'entraînement du modèle et de notation sur plusieurs plis.

Tout d'abord, ouvrez le fichier main.py situé dans le répertoire ~/project en utilisant l'explorateur de fichiers sur le côté gauche de votre IDE.

Maintenant, ajoutez l'instruction d'importation pour cross_val_score à votre script main.py. Placez-la avec les autres importations en haut du fichier.

from sklearn.model_selection import cross_val_score

Votre fichier main.py devrait maintenant ressembler à ceci :

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Charger le jeu de données Iris
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialiser un classifieur Support Vector Classifier (SVC)
## Paramètres expliqués :
## - kernel='linear' : Utilise un noyau linéaire pour des données linéairement séparables comme Iris
## - C=1 : Paramètre de régularisation (des valeurs plus élevées = moins de régularisation)
## - random_state=42 : Assure des résultats reproductibles entre les exécutions
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Votre code ira sous cette ligne ---

Vous pouvez exécuter le script pour vous assurer qu'il n'y a pas d'erreurs de syntaxe. Ouvrez un terminal dans votre IDE et exécutez la commande suivante :

python3 main.py

Vous ne devriez voir aucune sortie, ce qui est attendu car nous n'avons pas encore ajouté de code pour produire une sortie.

Initialiser KFold avec n_splits=5 depuis sklearn.model_selection

Bien que cross_val_score puisse gérer automatiquement la division, il est de bonne pratique de comprendre le mécanisme sous-jacent. La stratégie de validation croisée la plus courante est K-Fold, où le jeu de données est divisé en 'k' plis. Le modèle est entraîné sur k-1 plis et testé sur le pli restant, répétant ce processus k fois.

Paramètres de KFold :

  • n_splits=5 : Divise les données en 5 parties égales (plis).
  • shuffle=False (par défaut) : Maintient l'ordre original des données.
  • random_state : Contrôle la randomisation si shuffle=True.

La classe KFold dans scikit-learn est un itérateur de validation croisée qui fournit des indices d'entraînement/test pour diviser les données. Bien que nous utiliserons un raccourci plus simple dans l'étape suivante, comprendre KFold est fondamental.

Importons KFold et voyons comment l'initialiser. Ajoutez les lignes suivantes à votre fichier main.py.

Tout d'abord, ajoutez l'instruction d'importation en haut :

from sklearn.model_selection import KFold

Ensuite, vous pouvez l'initialiser. Cependant, pour ce laboratoire, nous nous appuierons sur le paramètre cv de cross_val_score, qui est une approche plus directe. Le but de cette étape est de vous introduire au concept de KFold. Par souci de simplicité et pour suivre le déroulement du laboratoire, nous n'ajouterons pas le code d'initialisation de KFold à notre script. Nous utiliserons directement cv=5 dans l'étape suivante, ce qui utilise en interne une stratégie K-Fold. C'est la manière la plus courante et la plus simple d'effectuer une validation croisée.

Passons à l'étape suivante où nous utiliserons ce concept en pratique. Comme aucun code n'a été ajouté dans cette étape, vous pouvez cliquer sur "Continuer" pour passer à la suite.

Effectuer la validation croisée avec cross_val_score(clf, X, y, cv=5)

Il est maintenant temps d'effectuer la validation croisée. Nous utiliserons la fonction cross_val_score que nous avons importée précédemment. Cette fonction prend plusieurs arguments :

Paramètres de cross_val_score :

  • estimator : Le modèle à évaluer (notre classifieur clf).
  • X : La matrice de données des caractéristiques.
  • y : Le tableau des étiquettes cibles.
  • cv=5 : Stratégie de validation croisée (un entier = k-fold, ou un objet CV splitter).
  • scoring : Métrique d'évaluation (par défaut, utilise la méthode score de l'estimateur).
  • n_jobs : Nombre de cœurs de processeur à utiliser (par défaut=1, -1 pour tous les cœurs).

En définissant cv=5, nous indiquons à scikit-learn d'effectuer une validation croisée à 5 plis. Elle divisera automatiquement les données en 5 plis, puis entraînera et testera le modèle 5 fois, renvoyant un tableau contenant le score pour chaque exécution.

Ajoutez le code suivant à la fin de votre fichier main.py, sous la ligne de commentaire :

## Effectuer une validation croisée à 5 plis
scores = cross_val_score(clf, X, y, cv=5)

## Afficher le tableau des scores
print("Scores:", scores)

Votre fichier main.py complet devrait maintenant ressembler à ceci :

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Charger le jeu de données Iris
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialiser un classifieur Support Vector Classifier (SVC)
## Paramètres expliqués :
## - kernel='linear': Utilise un noyau linéaire pour des données linéairement séparables comme Iris
## - C=1: Paramètre de régularisation (des valeurs plus élevées = moins de régularisation)
## - random_state=42: Assure des résultats reproductibles entre les exécutions
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Votre code ira sous cette ligne ---

## Effectuer une validation croisée à 5 plis
scores = cross_val_score(clf, X, y, cv=5)

## Afficher le tableau des scores
print("Scores:", scores)

Maintenant, exécutez le script depuis votre terminal :

python3 main.py

Vous verrez la sortie affichant un tableau de 5 scores, un pour chaque pli de la validation croisée.

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001
Standard deviation: 0.016329931618554516

Vos scores peuvent être légèrement différents en fonction de la division exacte, mais ils devraient être similaires. Ce tableau vous donne un aperçu détaillé de la performance du modèle sur différents sous-ensembles de données.

Calculer le score moyen de validation croisée avec scores.mean()

Avoir un tableau de scores est informatif, mais pour un résumé rapide de la performance du modèle, nous calculons généralement la moyenne de ces scores. Cette seule valeur nous donne une idée générale de la précision du modèle.

La fonction cross_val_score renvoie un tableau NumPy, qui dispose de nombreuses méthodes utiles, y compris .mean(). Nous pouvons appeler cette méthode directement sur notre variable scores.

Ajoutez les lignes suivantes à la fin de votre script main.py pour calculer et afficher le score moyen :

## Calculer et afficher la moyenne des scores
mean_score = scores.mean()
print("Mean score:", mean_score)

Votre fichier main.py devrait maintenant contenir le code suivant :

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Charger le jeu de données Iris
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialiser un classifieur Support Vector Classifier (SVC)
## Paramètres expliqués :
## - kernel='linear': Utilise un noyau linéaire pour des données linéairement séparables comme Iris
## - C=1: Paramètre de régularisation (des valeurs plus élevées = moins de régularisation)
## - random_state=42: Assure des résultats reproductibles entre les exécutions
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Votre code ira sous cette ligne ---

## Effectuer une validation croisée à 5 plis
scores = cross_val_score(clf, X, y, cv=5)

## Afficher le tableau des scores
print("Scores:", scores)

## Calculer et afficher la moyenne des scores
mean_score = scores.mean()
print("Mean score:", mean_score)

Exécutez à nouveau le script :

python3 main.py

La sortie inclura maintenant la moyenne des 5 scores, vous donnant une métrique de performance unique et représentative.

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001

Calculer l'écart type des scores de validation croisée avec scores.std()

Le score moyen nous indique la performance moyenne, mais il ne nous dit pas à quel point cette performance est cohérente. L'écart type des scores nous donne une mesure de cette variance.

Interprétation de l'écart type :

  • Faible écart type (< 0.05) : Le modèle obtient des performances cohérentes sur tous les sous-ensembles de données.
  • Écart type moyen (0.05-0.15) : Variation modérée, acceptable dans la plupart des cas.
  • Écart type élevé (> 0.15) : Grande variation de performance, peut indiquer des problèmes de données ou une instabilité du modèle.

Un faible écart type indique que la performance du modèle est stable sur différents sous-ensembles de données, tandis qu'un écart type élevé suggère que la performance est plus variable.

Tout comme .mean(), les tableaux NumPy disposent également d'une méthode .std() pour calculer l'écart type.

Ajoutez la dernière partie du code à votre script main.py pour calculer et afficher l'écart type :

## Calculer et afficher l'écart type des scores
std_dev = scores.std()
print("Standard deviation:", std_dev)

Votre script main.py final est maintenant complet et devrait ressembler à ceci :

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Charger le jeu de données Iris
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialiser un classifieur Support Vector Classifier (SVC)
## Paramètres expliqués :
## - kernel='linear': Utilise un noyau linéaire pour des données linéairement séparables comme Iris
## - C=1: Paramètre de régularisation (des valeurs plus élevées = moins de régularisation)
## - random_state=42: Assure des résultats reproductibles entre les exécutions
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Votre code ira sous cette ligne ---

## Effectuer une validation croisée à 5 plis
scores = cross_val_score(clf, X, y, cv=5)

## Afficher le tableau des scores
print("Scores:", scores)

## Calculer et afficher la moyenne des scores
mean_score = scores.mean()
print("Mean score:", mean_score)

## Calculer et afficher l'écart type des scores
std_dev = scores.std()
print("Standard deviation:", std_dev)

Exécutez le script une dernière fois :

python3 main.py

La sortie finale affichera le tableau des scores, leur moyenne et leur écart type, vous donnant une évaluation complète de la performance de votre modèle.

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001
Standard deviation: 0.016329931618554516

Résumé

Félicitations pour avoir terminé ce laboratoire ! Vous avez appris avec succès comment effectuer et interpréter une validation croisée k-fold en utilisant scikit-learn.

Dans ce laboratoire, vous avez :

  • Compris l'importance de la validation croisée pour une évaluation robuste du modèle.
  • Utilisé la fonction cross_val_score pour effectuer facilement une validation croisée à 5 plis sur un Support Vector Classifier.
  • Analysé les résultats en calculant et en affichant la moyenne et l'écart type des scores de validation croisée.

Conseils pratiques pour la validation croisée :

  • Utilisez la validation croisée à 5 ou 10 plis pour la plupart des scénarios.
  • Envisagez la validation croisée stratifiée pour les jeux de données déséquilibrés.
  • Utilisez cross_validate au lieu de cross_val_score pour plusieurs métriques.
  • Définissez toujours random_state pour des résultats reproductibles.

Cette technique est une partie fondamentale du flux de travail de l'apprentissage automatique, garantissant que la performance de votre modèle est fiable et n'est pas simplement le résultat d'une division train-test chanceuse. Vous pouvez maintenant appliquer ces connaissances pour évaluer vos propres modèles d'apprentissage automatique avec une plus grande confiance.