Flujo con y sin data leakage para el parámetro AUC
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from sklearn.preprocessing import MinMaxScaler, OrdinalEncoder
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.metrics import roc_auc_score
df = pd.read_csv("../data/heart.csv")
categoricas = ['Sex', 'ChestPainType', 'RestingECG', 'ExerciseAngina', 'ST_Slope']
numericas = ['Age', 'RestingBP', 'Cholesterol', 'FastingBS', 'MaxHR', 'Oldpeak']
X = df.drop("HeartDisease", axis=1)
y = df["HeartDisease"]
# Flujo CON fuga
encoder_leaky = OrdinalEncoder()
X_leaky = X.copy()
X_leaky[categoricas] = encoder_leaky.fit_transform(X_leaky[categoricas])
X_leaky["leaky_feature"] = y + np.random.normal(0, 0.01, size=len(y))
scaler = MinMaxScaler()
X_scaled = scaler.fit_transform(X_leaky)
X_train_l, X_test_l, y_train_l, y_test_l = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
grid_l = GridSearchCV(SVC(probability=True), param_grid={"C": [0.1, 1, 10], "gamma": [0.01, 0.1]}, cv=5, scoring="roc_auc")
grid_l.fit(X_train_l, y_train_l)
auc_l = roc_auc_score(y_test_l, grid_l.predict_proba(X_test_l)[:, 1])
# Flujo SIN fuga
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
preprocessor = ColumnTransformer([
('cat', OrdinalEncoder(), categoricas),
('num', MinMaxScaler(), numericas)
])
pipe = Pipeline([("prep", preprocessor), ("svc", SVC(probability=True))])
param_grid = {"svc__C": [0.1, 1, 10], "svc__gamma": [0.01, 0.1]}
grid = GridSearchCV(pipe, param_grid, cv=5, scoring="roc_auc")
grid.fit(X_train, y_train)
auc = roc_auc_score(y_test, grid.predict_proba(X_test)[:, 1])
print(f"AUC con fuga: {auc_l:.3f}")
print(f"AUC sin fuga: {auc:.3f}")AUC con fuga: 1.000
AUC sin fuga: 0.920
Se puede ver cómo el AUC con fuga puede ser engañoso porque muestra un modelo perfecto mientras que el sin fuga muestra un AUC del 0.920 el cual es correcto