Regularización overfitting

Regularización para reducir el overfitting

El overfitting aparece cuando un modelo aprende demasiado bien los patrones y el ruido del conjunto de entrenamiento, perdiendo capacidad de generalización en datos nuevos. Una forma eficaz de mitigar este problema es regularizar los modelos lineales. La regularización introduce un término de penalización en la función de coste que desincentiva los coeficientes grandes y, por tanto, simplifica el modelo. En otras palabras, la regularización reduce la complejidad del modelo al penalizar pesos grandes. Un valor alto del parámetro de regularización conduce a modelos más simples, mientras que valores bajos aumentan el riesgo de sobreajuste.

En este artículo veremos tres técnicas populares de regularización y cómo implementarlas con scikit‑learn: Ridge (L2), Lasso (L1) y ElasticNet. Cada una aplica la penalización de manera distinta y, por tanto, presenta ventajas y desventajas diferentes.

Ridge Regression (L2)

La regresión ridge modifica la función de coste original sumando el cuadrado de la norma L2 de los coeficientes multiplicado por un parámetro α.

El parámetro α≥0 controla la cantidad de contracción: a mayor α, mayor es el grado de penalización y más robustos se vuelven los coeficientes frente a la colinealidad. Este método no anula variables, sino que reduce todos los coeficientes de manera proporcional. El algoritmo implementado en Ridge minimiza esta expresión y almacena los coeficientes en el atributo coef_.

Ejemplo en Python

En el ejemplo siguiente utilizamos un conjunto sintético con 100 muestras y 12 características (hemos duplicado dos de las variables para introducir correlación) y comparamos un modelo de regresión lineal convencional con uno ridge (α=1):

import numpy as np
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error# Datos sintéticos con correlaciones
X, y, true_coef = make_regression(n_samples=100, n_features=10,
n_informative=5, noise=10, coef=True,
random_state=42)
# Añadimos variables altamente correlacionadas
X = np.hstack([X, X[:, :2] + 0.01*np.random.randn(100, 2)])# Dividimos en entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
random_state=42)# Regresión lineal estándar
lin_reg = LinearRegression().fit(X_train, y_train)
y_pred_lr = lin_reg.predict(X_test)
rmse_lr = np.sqrt(mean_squared_error(y_test, y_pred_lr))# Regresión ridge
ridge_reg = Ridge(alpha=1.0).fit(X_train, y_train)
y_pred_ridge = ridge_reg.predict(X_test)
rmse_ridge = np.sqrt(mean_squared_error(y_test, y_pred_ridge))

print(f’RMSE lineal: {rmse_lr:.2f})
print(f’RMSE ridge : {rmse_ridge:.2f})

Lasso (L1)

La técnica Lasso (Least Absolute Shrinkage and Selection Operator) añade una penalización basada en la norma L1 de los coeficientes.

Una característica clave del Lasso es que produce soluciones dispersas: algunos coeficientes se reducen exactamente a cero, lo que lo hace útil para seleccionar variables. Esta tendencia a preferir soluciones con menos coeficientes no nulos lo convierte en una herramienta habitual para problemas con muchas variables potenciales y poca información.

Ejemplo en Python

from sklearn.linear_model import Lasso

lasso_reg = Lasso(alpha=0.1).fit(X_train, y_train)
y_pred_lasso = lasso_reg.predict(X_test)
rmse_lasso = np.sqrt(mean_squared_error(y_test, y_pred_lasso))

num_nonzero = np.sum(np.abs(lasso_reg.coef_) > 1e-6)

print(f’RMSE lasso: {rmse_lasso:.2f})
print(f’Coeficientes no nulos: {num_nonzero})

Al ejecutar este fragmento sobre el mismo dataset, el Lasso obtiene un RMSE similar al de la regresión sin regularizar pero reduce el número de coeficientes activos. Esa propiedad lo convierte en un método de selección de variables integrado: variables con coeficientes anulados pueden descartarse del modelo sin perjudicar la predicción.

ElasticNet

La ElasticNet combina las penalizaciones L1 y L2 en una única función objetivo.

ElasticNet permite aprender un modelo disperso (al igual que Lasso) manteniendo las propiedades de regularización de Ridge. Además es especialmente útil cuando hay varias características correlacionadas, ya que tiende a seleccionar conjuntamente las variables relacionadas.

Ejemplo en Python

from sklearn.linear_model import ElasticNet

elastic_reg = ElasticNet(alpha=0.1, l1_ratio=0.5).fit(X_train, y_train)
y_pred_elastic = elastic_reg.predict(X_test)
rmse_elastic = np.sqrt(mean_squared_error(y_test, y_pred_elastic))

num_nonzero_elastic = np.sum(np.abs(elastic_reg.coef_) > 1e-6)

print(f’RMSE elastic net: {rmse_elastic:.2f})
print(f’Coeficientes no nulos: {num_nonzero_elastic})

El parámetro l1_ratio permite interpolar entre los extremos: con ρ=1 tenemos Lasso puro; con ρ=0 tenemos Ridge. Al ajustar ambos parámetros con ElasticNetCV podemos obtener un equilibrio adecuado entre sparsity y estabilidad.

Haciendo un resumen de cada técnica:

  • Ridge (L2) añade la suma de los cuadrados de los coeficientes a la función de coste. Esto reduce la varianza del modelo y estabiliza los coeficientes cuando existen variables correlacionadas, pero no elimina variables.

  • Lasso (L1) incorpora la suma de los valores absolutos de los coeficientes y fuerza a algunos a ser exactamente cero, ofreciendo un mecanismo de selección de características.

  • ElasticNet mezcla ambas aproximaciones con un parámetro de mezcla l1_ratio. Permite obtener un compromiso entre la sparsity del Lasso y la robustez del Ridge, siendo útil cuando hay múltiples variables altamente correlacionadas.

En la práctica, la elección del tipo de regularización y del valor óptimo de α (y de l1_ratio en el caso de ElasticNet) depende de la estructura de los datos. Estos hiperparámetros deben calibrarse mediante validación cruzada para evitar tanto el sobreajuste (valores demasiado bajos) como el subajuste (valores excesivos). Scikit‑learn proporciona las clases RidgeCV, LassoCV y ElasticNetCV que realizan este ajuste automático. Con la regularización adecuada, los modelos lineales se vuelven más robustos, interpretables y generalizables.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *