Skip to content

Découper les données par client, pas par ligne

factures_encoded = pd.get_dummies(factures, columns=["secteur"], prefix="secteur")

pd.get_dummies transforme la colonne catégorielle secteur en plusieurs colonnes binaires (secteur_BTP, secteur_Commerce, …) — l’encodage one-hot, nécessaire car un modèle scikit-learn attend des nombres, pas du texte.

Le problème d’un split aléatoire classique

Section titled “Le problème d’un split aléatoire classique”

Le module 1 a posé la règle : séparer train et test avant tout entraînement. Mais comment séparer compte aussi. Un même client apparaît dans plusieurs lignes (une par facture). Si train_test_split classique répartit les lignes au hasard, des factures du même client peuvent se retrouver à la fois dans le train et dans le test.

Pourquoi est-ce un problème ? Le modèle pourrait alors se caler sur des particularités propres à ce client précis — vues pendant l’entraînement — plutôt que d’apprendre un signal réellement généralisable à de nouveaux clients jamais rencontrés. La performance mesurée sur le test serait alors optimiste, et ne se reproduirait pas sur de vrais nouveaux clients.

from sklearn.model_selection import GroupShuffleSplit
groups = factures_encoded["client"].values
y = factures_encoded["paye_en_retard"].values
splitter = GroupShuffleSplit(test_size=0.2, n_splits=1, random_state=42)
train_idx, test_idx = next(splitter.split(factures_encoded, y, groups=groups))
print("clients en train:", len(set(groups[train_idx])), "en test:", len(set(groups[test_idx])))
assert set(groups[train_idx]).isdisjoint(set(groups[test_idx]))
clients en train: 48 en test: 12

GroupShuffleSplit répartit des groupes entiers (ici, tous les clients) entre train et test, jamais un groupe partagé entre les deux. L’assertion isdisjoint (ensembles disjoints) confirme qu’aucun client n’apparaît des deux côtés.

Ce principe s’applique dès qu’une même entité produit plusieurs lignes : plusieurs mesures d’un même capteur, plusieurs commandes d’un même client, plusieurs images d’un même patient. La question à se poser systématiquement : « le modèle doit-il généraliser à de nouvelles entités, ou seulement prédire de nouvelles observations d’entités déjà connues ? » — la réponse détermine s’il faut splitter par ligne ou par groupe.

👉 Un piège réel : l’importance trompeuse d’une feature


Junior TSAFACK – 12/09/2026