Machine Learning

Fuite corrigée : sélection de features sur tout le dataset

Sélectionner les features corrélées à la cible AVANT la cross-validation produit des AUC mirobolantes sur du bruit pur — démonstration chiffrée, puis correction par pipeline.

Cas d'usage

Comprendre pourquoi un score de CV à 0.9 peut être un artefact complet sur données larges (génomique, finance).

Prérequis

scikit-learn, numpy

Python
import numpy as np
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline

rng = np.random.default_rng(0)
X_bruit = rng.normal(size=(200, 5000))    # bruit pur, AUCUN signal
y_bruit = rng.integers(0, 2, 200)

# INCORRECT : sélection sur TOUT le dataset, puis CV
X_sel = SelectKBest(f_classif, k=20).fit_transform(X_bruit, y_bruit)
auc_triche = cross_val_score(LogisticRegression(), X_sel, y_bruit,
                             cv=5, scoring="roc_auc").mean()

# CORRECT : la sélection vit dans le pipeline, refittée par fold
pipe = make_pipeline(SelectKBest(f_classif, k=20), LogisticRegression())
auc_vraie = cross_val_score(pipe, X_bruit, y_bruit,
                            cv=5, scoring="roc_auc").mean()

print(f"AUC avec fuite : {auc_triche:.3f}   <- signal fantôme")
print(f"AUC corrigée   : {auc_vraie:.3f}   <- ~0.5, comme attendu")

Résultat

AUC avec fuite : 0.852   <- signal fantôme
AUC corrigée   : 0.497   <- ~0.5, comme attendu
>>> X_bruit.shape, float(y_bruit.mean())
((200, 5000), 0.515)
Fuite de donnéesFeature selectionAnti-patternDémonstration

Snippets liés

Retour au Data Lab