Data Science & ML · L3 · Section 11/12
TP — Pipeline ML reproductible
Progression
#TP: Pipeline ML complet
Ce TP déroule la construction d'un pipeline ML reproductible, de la génération des données au modèle final évalué une seule fois sur un test scellé. Il mobilise toutes les pages du module: split sans fuite, preprocessing dans un Pipeline, comparaison de modèles par validation croisée, métrique adaptée, analyse d'erreurs.
#Prérequis et objectifs
Prérequis: pages « Pipeline et features », « Apprentissage supervisé » et « Évaluation et généralisation » du module; manipulation de pandas et scikit-learn.
Objectifs d'apprentissage:
- construire un pipeline complet où chaque transformation est ajustée sur le train uniquement;
- comparer plusieurs modèles par validation croisée avec une métrique unique fixée à l'avance;
- évaluer une fois sur le test, avec une baseline de référence et un intervalle de confiance;
- analyser les erreurs de façon actionnable (où le modèle se trompe-t-il, et de combien);
- produire un résultat reproductible: graine fixée, protocole écrit avant les expériences.
#Le fil rouge: prédire un salaire
Cas d'étude volontairement simple: un jeu synthétique de salaires, où l'on connaît la vraie loi de génération. Connaître la vérité permet de vérifier ce que le pipeline retrouve, et ce que le bruit rend invisible.
Important: le salaire dépend ici de l'expérience, du niveau d'études et de la taille de l'entreprise. Le modèle prédit une association au sein de ce jeu synthétique; aucune conclusion causale ou « méritocratique » n'en découle pour le monde réel, et la page « Éthique et interprétabilité » explique pourquoi ce type de cible est sensible.
#Étape 1: générer et explorer
Exploration minimale avant tout modèle: types, distributions, cardinalité des catégories, valeurs manquantes. Ici on remarque que l'age et l'expérience sont corrélés dans la vraie vie, mais pas dans ce jeu synthétique (tirages indépendants): le pipeline ne doit pas supposer de relation qu'il n'a pas vérifiée.
#Étape 2: nettoyer avec précaution
Deux règles gouvernent le nettoyage:
Toute statistique d'imputation (médiane, mode) se calcule sur le train uniquement. Sinon les valeurs des données de test contaminent l'imputation du train: fuite classique, invisible sur les courbes, présente dans le score.
Pourquoi imputer plutôt que supprimer: si seulement 4% des lignes ont une valeur manquante et que le jeu est grand, supprimer est acceptable. Si le motif d'absence est informatif (les très expérimentés omettent de remplir le champ « expérience », par exemple), une colonne indicateur « était manquant » devient une feature à part entière; le module « Pipeline et features » détaille ce point.
La suite regroupe ces opérations dans un Pipeline scikit-learn, ce qui les rend automatiquement sans fuite sous validation croisée: c'est la version robuste du pattern manuel ci-dessus.
#Étape 3: assembler le pipeline
Le ColumnTransformer applique un traitement par type de colonne, le Pipeline chaîne preprocessing et modèle. Objectif de conception: un unique objet, ajusté d'un seul geste, dans lequel aucune étape ne peut contourner le split.
Observation attendue: le RMSE CV tombe autour de 5000, l'écart-type du bruit de génération. Le modèle a extrait tout le signal linéaire disponible; le résidu restant est le bruit irréductible. Vouloir descendre sous ce plancher sur ce jeu, c'est mémoriser le bruit: la suite du TP montre qu'un modèle flexible y « réussit » sur le train et échoue sur le test.
#Étape 4: comparer des modèles honnêtement
Observation attendue: l'arbre libre affiche un RMSE d'entraînement nettement inférieur à 5000 (il mémorise le bruit) pour un RMSE de validation au mieux égal aux autres candidats, souvent légèrement pire. La régression linéaire, exactement adaptée à la loi de génération, est imbattable ici. Conclusion de méthode: le classement des modèles dépend du jeu; la colonne « écart train/validation », elle, se lit de façon universelle.
#Étape 5: évaluer sur le test, une seule fois
Observations attendues: la baseline médiane commet un MAE d'environ 12000 (la dispersion brute des salaires); le champion descend autour de 4000 (le bruit gaussien tronqué par la médiane); l'intervalle affiché rappelle qu'avec 100 exemples de test, quelques milliers d'euros de RMSE restent dans l'incertitude d'échantillonnage. Les plus grosses erreurs ne sont pas des anomalies du modèle: ce sont les individus dont le bruit de génération était extrême. La leçon: sur un phénomène réellement bruité, l'analyse d'erreurs doit distinguer « bruit irréductible » de « structure manquée ».
#Étape 6: reproductibilité
Le protocole complet tient en quelques exigences: graine fixée et consignée (np.random.default_rng(42)), données versionnées ou code de génération sous gestion de sources, description écrite de la métrique principale AVANT les expériences, journal des configurations essayées (y compris rejetées), et code exécutable de bout en bout sans intervention. Le carnet d'expériences est un livrable au même titre que le modèle.
#Exercice final vérifiable: détecter la fuite
Suggestion de vérification croisée, à exécuter réellement: créez une feature « salaire_moyen_par_education » calculée sur l'ensemble des données (moyenne du salaire par niveau d'études, test compris), ajoutez-la aux features du playground de l'étape 3, et relancez la validation croisée. Corrigé attendu: le RMSE CV plonge sous le plancher du bruit (autour de 4800 ou moins, au lieu de 5000): la moyenne par catégorie contient l'information du bruit des exemples de validation, le score annonce mieux que ce que le modèle saura faire en production. Deuxième partie: recalculez cette feature par fold (moyenne calculée sur le train du fold uniquement, par exemple via TargetEncoder dans le Pipeline) et observez le RMSE revenir autour de 5000. Conclusion observable: la même feature, calculée correctement ou pas, fait basculer le score de « magique » à « honnête », et seule la version par fold est la vraie performance.