Encodage des variables catégorielles
⏱ 55 minLes algorithmes ML travaillent avec des nombres. Encoder les variables catégorielles correctement est critique — un mauvais encodage peut introduire des biais ou faire exploser la dimensionnalité.
One-Hot Encoding (OHE) — pour les catégories nominales sans ordre
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
# Exemple : couleur n'a pas d'ordre naturel
df = pd.DataFrame({"couleur": ["rouge", "bleu", "vert", "rouge", "bleu"]})
# Pandas get_dummies
ohe_df = pd.get_dummies(df["couleur"], prefix="couleur", drop_first=True)
# drop_first=True évite la multicolinéarité (dummy variable trap)
# Sklearn (pour pipelines)
enc = OneHotEncoder(sparse_output=False, drop="first", handle_unknown="ignore")
X_enc = enc.fit_transform(df[["couleur"]])
# handle_unknown="ignore" : si une nouvelle catégorie apparaît en test → zéros
⚠️ Quand NE PAS utiliser OHE ?
Si une variable a > 30 catégories (villes, codes postaux), OHE crée trop de colonnes → utiliser Target Encoding.
Ordinal Encoding — pour les catégories avec un ordre
from sklearn.preprocessing import OrdinalEncoder
# ✅ niveau d'éducation a un ordre naturel
df["éducation"] = ["Lycée", "Licence", "Master", "Doctorat", "Lycée"]
oe = OrdinalEncoder(categories=[["Lycée", "Licence", "Master", "Doctorat"]])
df["éducation_enc"] = oe.fit_transform(df[["éducation"]])
# → [0, 1, 2, 3, 0]
Target Encoding — pour les catégories à haute cardinalité
# Remplace chaque catégorie par la moyenne de la cible pour cette catégorie
# Parfait pour : villes, codes postaux, produits, utilisateurs
import numpy as np
def target_encode(train_df, test_df, col, target, n_folds=5, smoothing=10):
"""Target encoding avec régularisation pour éviter le data leakage."""
global_mean = train_df[target].mean()
# Calculer la moyenne par catégorie avec smoothing
stats = train_df.groupby(col)[target].agg(["mean", "count"])
# Smoothing : pondère vers la moyenne globale si peu d'exemples
smooth = (stats["count"] * stats["mean"] + smoothing * global_mean) / (stats["count"] + smoothing)
train_df[f"{col}_te"] = train_df[col].map(smooth).fillna(global_mean)
test_df[f"{col}_te"] = test_df[col].map(smooth).fillna(global_mean)
return train_df, test_df
# ⚠️ TOUJOURS encoder sur le train uniquement, appliquer sur test
train, test = target_encode(train, test, "ville", "prix")
Résumé : quel encodage choisir ?
| Situation | Encodage recommandé |
|-----------|---------------------|
| ≤ 10 catégories, sans ordre | One-Hot Encoding |
| Catégories ordonnées | Ordinal Encoding |
| > 20 catégories | Target Encoding |
| Texte libre | TF-IDF ou embeddings |
✍️ Exercices de la leçon
2 exercicesFais-les dans l'ordre, dans un vrai fichier .py — pas dans ta tête. Ne déplie la correction qu'après avoir écrit quelque chose, même faux.
Exercice A — Trois variables, trois encodages
Application directe · Tu appliques ce que tu viens de lire.
import pandas as pd
df = pd.DataFrame({
"couleur": ["rouge", "bleu", "vert", "rouge", "bleu"],
"education": ["Lycée", "Master", "Licence", "Doctorat", "Lycée"],
"ville": ["Dakar", "Abidjan", "Lomé", "Dakar", "Cotonou"],
"achat": [0, 1, 1, 0, 1],
})
Encode les trois variables catégorielles, chacune avec la méthode adaptée à sa nature :
- 1.
couleur— nominale, faible cardinalité - 2.
education— ordinale, l'ordre a un sens - 3.
ville— nominale, cardinalité potentiellement très élevée en vrai
Justifie chaque choix en une phrase avant de coder.
Exercice B — Cinq variables, aucune consigne
Page blanche · Aucun squelette : à toi de choisir la méthode.
Page blanche. Décision avant code.
Un dataset de prédiction de défaut de paiement contient ces cinq variables catégorielles :
| Variable | Modalités distinctes | Exemple |
|---|---|---|
| type_contrat | 3 | CDI, CDD, Indépendant |
| code_postal | 6 200 | 75011, 33000… |
| niveau_risque | 5 | Très faible → Très élevé |
| marque_vehicule | 47 | Toyota, Peugeot… |
| id_client | 180 000 | C-000184… |
Pour chacune, décide et justifie par écrit :
- l'encodage retenu, et pourquoi
- combien de colonnes il va créer
- le risque principal de ce choix
Puis assemble le tout dans un ColumnTransformer scikit-learn.
Attention : l'une de ces variables ne doit pas être encodée du tout. À toi de voir laquelle et de dire pourquoi.