Quand vos « meilleures » features dégradent votre modèle
Vous connaissez ce sentiment ? Vous passez des jours à concevoir une feature magnifique. Elle capture exactement le signal que vous cherchiez. Vous entraînez, évaluez, et votre F1 classe 2 passe de 0,72 à 0,78. Vous souriez. Puis vous soumettez au leaderboard et votre score chute. Qu'est-ce qui s'est passé ? Vous venez de rencontrer le trade-off du feature engineering.
C'est un piège dans lequel tombe presque tout data scientist au moins une fois. Je m'y suis fait prendre il y a quelques mois, et ça m'a coûté une bonne semaine de debug. Alors laissez-moi vous expliquer ce qui se passe vraiment sous le capot, pourquoi vos features manuelles peuvent se retourner contre vous, et comment construire un workflow d'évaluation qui ne vous ment pas.
Le piège classique : le gain d'une métrique est la perte d'une autre
Imaginez la scène. Je construisais un modèle de classification multi-classes pour un client. Le baseline était correct. J'ajoute deux features artisanales : **Gravité Impact** et **Ratio Énergie**. Toutes deux dérivées de données capteurs brutes, conçues pour attraper une classe de panne rare. Elles avaient du sens physique. En validation, le F1 classe 2 passe de 0,72 à 0,78. Beau, non ?
Pas si vite. Quand je regarde l'ensemble, le F1 classes 0 et 1 a chuté tous les deux. Le leaderboard — qui utilise une moyenne pondérée sur toutes les classes — était plus bas que mon baseline. Le modèle avait effectivement appris à sacrifier les classes majoritaires pour faire briller la classe minoritaire.
Ce n'est pas de la malchance. C'est la réalité mathématique d'un budget de probabilité partagé. Dans la plupart des modèles multi-classes, augmenter la confiance d'une classe réduit celle des autres. Si vos nouvelles features sont corrélées avec les existantes, vous n'ajoutez pas d'information — vous amplifiez du bruit et du biais.
Pourquoi les features manuelles se retournent-elles contre vous ?
La multicolinéarité, tueuse silencieuse
Quand votre nouvelle feature est corrélée avec deux ou trois features existantes, le modèle répartit le crédit entre elles. Dans les modèles à base d'arbres, ça peut masquer des splits importants. Dans les modèles linéaires, ça gonfle les coefficients. Résultat ? Des prédictions moins stables, surtout sur données inédites.
Le pire, c'est que la multicolinéarité ne dégrade pas toujours l'accuracy en entraînement. Elle peut même vous aider à mémoriser du bruit. Mais dès que la distribution test bouge légèrement, votre belle feature devient un boulet.
Le trade-off Précision/Rappel
Si vous avez engineer une feature pour trouver la classe 2, vous augmentez probablement son rappel tout en détruisant la précision de la classe 1. Supposons que le seuil bouge. Plus d'exemples classés en classe 2, mais beaucoup sont en réalité classe 1 ou 0. Votre score macro chute même si votre « classe cible » a l'air mieux.
Je vois ça tout le temps en détection de fraude. Quelqu'un construit une feature qui attrape plus de fraude, mais qui flag aussi une tonne de transactions légitimes. Le rappel fraude monte, mais le taux de faux positifs double. Dans le vrai monde, ça veut dire clients en colère et équipe support stressée.
Les métriques leaderboard sont généralement agrégées
La plupart des leaderboards utilisent une métrique scalaire unique — accuracy, macro-F1, kappa pondéré, ou log loss. Ce scalaire cache le détail par classe. Si vous optimisez pour une tranche, vous n'optimisez pas pour le tout. Un gain de 5 points en F1 classe 2 peut être effacé par une chute de 3 points sur deux autres classes, selon les poids.
C'est pour ça que la première chose que je fais maintenant, c'est lire la métrique de la compet ou du projet *très* attentivement. Si c'est du F1 pondéré, les améliorations sur une classe rare sont minuscules. Si c'est du macro-F1, chaque classe compte équitablement, même celles qui vous intéressent pas.
Exemple concret : le cas des données capteurs
Prenons un exemple réel. Imaginez une usine avec capteurs température, vibration, pression. Modèle baseline : 0,85 macro-F1 sur trois classes de pannes.
Je crée un **ratio énergie** = amplitude vibration / variance pression. Ça avait du sens physique. Les impacts haute énergie devraient indiquer des pannes sévères. Sur l'entraînement, le F1 classe 2 monte à 0,81. Mais en cross-validation, le gain ne tient pas. Pourquoi ? Le ratio énergie était très corrélé avec vibration brute et pression — multicolinéarité encore. En test, le bruit capteur à basse pression faisait exploser le ratio, envoyant le modèle dans de faux positifs classe 2.
La fix était contre-intuitive : au lieu d'ajouter le ratio brut, j'ai utilisé une feature résiduelle — la partie de la vibration *non* expliquée par la pression. Ce signal orthogonalisé apportait vraiment de l'info nouvelle, et le score leaderboard a monté sur toutes les classes. Leçon : ne demandez pas « ma feature a-t-elle du sens ? » Demandez « ma feature apporte-t-elle de l'info que mon modèle n'a pas déjà ? »
Autre exemple : prédiction churn e-commerce
J'ai bossé avec une boîte de box par abonnement. L'équipe marketing voulait un **score engagement client** combinant fréquence login, tickets support, mentions réseaux sociaux. Ça sonnait bien. Mais le score n'était qu'une somme pondérée de features existantes. Une fois ajouté au modèle, les importance features se mélangent, mais l'AUC bouge pas. Pire, la calibration se dégrade pour les utilisateurs peu engagés parce que le score domine la loss.
On a fini par remplacer le score artisanal par un simple compteur de catégories de features distinctes contactées sur les 7 derniers jours. Cette petite feature, moins corrélée, a donné un vrai lift. La leçon se répète : parfois la feature la moins flashy est la meilleure.
Comment évaluer vos features sans vous faire avoir
1. Construisez un scorecard multi-métriques
Ne suivez pas juste le F1 classe 2. Faites un scorecard qui inclut :
- Macro-F1 et weighted-F1
- Précision et rappel pour chaque classe
- Log loss ou Brier score (pour la calibration)
- Une note sur si les métriques par classe bougent dans le même sens
Voilà ce que j'affiche après chaque expérience :
| Métrique | Baseline | Nouvelle Feature | Verdict |
|---|---|---|---|
| Classe 0 F1 | 0,88 | 0,84 | Mauvais |
| Classe 1 F1 | 0,82 | 0,79 | Mauvais |
| Classe 2 F1 | 0,72 | 0,78 | Bon |
| Macro-F1 | 0,81 | 0,80 | Mauvais |
Un coup d'œil et l'histoire est claire. La belle feature a aidé une classe mais nui aux autres. Sans ce scorecard, j'aurais soumis le modèle et eu une mauvaise surprise.
2. Faites un audit de corrélation
Avant d'ajouter une feature manuelle, checkez sa corrélation avec les existantes. Utilisez `df.corr()` de pandas et regardez les valeurs absolues au-dessus de 0,7. Si votre nouvelle feature est trop proche des autres, envisagez :
- Supprimer une des features redondantes
- Utiliser la résidualisation (régresser la nouvelle feature sur les anciennes, garder le résiduel)
- Faire de la sélection via `SelectKBest` ou `RFECV` de scikit-learn
Le guide officiel feature selection de scikit-learn regorge d'approches pratiques : https://scikit-learn.org/stable/modules/feature_selection.html
3. Utilisez SHAP pour comprendre les effets directionnels
Après l'entraînement, calculez les valeurs SHAP pour voir exactement comment votre nouvelle feature affecte chaque classe. Parfois une feature aide la classe 2 mais nuit activement à la classe 1. Un summary plot SHAP vous le montre direct. La librairie est open-source et bien maintenue sur https://github.com/shap/shap.
J'ai chopé plusieurs features « géniales » qui avaient de fortes valeurs SHAP positives pour une classe mais des valeurs encore plus fortes négatives pour une autre. C'est le trade-off qu'il faut voir *avant* de soumettre.
4. Faites des ablations
Ablation = retirer une feature et voir ce qui se passe. C'est pourtant rare en feature engineering manuel. Je lance toujours trois expériences :
- Baseline avec anciennes features
- Baseline + nouvelle feature
- Baseline + nouvelle feature, moins une ancienne feature corrélée
Si la troisième bat la deuxième, vous avez résolu un problème de multicolinéarité. Si la deuxième est pire que la première, virez la feature. Si la deuxième est meilleure mais que l'éval leaderboard dit non, creusez votre setup de validation.
Troisième exemple : classification triage médical
J'ai bossé sur un prototype de symptom checker. Objectif : trier patients en trois niveaux d'urgence. Je construis un **score comorbidité** en sommant le nombre de pathologies préexistantes. Ça améliore la détection des patients haute urgence, mais ça fait aussi ignorer au modèle la sévérité du symptôme *actuel*. Un patient avec un symptôme léger et une comorbidité était classé haute urgence, alors que son risque réel était faible.
Le problème : ma feature était trop dominante. Le modèle s'est accroché parce que c'était facile à splitter, et a ignoré les features textuelles plus riches et nuancées. C'est un autre trade-off clé : **la dominance de feature**. Une feature artisanale forte peut éclipser des features plus faibles mais plus informatives. La régularisation et les interactions peuvent aider, mais le simple est souvent mieux.
La vraie leçon : les features ne sont pas gratuites
Chaque feature ajoutée augmente la complexité, le temps d'entraînement, et le risque d'overfitting. La régularisation aide, mais elle ne peut pas corriger une feature fondamentalement redondante. Il faut voir chaque feature comme un pari : elle doit justifier sa place en apportant un signal nouveau et stable sur plusieurs métriques.
J'ai aussi appris que quand un leaderboard chute après ajout d'une feature, la cause racine est presque jamais « la métrique est fausse ». C'est que je chassais un optimum local. Le modèle n'est pas bête — il fait exactement ce que je lui ai demandé. J'ai juste demandé la mauvaise chose.
FAQ
Pourquoi mon F1 monte sur une classe mais mon score leaderboard descend ?
Parce que le leaderboard utilise probablement une moyenne pondérée ou macro. Votre modèle sacrifie peut-être précision ou rappel sur d'autres classes pour gagner sur celle que vous visiez. Évaluez toujours la matrice de confusion complète avant de vous emballer.
Quelle est la meilleure façon de gérer les features multicolinéaires ?
Checkez la corrélation d'abord. Si deux features sont très corrélées, virez-en une ou utilisez une version résidualisée de la nouvelle. La régularisation (L1 ou L2) peut stabiliser le modèle, mais supprimer la redondance est généralement plus efficace que d'essayer de la corriger avec des pénalités.
Le feature engineering manuel est-il encore utile en ML moderne ?
Oui, mais seulement quand il encode une expertise métier qui n'est pas déjà dans le modèle. Si une feature n'est qu'une combinaison mathématique de features existantes, elle aidera généralement pas. Si elle capture un signal vraiment nouveau, elle peut être puissante. La clé : vérifier qu'elle apporte vraiment de l'info indépendante.
Comment savoir si une feature aide vraiment ?
Comparez baseline et modèle avec feature sur plusieurs métriques et en cross-validation. Faites une ablation. Regardez feature importance et valeurs SHAP. Si l'amélioration est inconsistante across folds ou métriques, c'est probablement de l'overfitting sur du bruit.
Dernières pensées
Je connais le frisson de construire LA feature parfaite. On a l'impression d'avoir craqué le code. Mais le leaderboard est l'arbitre ultime. Plus tôt vous intégrez l'évaluation multi-métriques dans votre workflow, moins vous perdrez de temps sur des features qui n'aident qu'une tranche du problème.
La prochaine fois que vous êtes sur le point de shipper cette feature « gravité impact » si maline, arrêtez-vous. Demandez-vous : « Est-ce que j'apporte de l'info nouvelle, ou j'amplifie juste un signal que j'ai déjà ? » Votre futur vous — et votre ranking leaderboard — vous remercieront.
Technologie
Comments (0)
No comments yet. Be the first to comment!
Leave a Comment