ML · Chapitre 5
Machine learning 5 — Mise en pratique sur projets variés
Les quatre chapitres précédents ont introduit, brique par brique, les outils du machine learning supervisé : exploration des données, prétraitement, choix d'un modèle, validation croisée, optimisation des hyperparamètres. Ces compétences ne prennent leur valeur que mises bout à bout, sur des jeux de données qui n'ont pas été nettoyés à votre place. Ce dernier chapitre du parcours ML est entièrement consacré à la mise en pratique sur quatre projets aux profils volontairement contrastés : un problème industriel à très grand nombre de variables (Mercedes-Benz), un problème médical déséquilibré (Stroke), un classique de la régression immobilière (Ames Housing) et un benchmark de vision par ordinateur (MNIST).
L'objectif n'est plus d'apprendre une technique nouvelle mais de structurer une démarche de projet. Sur un dataset que vous découvrez, l'enchaînement attendu est toujours le même : EDA (Exploratory Data Analysis) pour comprendre la nature des variables et leur qualité, prétraitement pour rendre les données exploitables par les estimateurs scikit-learn, premier modèle de référence (baseline) pour fixer un ordre de grandeur, validation croisée pour comparer plusieurs familles de modèles, puis fine-tuning des plus prometteurs. Toute déviation de ce schéma doit être justifiée : un projet ML n'est pas une compétition de modèles, c'est une réponse documentée à une question métier.
Chaque section ci-dessous décrit un mini-brief de projet : l'origine et l'objectif du dataset, sa structure, les pièges classiques que l'on rencontre, la démarche conseillée, et quelques squelettes de code montrant les briques scikit-learn à mobiliser. Les blocs Python ne sont pas exécutables tels quels : ce sont des canevas à compléter, dans l'esprit des notebooks étudiants v2-2 du cours.
Mercedes-Benz Greener Manufacturing
Contexte et objectif métier
Le dataset Mercedes-Benz Greener Manufacturing, publié sur Kaggle en 2017, provient d'une chaîne d'essais réels du constructeur allemand. Chaque véhicule produit est testé sur banc afin de vérifier la conformité de sa configuration. Ces tests consomment du temps machine, de l'énergie et mobilisent des opérateurs : les réduire est un enjeu industriel et environnemental — d'où le qualificatif Greener.
La cible y est une variable continue correspondant au temps (ou à un score de performance) que prend le test pour une configuration donnée. On est donc dans un problème de régression. L'enjeu pratique : prédire le temps de test à partir des seules options techniques choisies, pour anticiper la durée de banc et lisser le planning d'usine.
Structure des données
Une ligne correspond à une configuration de véhicule. Il y a quelques centaines de variables, à séparer en deux blocs :
- Variables catégorielles :
X0,X1,X2,X3,X4,X5,X6,X8. Codées par des lettres minuscules (a,b,c, …), ce sont des codes internes désignant le type de moteur, la transmission, des composants mécaniques ou électroniques, des variantes de conception. - Variables binaires haute dimension : environ 370 colonnes nommées
X10,X11, …,X385, valant 0 ou 1, indiquant la présence ou l'absence d'un composant ou d'une option (flags d'un encodage industriel).
Pièges classiques
- Colonnes constantes. Sur 370 binaires, plusieurs ne prennent qu'une seule valeur (toujours 0 ou toujours 1). Elles n'apportent aucune information et perturbent certains estimateurs ou augmentent le temps de calcul. Il faut les détecter et les supprimer.
- Colonnes dupliquées. Plusieurs paires de colonnes binaires sont identiques. Garder les deux est redondant. Une déduplication basée sur la transposition du DataFrame est efficace.
- Variables catégorielles à modalités rares. Certaines lettres n'apparaissent que dans deux ou trois lignes. Un encodage one-hot brut multiplie alors les colonnes peu informatives ; un encodage par cible ou un regroupement Other peut être préférable.
- Faible rapport signal/bruit. La majorité des binaires ont une corrélation très faible avec
y. Un modèle linéaire brut sera médiocre. Privilégier des modèles à sélection implicite (Lasso, arbres, gradient boosting).
Démarche conseillée
L'EDA commence par un df.info() et un df.describe() pour vérifier les types et l'absence de valeurs manquantes (le dataset n'en contient pas explicitement). Tracer la distribution de y est instructif : asymétrique, avec une longue queue. Une transformation logarithmique de la cible améliore généralement les performances des modèles linéaires.
import pandas as pd import numpy as np df = pd.read_csv("mercedes_test.csv") # Détection des colonnes constantes cols_constantes = [c for c in df.columns if df[c].nunique() == 1] # Séparation features / cible y = df["y"] X = df.drop(columns=["ID", "y"] + cols_constantes)
Pour le prétraitement des huit variables catégorielles, un OneHotEncoder avec handle_unknown="ignore" est le plus simple. Les binaires passent telles quelles. Un ColumnTransformer permet d'orchestrer proprement les deux blocs.
from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder cat_cols = ["X0", "X1", "X2", "X3", "X4", "X5", "X6", "X8"] bin_cols = [c for c in X.columns if c not in cat_cols] preprocess = ColumnTransformer([ ("cat", OneHotEncoder(handle_unknown="ignore"), cat_cols), ("bin", "passthrough", bin_cols), ])
Comme baseline, un DummyRegressor(strategy="mean") donne le R² minimal de référence (zéro en validation). Une régression linéaire ridge bien régularisée fournit la première vraie référence. On enchaîne ensuite sur des modèles plus expressifs : RandomForestRegressor, GradientBoostingRegressor, XGBRegressor (si la bibliothèque est disponible).
from sklearn.pipeline import Pipeline from sklearn.linear_model import Ridge from sklearn.ensemble import GradientBoostingRegressor from sklearn.model_selection import cross_val_score pipe = Pipeline([("prep", preprocess), ("model", Ridge(alpha=1.0))]) scores = cross_val_score(pipe, X, y, cv=5, scoring="r2")
La métrique de référence sur Kaggle est le R². Sur ce dataset, un score honnête se situe autour de 0.55 — au-delà, on entre dans la zone où le surapprentissage guette. Le fine-tuning portera sur alpha pour Ridge, n_estimators/max_depth/learning_rate pour le gradient boosting. Une GridSearchCV ou une RandomizedSearchCV sur l'union des hyperparamètres permettra de choisir.
Pour aller plus loin
- Compétition Kaggle d'origine : https://www.kaggle.com/c/mercedes-benz-greener-manufacturing
- Dataset Kaggle : https://www.kaggle.com/datasets/competitions/mercedes-benz-greener-manufacturing
Stroke Prediction Dataset
Contexte et objectif métier
L'AVC (accident vasculaire cérébral) est l'une des principales causes mondiales de mortalité et de handicap. Identifier en amont les patients à risque permet de mettre en place des actions de prévention ciblées : suivi médical renforcé, recommandations sur l'hygiène de vie, traitements préventifs. Le dataset Stroke Prediction Dataset de Fede Soriano (Kaggle) propose, pour quelques milliers d'individus, un ensemble de variables démographiques, médicales et comportementales, ainsi qu'une étiquette stroke indiquant si la personne a subi un AVC.
Le problème est une classification binaire : stroke = 1 (AVC survenu) versus stroke = 0 (pas d'AVC). Mais c'est surtout un cas d'école de classification déséquilibrée : les cas positifs représentent environ 5 % du jeu de données. Toute la difficulté méthodologique est là.
Structure des données
Le dataset contient une dizaine de variables explicatives, à organiser comme suit :
- Identifiant :
id— à exclure du modèle. - Démographiques :
gender,age,Residence_type. - Antécédents médicaux :
hypertension,heart_disease. - Situation sociale :
ever_married,work_type. - Mode de vie :
smoking_status. La modalitéUnknownest en réalité une valeur manquante déguisée — à traiter comme telle. - Biométrie :
avg_glucose_level,bmi. La variablebmicontient de vraies valeurs manquantes (NaN).
Pièges classiques
- Le piège de l'accuracy. Avec 95 % de négatifs, un modèle qui prédit toujours « pas d'AVC » obtient 95 % d'accuracy. Cette métrique est inutilisable. Il faut raisonner en rappel (sensibilité) sur la classe positive, précision, F1-score, et surtout AUC ROC ou AUC PR.
- Fuite de données via l'imputation. Calculer la moyenne de
bmisur l'ensemble du dataset puis splitter, c'est tricher : l'information du test infuse dans le train. LeSimpleImputerdoit être encapsulé dans unPipelinepour s'ajuster uniquement sur le fold d'entraînement. - Modalité
Unknowntraitée comme une catégorie normale. Le modèle apprendra que « Unknown » a un risque moyen, alors que cette modalité regroupe en fait des profils hétérogènes. À tester : remplacer parNaNpuis imputer, ou créer une variable indicatricesmoking_unknown. - Identifiant utilisé comme feature.
idest ordonné dans le fichier. Si on l'inclut, le modèle peut apprendre une corrélation factice. À supprimer dès l'EDA. - Stratification oubliée. Lors du
train_test_split, sansstratify=y, on peut se retrouver avec un test set qui n'a presque aucun cas positif.
Démarche conseillée
L'EDA met en évidence trois faits dominants : le risque d'AVC croît fortement avec l'âge, il est corrélé à hypertension et heart_disease, et les variables socio-professionnelles sont surtout des proxys d'âge (les enfants ne font pas d'AVC, les retraités si). Une matrice de corrélation et quelques boxplots de age selon stroke valent un long discours.
import pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv("stroke.csv").drop(columns="id") # Traiter Unknown comme NaN df["smoking_status"] = df["smoking_status"].replace("Unknown", pd.NA) X = df.drop(columns="stroke") y = df["stroke"] X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, stratify=y, random_state=42 )
Le pipeline assemble une imputation pour les numériques (médiane), une imputation par le mode pour les catégorielles, un encodage one-hot, puis un classifieur. La gestion du déséquilibre se fait soit par class_weight="balanced" (logistique, forêt aléatoire), soit par sous-échantillonnage / sur-échantillonnage (SMOTE de la bibliothèque imbalanced-learn).
from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer from sklearn.preprocessing import OneHotEncoder, StandardScaler from sklearn.linear_model import LogisticRegression num = ["age", "avg_glucose_level", "bmi"] cat = ["gender", "Residence_type", "ever_married", "work_type", "smoking_status"] prep = ColumnTransformer([ ("num", Pipeline([("imp", SimpleImputer(strategy="median")), ("sc", StandardScaler())]), num), ("cat", Pipeline([("imp", SimpleImputer(strategy="most_frequent")), ("ohe", OneHotEncoder(handle_unknown="ignore"))]), cat), ]) clf = Pipeline([("prep", prep), ("model", LogisticRegression(class_weight="balanced", max_iter=1000))])
Les modèles à comparer : régression logistique régularisée, RandomForestClassifier, GradientBoostingClassifier. La métrique reportée doit être l'AUC ROC en validation croisée stratifiée. Pour le seuil de décision, ne pas se contenter du 0.5 par défaut : une courbe précision-rappel permet de choisir un seuil aligné sur le coût métier (rater un AVC est plus grave qu'une fausse alerte).
from sklearn.model_selection import cross_val_score, StratifiedKFold cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) auc = cross_val_score(clf, X, y, cv=cv, scoring="roc_auc").mean()
Pour aller plus loin
- Dataset Kaggle : https://www.kaggle.com/datasets/fedesoriano/stroke-prediction-dataset
- Lecture conseillée sur les métriques en classification déséquilibrée : Imbalanced-learn user guide.
House Prices — Ames Housing Dataset
Contexte et objectif métier
Le dataset Ames Housing, compilé par Dean De Cock à l'université de l'Iowa, est devenu un standard de l'enseignement de la régression depuis qu'il a remplacé le vieux Boston Housing dans les écoles. Il décrit environ 1 500 ventes de maisons individuelles à Ames (Iowa) avec une richesse de variables sans équivalent : 80 colonnes mêlant numériques continues, catégorielles nominales, ordinales encodées et indicateurs binaires. La cible SalePrice est le prix de vente final, en dollars.
C'est un problème de régression classique, mais le dataset oppose au praticien deux difficultés : la forte hétérogénéité des types de variables (impossible d'appliquer un traitement uniforme) et un nombre élevé de variables relativement au nombre d'observations, qui ouvre la porte au surapprentissage et justifie la régularisation.
Structure des données
On peut regrouper les 80 variables en familles thématiques, ce qui aide à structurer le prétraitement :
- Identifiant :
Id— à exclure. - Localisation :
Neighborhood(très informative),MSZoning. - Terrain :
LotArea,LotFrontage(avec valeurs manquantes),LotShape,LandContour,LotConfig,LandSlope. - Type et style :
MSSubClass(codes numériques mais à traiter comme catégoriels),BldgType,HouseStyle. - Qualité globale :
OverallQual(ordinale, très corrélée à la cible),OverallCond. - Années :
YearBuilt,YearRemodAdd. - Surfaces :
GrLivArea(la plus prédictive aprèsOverallQual),TotalBsmtSF,1stFlrSF,2ndFlrSF. - Pièces :
BedroomAbvGr,TotRmsAbvGrd,KitchenAbvGr. - Sous-sol :
BsmtQual,BsmtCond,BsmtExposure,BsmtFinType1/2,BsmtFinSF1/2,BsmtUnfSF. LesNaNy signifient « pas de sous-sol ». - Salles de bain :
FullBath,HalfBath,BsmtFullBath,BsmtHalfBath. - Garage :
GarageType,GarageYrBlt,GarageCars,GarageArea,GarageQual,GarageCond. Mêmes conventions deNaNque pour le sous-sol. - Extérieur et matériaux :
Exterior1st/2nd,RoofStyle,RoofMatl,Foundation,MasVnrType,MasVnrArea. - Confort et réseaux :
Heating,HeatingQC,CentralAir,Electrical,Utilities. - Aménagements extérieurs :
WoodDeckSF,OpenPorchSF,EnclosedPorch,ScreenPorch,PoolArea. - Contexte de vente :
MoSold,YrSold,SaleType,SaleCondition.
Pièges classiques
- Valeurs manquantes structurelles. Un
NaNdansGarageQualn'est pas un trou de saisie mais l'absence de garage. Imputer par le mode est une erreur. La règle est : pour ces variables-là, créer une modalité"None"(ou imputer la version numérique associée par 0). - Variable cible asymétrique.
SalePricea une distribution très étalée à droite. La compétition Kaggle évalue d'ailleurs le RMSE surlog(SalePrice). Appliquernp.log1pà la cible est presque toujours bénéfique. MSSubClasstraité comme numérique. Codé en entiers (20, 30, 60, …) il ne porte pourtant aucune relation d'ordre : c'est une catégorie. À convertir explicitement en string ou catégorie pandas.- Outliers évidents. Le dataset contient quelques très grandes maisons vendues à des prix faibles (ventes entre proches, dossiers particuliers). De Cock recommande lui-même de filtrer les ventes avec
GrLivArea > 4000. - Encodage explosif. Avec
OneHotEncodersur les 40+ variables catégorielles, on peut dépasser 250 colonnes. Sur 1 500 lignes, les modèles linéaires non régularisés divergent. Régularisation obligatoire (Ridge, Lasso, ElasticNet) ou modèles à arbres qui s'en moquent. - Fuite via les variables temporelles.
YrSoldest postérieur àYearBuiltmais une feature dérivée commeAge = YrSold - YearBuiltdoit se calculer dans le pipeline pour ne pas mélanger les splits.
Démarche conseillée
L'EDA insiste sur les variables les plus corrélées à SalePrice : OverallQual, GrLivArea, GarageCars, TotalBsmtSF, 1stFlrSF, FullBath, YearBuilt. Un nuage de points GrLivArea vs SalePrice met immédiatement en évidence les outliers évoqués plus haut.
import numpy as np import pandas as pd df = pd.read_csv("house_prices.csv") df = df[df["GrLivArea"] < 4000].copy() df["MSSubClass"] = df["MSSubClass"].astype(str) y = np.log1p(df["SalePrice"]) X = df.drop(columns=["Id", "SalePrice"])
Pour le prétraitement, deux pipelines parallèles : un pour les numériques (imputation médiane + standardisation), un pour les catégorielles (imputation par "None" quand NaN veut dire absence, mode sinon, puis one-hot). Un ColumnTransformer les compose.
from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer from sklearn.preprocessing import StandardScaler, OneHotEncoder num = X.select_dtypes(include=np.number).columns.tolist() cat = X.select_dtypes(exclude=np.number).columns.tolist() prep = ColumnTransformer([ ("num", Pipeline([("imp", SimpleImputer(strategy="median")), ("sc", StandardScaler())]), num), ("cat", Pipeline([("imp", SimpleImputer(strategy="constant", fill_value="None")), ("ohe", OneHotEncoder(handle_unknown="ignore"))]), cat), ])
La baseline est Ridge(alpha=10). Elle est étonnamment difficile à battre. Comparer ensuite avec Lasso (qui fait la sélection de variables), ElasticNet, RandomForestRegressor, GradientBoostingRegressor, et idéalement XGBoost ou LightGBM. La métrique attendue est le RMSE sur log(SalePrice).
from sklearn.linear_model import Ridge from sklearn.model_selection import cross_val_score pipe = Pipeline([("prep", prep), ("model", Ridge(alpha=10))]) rmse = -cross_val_score(pipe, X, y, cv=5, scoring="neg_root_mean_squared_error").mean()
Le fine-tuning porte sur alpha pour les modèles linéaires (échelle logarithmique : 0.01, 0.1, 1, 10, 100), et sur le triplet n_estimators/max_depth/learning_rate pour le gradient boosting. Un stacking (empilement) d'une Ridge et d'un gradient boosting est la solution gagnante classique de la compétition.
Pour aller plus loin
- Compétition Kaggle : https://www.kaggle.com/c/house-prices-advanced-regression-techniques
- Article original de Dean De Cock : Ames, Iowa: Alternative to the Boston Housing Data, Journal of Statistics Education, 2011.
MNIST — chiffres manuscrits au format CSV
Contexte et objectif métier
MNIST (Modified National Institute of Standards and Technology) est le jeu de données le plus historique de l'apprentissage automatique appliqué à l'image. Constitué par Yann LeCun, Corinna Cortes et Christopher J. C. Burges à la fin des années 1990, il a accompagné toute la première vague des réseaux de neurones convolutifs. Sa taille raisonnable et la simplicité de la tâche en font un benchmark idéal pour découvrir la classification multi-classes sur image, avant d'aborder le deep learning à proprement parler.
Le problème est une classification multi-classes à 10 classes : reconnaître quel chiffre (0 à 9) est représenté sur une image 28×28 pixels en niveaux de gris. La version utilisée ici est en CSV : chaque image devient une ligne, et chaque pixel une colonne nommée selon ses coordonnées (1x1, 1x2, …, 28x28), plus une colonne label.
Structure des données
- 60 000 images d'entraînement, 10 000 images de test (selon la version Kaggle).
- 784 variables d'entrée (28 × 28 pixels), entiers entre 0 (noir) et 255 (blanc).
- 1 variable cible
label, entier entre 0 et 9.
Pièges classiques
- Ne pas regarder les images. C'est la première chose à faire sur un dataset de vision : afficher une dizaine d'exemples de chaque classe. Cela révèle la qualité du recadrage, la diversité des graphies, et permet de détecter des classes ambiguës (le 4 ouvert versus le 9, le 1 sans empattement versus le 7).
- Travailler sur le dataset complet sans nécessité. 60 000 lignes × 784 colonnes, c'est lourd. Pour explorer les modèles, prélever 10 000 lignes au hasard suffit largement et divise les temps d'entraînement.
- Oublier la normalisation des pixels. Les modèles à descente de gradient (SVM, régression logistique, MLP) souffrent de valeurs entre 0 et 255. Diviser par 255 ramène tout dans
[0, 1]. - Confondre split de fichiers et split aléatoire. La version CSV de Kaggle est généralement un seul fichier — il faut faire un
train_test_splitstratifié soi-même. Sur d'autres versions de MNIST, les fichierstrain.csvettest.csvsont déjà séparés et il ne faut pas les remélanger. - Métriques visuelles oubliées. Sur 10 classes, l'accuracy globale ne dit pas où le modèle se trompe. Une matrice de confusion identifie immédiatement les paires de chiffres confondues.
Démarche conseillée
Après chargement, séparer features et cible une fois pour toutes simplifie tout le reste du notebook.
import pandas as pd import numpy as np import matplotlib.pyplot as plt df = pd.read_csv("mnist.csv") X = df.drop(columns="label").to_numpy() y = df["label"].to_numpy()
Pour visualiser, il faut redonner sa forme bidimensionnelle au vecteur de 784 valeurs grâce à reshape(28, 28), puis utiliser imshow en niveaux de gris.
image = X[0].reshape(28, 28) plt.imshow(image, cmap="gray") plt.title(y[0]) plt.axis("off")
Pour afficher plusieurs chiffres dans une même figure, on utilise subplots qui retourne une grille de sous-figures indexables par (i, j).
fig, axes = plt.subplots(2, 5, figsize=(10, 4)) k = 0 for i in range(2): for j in range(5): axes[i, j].imshow(X[k].reshape(28, 28), cmap="gray") axes[i, j].set_title(y[k]) axes[i, j].axis("off") k += 1 plt.tight_layout()
La normalisation est un simple X = X / 255.0. Elle est indispensable pour les modèles linéaires et les SVM, optionnelle (mais sans coût) pour les arbres.
Côté modèles, partir d'une baseline pédagogique :
KNeighborsClassifier(n_neighbors=3)— étonnamment performant sur MNIST (~97 % d'accuracy), mais lent en prédiction.LogisticRegression(max_iter=1000)— référence linéaire (~92 %).RandomForestClassifier(n_estimators=100)— solide (~96 %), rapide à entraîner.SVC(kernel="rbf", C=10, gamma="scale")— un peu plus précis (~98 %) mais coûteux à entraîner sur tout le dataset.
from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, confusion_matrix X_train, X_test, y_train, y_test = train_test_split( X / 255.0, y, test_size=0.2, stratify=y, random_state=42 ) clf = LogisticRegression(max_iter=1000) clf.fit(X_train, y_train) y_pred = clf.predict(X_test) print(accuracy_score(y_test, y_pred))
La matrice de confusion est l'outil de diagnostic visuel par excellence : elle montre, sur les 10×10 cellules, où les confusions ont lieu. Attendez-vous à voir le couple (4, 9) et le couple (3, 5) ressortir.
import seaborn as sns cm = confusion_matrix(y_test, y_pred) sns.heatmap(cm, annot=True, fmt="d", cmap="Blues")
Pour aller au-delà des 98 % d'accuracy, il faudrait passer aux réseaux de neurones convolutifs — ce qui est le sujet du deuxième parcours du cours, le bloc Deep Learning. MNIST est ici le lien naturel entre ML classique et DL.
Pour aller plus loin
- Dataset Kaggle (version CSV) : https://www.kaggle.com/datasets/oddrationale/mnist-in-csv
- Page historique : http://yann.lecun.com/exdb/mnist/
- Pour la suite : compétitions Kaggle Digit Recognizer et Fashion-MNIST (variante plus difficile sur des vêtements).
Synthèse méthodologique
Ces quatre projets ne demandent aucune technique nouvelle par rapport aux chapitres ML 1 à 4, mais ils diffèrent radicalement dans leurs pièges : haute dimension et redondance pour Mercedes, déséquilibre et fuite d'imputation pour Stroke, hétérogénéité des types et valeurs manquantes structurelles pour Ames, taille et visualisation pour MNIST. Un bon réflexe, lorsqu'on aborde un dataset inconnu, est de se demander :
- Quel est le type de problème ? Régression, classification binaire, multi-classes ? Quelle métrique y est associée par défaut, et quelle métrique est pertinente pour le métier ?
- Quels sont les types de variables ? Numériques, catégorielles nominales, ordinales, binaires ? Quelle stratégie d'encodage et de mise à l'échelle pour chacune ?
- Quels sont les défauts du dataset ? Valeurs manquantes (réelles ou structurelles), déséquilibre de classes, outliers, asymétrie de la cible, redondance entre colonnes, modalités rares ?
- Quelles familles de modèles essayer en premier ? La règle saine : une baseline triviale (Dummy), un modèle linéaire régularisé, un modèle à arbres de boost. Ne pas commencer par le modèle le plus complexe.
- Comment valider proprement ? Cross-validation stratifiée si classification, K-fold simple sinon. Le pipeline complet (prétraitement + modèle) doit être passé à
cross_val_scorepour éviter la fuite.
C'est cette grille de lecture, plutôt qu'une recette de cuisine, que vous devez avoir intériorisée à la fin du cours. Les notebooks corrigés du chapitre 5 montrent une mise en œuvre détaillée pour chacun des quatre projets ; servez-vous-en comme références, pas comme modèles à recopier. Le vrai apprentissage commence quand vous attaquez un cinquième dataset — celui de votre projet de fin de module — sans filet.
Pour aller plus loin
- Compétitions Kaggle associées :
- Mercedes-Benz Greener Manufacturing : https://www.kaggle.com/c/mercedes-benz-greener-manufacturing
- House Prices: Advanced Regression Techniques : https://www.kaggle.com/c/house-prices-advanced-regression-techniques
- Digit Recognizer (MNIST) : https://www.kaggle.com/c/digit-recognizer
- Datasets supplémentaires pour s'entraîner :
- Stroke Prediction Dataset : https://www.kaggle.com/datasets/fedesoriano/stroke-prediction-dataset
- MNIST en CSV : https://www.kaggle.com/datasets/oddrationale/mnist-in-csv
- Lectures recommandées :
- Aurélien Géron, Hands-On Machine Learning with Scikit-Learn, Keras and TensorFlow, O'Reilly — les chapitres 2 et 3 reprennent la démarche projet sur d'autres datasets.
- Documentation officielle scikit-learn, section User Guide / Putting it all together.
- Les notebooks
pyim59publiés sur Kaggle, qui accompagnent ce cours en version corrigée et en version étudiant pour les trois langues (FR / EN / ZH).