🔄 MÓDULO 5: "Validación Cruzada y Sobreajuste: Construyendo Modelos que Generalizan"

Objetivo:

Entender por qué un modelo que funciona bien en datos de entrenamiento puede fallar en el mundo real. Aprender a detectar, prevenir y medir el sobreajuste usando técnicas de validación robustas.


5.1 ¿Qué es el Sobreajuste?

Sobreajuste ocurre cuando un modelo aprende demasiado bien los datos de entrenamiento—incluyendo ruido y patrones aleatorios—en lugar de patrones generales. Resultado:

  • ✅ Excelente rendimiento en datos de entrenamiento.
  • ❌ Mal rendimiento en datos nuevos (test o producción).

Imagina un estudiante que memoriza las respuestas del examen en lugar de entender los conceptos. En el examen real, reprueba.


5.2 ¿Cómo Detectar el Sobreajuste?

Método más simple: comparar el rendimiento en entrenamiento vs. validación/test.

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

modelo = LogisticRegression()
modelo.fit(X_train, y_train)

# Rendimiento en entrenamiento
y_train_pred = modelo.predict(X_train)
train_acc = accuracy_score(y_train, y_train_pred)

# Rendimiento en test
y_test_pred = modelo.predict(X_test)
test_acc = accuracy_score(y_test, y_test_pred)

print(f"Precisión en Entrenamiento: {train_acc:.4f}")
print(f"Precisión en Test:     {test_acc:.4f}")

# Si train_acc >> test_acc → ¡Sobreajuste!

⚠️ Ejemplo típico:

  • Precisión en Entrenamiento: 0.998
  • Precisión en Test: 0.821
    → Modelo sobreajustado.

5.3 ¿Qué Causa el Sobreajuste?

  • Modelo demasiado complejo (ej., árbol de decisión con profundidad 20 en un conjunto de datos pequeño).
  • Pocos datos de entrenamiento.
  • Demasiadas características (maldición de la dimensionalidad).
  • Ruido en los datos (etiquetas incorrectas, valores atípicos no tratados).

5.4 Soluciones para Evitar el Sobreajuste

➤ Regularización

Agrega una penalización a la función de pérdida para evitar que los coeficientes sean demasiado grandes.

# Regresión logística con regularización L2 (Ridge)
modelo_l2 = LogisticRegression(penalty='l2', C=1.0)  # C menor = más regularización

# Con L1 (Lasso) para selección automática de características
modelo_l1 = LogisticRegression(penalty='l1', solver='liblinear', C=0.1)

L1 (Lasso): Puede anular coeficientes → selección de características.
L2 (Ridge): Reduce coeficientes pero no los anula → más estable.


➤ Simplificar el Modelo

  • Reducir la profundidad del árbol.
  • Reducir capas/neuronas en redes.
  • Usar menos características (selección de características).

➤ Más Datos

Simple pero poderoso. Más datos representativos ayudan al modelo a aprender patrones más generales.


➤ Validación Cruzada

La mejor herramienta para evaluar la capacidad de generalización de un modelo antes de ver los datos de test.


5.5 Validación Cruzada: Tu Escudo contra el Optimismo

La validación simple (división train/test) puede ser engañosa si la división es afortunada o desafortunada.

Validación cruzada (CV) divide los datos en K pliegues, entrena K veces, cada vez usando un pliegue diferente como validación.

Resultado: una estimación de rendimiento más robusta y confiable.

from sklearn.model_selection import cross_val_score

modelo = LogisticRegression()

# Validación cruzada de 5 pliegues
scores = cross_val_score(modelo, X_train, y_train, cv=5, scoring='roc_auc')

print(f"AUC-ROC por pliegue: {scores}")
print(f"AUC-ROC promedio: {scores.mean():.4f} (+/- {scores.std() * 2:.4f})")

Ventajas:

  • Usa todos los datos para entrenamiento y validación.
  • Reduce la varianza en la estimación de rendimiento.
  • Ideal para comparar modelos o ajustar hiperparámetros.

5.6 Tipos de Validación Cruzada

➤ K-Fold CV (estándar)

Divide en K partes iguales. Cada pliegue se usa una vez como validación.

from sklearn.model_selection import KFold

kf = KFold(n_splits=5, shuffle=True, random_state=42)

➤ K-Fold Estratificado CV

Mantiene las proporciones de clase en cada pliegue. ESPECIALMENTE IMPORTANTE PARA CONJUNTOS DE DATOS DESBALANCEADOS.

from sklearn.model_selection import StratifiedKFold

skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(modelo, X_train, y_train, cv=skf, scoring='roc_auc')

➤ Validación Dejar Uno Afuera (LOO)

Cada pliegue es una sola observación. Muy costoso computacionalmente; solo para conjuntos de datos muy pequeños.


📈 Visualización: Comparando Train/Test vs CV

import numpy as np

# Entrenar y evaluar con train/test simple
modelo.fit(X_train, y_train)
test_score = roc_auc_score(y_test, modelo.predict_proba(X_test)[:,1])

# Evaluar con CV en conjunto de entrenamiento
cv_scores = cross_val_score(modelo, X_train, y_train, cv=5, scoring='roc_auc')

plt.figure(figsize=(8,5))
plt.axhline(y=test_score, color='red', linestyle='--', label=f'Puntaje Test: {test_score:.4f}')
plt.plot(range(1,6), cv_scores, 'bo-', label='Puntajes CV por Pliegue')
plt.axhline(y=cv_scores.mean(), color='blue', linestyle='-', label=f'Promedio CV: {cv_scores.mean():.4f}')
plt.title("Comparación: Validación Cruzada vs Test Final")
plt.xlabel("Pliegue")
plt.ylabel("AUC-ROC")
plt.legend()
plt.grid()
plt.show()

📝 Ejercicio 5.1: Diagnóstico y Prevención de Sobreajuste

Conjunto de datos: fraud_features.csv (preprocesado con características seleccionadas)

Tareas:

  1. Entrenar un modelo de Random Forest con profundidad máxima = 20.
  2. Calcular precisión y AUC-ROC en conjuntos de entrenamiento y test. ¿Hay sobreajuste?
  3. Aplicar validación cruzada estratificada de 5 pliegues en el conjunto de entrenamiento. Comparar AUC-ROC promedio con puntaje de test.
  4. Ahora entrenar un Random Forest con profundidad máxima = 5. Repetir pasos 2 y 3.
  5. Comparar ambos modelos: ¿cuál generaliza mejor? ¿Por qué?
  6. (Opcional) Probar Regresión Logística con regularización (C=0.01) y comparar.

💡 Notas Adicionales:

  • Siempre usa StratifiedKFold para problemas de clasificación desbalanceados.
  • La validación cruzada NO DEBE incluir el conjunto de test final. El conjunto de test es sagrado—se usa solo una vez, al final.
  • El sobreajuste no es inherentemente malo. A veces es inevitable. Lo importante es detectarlo y controlarlo.
  • En competencias de Kaggle, los ganadores usan validación cruzada estratificada con múltiples semillas para asegurar estabilidad.

Course Info

Course: AI-course1

Language: ES

Lesson: Module5