La validation croisée : exemple et application
L’utilisation de la validation croisée est quasiment indispensable pour l’évaluation des modèles.
Dans cet article, il a été montré que le choix de la répartition des individus entre train et test influence le modèle obtenu et donc ses performances.
Pour faire face à ce problème, il est possible de répéter plusieurs fois le processus de répartition des données et pour chaque nouvelle répartition obtenue réentrainer et réévaluer le modèle.
Cette méthode bien qu’étant non exhaustive permet de réduire considérablement le biais dû à la sélection aléatoire des bases d’apprentissage et de test.
La validation croisée standard
k-fold cross validation (validation croisée à k séparations) est la version de cross validation la plus standard. k est un nombre entier, compris entre 2 et le nombre de lignes de la base, qui représente la subdivision a effectué dans la base pour la cross validation. Pour un k quelconque, la procédure est la suivante:
> subdiviser la base de données en k parties aléatoires
> entraîner le modèle sur k-1 parties
> tester sur la partie restante
> reprendre cette procédure k fois en faisant varier la partie choisie pour le test.
Pour k=3, cette méthode consiste à séparer le jeu de données en 3 sous jeu de données que nous notons pour SB1, SB2 et SB3. Le modèle est entrainé sur SB1 et SB2 et testé sur SB3. Le score est ensuite calculé. La procédure est répétée en prenant cette fois ci SB2 et SB3 pour le train et ainsi de suite.
Calculons les performances de notre modèle de Random Forest avec cette méthode.
from sklearn.model_selection import cross_val_score rf = RandomForestClassifier() scores = cross_val_score(rf, X, y, cv=3) scores
> array([0.85128599, 0.84591171, 0.84882917])
Le score obtenu est relativement proche du score de test obtenu avec train_test_split. La valeur ajoutée de l’approche par validation croisée est que nos résultats sont moins dépendants du choix du split (la séparation aléatoire) et qu’il est possible d’étudier/mesurer la stabilité de notre précision.
Dans notre cas, l’écart type de nos précisions est de 0,0019. Notre estimation de l’erreur entre 84% et 85% semble donc assez cohérente.
Etudions un exemple, atypique pour mettre en avant l’intérêt de la validation croisée.
Exemple atypique
# exemple atypique # train test split classique X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4) rf = rf.fit(X_train,y_train) print("score train_test_split : ", accuracy_score(rf.predict(X_test),y_test)) # 5 folds cross validation scores = cross_val_score(rf, X, y, cv=5) print(scores) print("Moyenne : ", np.mean(scores), "et écart-type : ", np.std(scores))
> score train_test_split : 0.8931 > [0.9046 0.5554 0.6922 0.7811 0.827 ] > Moyenne : 0.75206 et écart-type : 0.11998845944506493
La précision de notre modèle est très volatile dans cet exemple. L’estimation ponctuelle donnée par le train_test_split est donc un mauvais indicateur de la précision de notre modèle. En effet, il ne nous permet pas de voir l’incertitude qui entoure la prédiction ni même d’avoir une estimation satisfaisante de la valeur moyenne de la précision.
Validation croisée avec Cross_validate
La cross validation peut aussi se faire en utilisant la fonction cross_validate().
Illustrons l’utilisation de cette fonction dans le cas des classes déséquilibrées.
# cross validation avec cross validate et classes déséquilibrées from sklearn.model_selection import StratifiedKFold from sklearn.model_selection import cross_validate res = cross_validate(rf, X, y, cv=StratifiedKFold(n_splits=5))
> {'fit_time': array([6.56530404, 6.30459189, 6.07588935, 6.40010118, 5.99491739]), > 'score_time': array([0.27090192, 0.26405549, 0.29956794, 0.2877326 , 0.30184984]), > 'test_score': array([0.84964811, 0.85067179, 0.8452975 , 0.84491363, 0.84900832])}
StratifiedKFold() permet de spécifier à la fonction cross_validate de prendre en compte la répartition des individus dans les classes. C’est la même classe de fonction que celle utilisée dans l’article sur la prise en compte des classes déséquilibrées.
Ajouter votre propre mesure de performance
La fonction Make_scorer() permet de définir une métrique de score de notre choix. Vous pouvez choisir parmi les métriques de sklearn (une liste ici) ou construire votre propre métrique en la définissant dans une fonction.
from sklearn.metrics import make_scorer, r2_score res = cross_validate(rf, X, y, scoring=dict(r2=make_scorer(r2_score)), cv=StratifiedKFold(n_splits=5))
Laisser un commentaire