Skip to content

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

Comme le module 3, cette leçon documente un résultat réellement obtenu en préparant ce cours, pas un exemple construit pour la démonstration.

Un premier entraînement, en apparence concluant

Section titled “Un premier entraînement, en apparence concluant”
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
feature_cols = ["taux_retard_recent", "montant_moyen_recent", "ecart_taux_secteur",
"secteur_BTP", "secteur_Commerce", "secteur_Industrie", "secteur_Services"]
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
clf = RandomForestClassifier(n_estimators=200, random_state=42)
clf.fit(X_train_scaled, y_train)
for name, imp in sorted(zip(feature_cols, clf.feature_importances_), key=lambda x: -x[1]):
print(f"{name}: {imp:.4f}")
montant_moyen_recent: 0.8246
secteur_BTP: 0.0498
taux_retard_recent: 0.0459
ecart_taux_secteur: 0.0450
secteur_Services: 0.0190
secteur_Commerce: 0.0099
secteur_Industrie: 0.0057

Le montant moyen récent des factures capte à lui seul 82 % de l’importance totale. Un résultat qui devrait immédiatement éveiller les soupçons : rien, dans la construction des données de ce module, ne relie le montant d’une facture au fait qu’elle soit payée en retard — seul le secteur du client détermine réellement le risque.

Pourquoi cette feature ressort-elle autant ?

Section titled “Pourquoi cette feature ressort-elle autant ?”

feature_importances_ d’un RandomForestClassifier mesure, par défaut, la réduction moyenne d’impureté (Gini) apportée par chaque feature à chaque nœud de chaque arbre — une métrique connue pour être biaisée en faveur des features continues à forte cardinalité. montant_moyen_recent prend potentiellement une valeur différente par ligne, ce qui offre à l’algorithme d’innombrables seuils de coupure possibles pour, involontairement, mémoriser des particularités du jeu d’entraînement plutôt qu’apprendre un signal réel — quand bien même le split est fait par client (leçon précédente). Une variable catégorielle à 4 modalités (secteur) n’offre, elle, que quelques coupures possibles.

La correction : écarter la feature sans signal

Section titled “La correction : écarter la feature sans signal”
feature_cols = ["taux_retard_recent", "ecart_taux_secteur",
"secteur_BTP", "secteur_Commerce", "secteur_Industrie", "secteur_Services"]
# ... reentrainement ...
secteur_BTP: 0.3408
taux_retard_recent: 0.2202
ecart_taux_secteur: 0.2172
secteur_Services: 0.1235
secteur_Commerce: 0.0588
secteur_Industrie: 0.0396

Une fois montant_moyen_recent écartée, le classement retrouve du sens : secteur_BTP domine, cohérent avec le taux de retard du BTP (40 %) très supérieur aux autres secteurs dans les données générées pour ce module.

Une feature avec une importance anormalement élevée mérite d’être questionnée avant d’être célébrée. Elle peut révéler une vraie découverte… ou un artefact statistique (biais de cardinalité, fuite de données, corrélation avec l’identité d’une entité plutôt qu’avec le phénomène étudié).

Dans un contexte professionnel, une piste pour trancher plus rigoureusement est la permutation importance (sklearn.inspection.permutation_importance), moins sensible à ce biais qu’une importance basée sur l’impureté — une piste volontairement laissée pour approfondissement plutôt que traitée ici en détail.

👉 Entraîner une forêt aléatoire et lire une matrice de confusion


Junior TSAFACK – 12/09/2026