← Retour au portfolio RSS

· 4 min de lecture

scikit-learn : le cycle complet d'un modèle

Étape 3 : entraîner, évaluer et comparer des modèles sans se mentir — pipelines, validation croisée, bonnes métriques.

Étape 3 de ma feuille de route pour maîtriser l’IA. Précédente : pandas · Suivante : Keras.

scikit-learn, c’est le machine learning « classique » : régressions, arbres, forêts aléatoires, SVM, k-means. Pas de GPU, pas de réseaux profonds, et pourtant c’est ce qui résout la majorité des problèmes sur données tabulaires. Sa force est une interface unique : chaque modèle s’utilise de la même façon.

L’interface : fit, predict, score

from sklearn.linear_model import LogisticRegression

modele = LogisticRegression()
modele.fit(X_train, y_train)          # apprendre
y_pred = modele.predict(X_test)       # prédire
modele.score(X_test, y_test)          # évaluer (exactitude par défaut)

Changer d’algorithme revient à changer une ligne. C’est ce qui permet de comparer rapidement plusieurs approches.

La règle d’or : ne jamais évaluer sur les données d’entraînement

Un modèle qui a « appris par cœur » aura un score parfait sur ce qu’il a déjà vu, et sera inutile sur de nouvelles données : c’est le surapprentissage. On garde donc un jeu de test de côté, auquel on ne touche qu’à la fin.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

stratify=y garde les mêmes proportions de classes dans les deux jeux, indispensable quand une classe est rare.

Pipelines : la préparation fait partie du modèle

Normaliser les données avant de les découper fait fuiter de l’information du test vers l’entraînement : la moyenne calculée « a vu » les données de test. Le Pipeline règle le problème en enchaînant préparation et modèle, ajustés uniquement sur l’entraînement.

from sklearn.pipeline import make_pipeline
from sklearn.compose import make_column_transformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestClassifier

numeriques = ["age", "tarif", "taille_famille"]
categorielles = ["sexe", "classe", "port"]

preparation = make_column_transformer(
    (make_pipeline(SimpleImputer(strategy="median"), StandardScaler()), numeriques),
    (make_pipeline(SimpleImputer(strategy="most_frequent"), OneHotEncoder(handle_unknown="ignore")), categorielles),
)

modele = make_pipeline(preparation, RandomForestClassifier(random_state=42))
modele.fit(X_train, y_train)

Tout le prétraitement vit dans l’objet modele : on l’enregistre, on le déploie, et une nouvelle ligne de données brutes passe par exactement les mêmes étapes.

Validation croisée et réglage des hyperparamètres

Un seul découpage entraînement/test donne un score qui dépend du hasard. La validation croisée entraîne et évalue k k fois sur des découpages différents :

from sklearn.model_selection import cross_val_score, GridSearchCV

scores = cross_val_score(modele, X_train, y_train, cv=5)
print(scores.mean(), scores.std())

grille = {
    "randomforestclassifier__n_estimators": [100, 300],
    "randomforestclassifier__max_depth": [None, 5, 10],
}
recherche = GridSearchCV(modele, grille, cv=5, n_jobs=-1)
recherche.fit(X_train, y_train)
recherche.best_params_

Le jeu de test reste intact jusqu’au bout : il sert une seule fois, pour le score final.

Choisir la bonne métrique

L’exactitude trompe dès que les classes sont déséquilibrées : un détecteur de fraude qui répond toujours « pas de fraude » atteint 99 % sur un jeu où 1 % des transactions sont frauduleuses.

from sklearn.metrics import classification_report, confusion_matrix

print(classification_report(y_test, y_pred))   # précision, rappel, F1 par classe
confusion_matrix(y_test, y_pred)
  • Précision : parmi ce que le modèle a signalé, combien étaient vrais ?
  • Rappel : parmi les vrais cas, combien le modèle en a-t-il trouvé ?

Le choix entre les deux est une décision métier : rater une fraude ou déranger un client honnête n’ont pas le même coût.

Quel algorithme essayer en premier ?

  1. Un modèle simple comme référence : régression linéaire ou logistique. C’est le prolongement direct de mon article sur la régression linéaire.
  2. Une forêt aléatoire ou du gradient boosting (HistGradientBoostingClassifier) : souvent le meilleur choix sur des données tabulaires.
  3. Ne passer aux réseaux de neurones que si les données le justifient : images, texte, son, très gros volumes.

Projet pour valider l’étape

Reprendre le notebook Titanic de l’étape pandas et :

  1. construire un Pipeline complet (préparation + modèle) ;
  2. comparer régression logistique, forêt aléatoire et gradient boosting en validation croisée ;
  3. régler les hyperparamètres du meilleur avec GridSearchCV ;
  4. rapporter le score final sur le jeu de test, une seule fois, avec la matrice de confusion ;
  5. soumettre les prédictions sur Kaggle.

Ressources

  • Tutoriels scikit-learn et le guide utilisateur, parmi les meilleures documentations de l’écosystème.
  • Le cours « Intermediate Machine Learning » de Kaggle Learn, centré sur les pipelines et les fuites de données.

← pandas · Feuille de route · Étape suivante : Keras →