Regresión Ridge y Lasso con regularización

Nivel
Scikit Learn
Scikit Learn
Actualizado: 18/04/2026

Regularización en regresión lineal

La regresión lineal estándar minimiza la suma de los errores al cuadrado entre las predicciones y los valores reales. Cuando el conjunto de datos tiene muchas características o hay alta correlación entre ellas, el modelo puede sobreajustarse: aprende el ruido del conjunto de entrenamiento y pierde capacidad de generalizar a datos nuevos.

La regularización introduce un término de penalización en la función de coste que limita la magnitud de los coeficientes, reduciendo el sobreajuste. En Scikit-learn hay dos variantes principales:

  • Ridge (regularización L2): penaliza la suma del cuadrado de los coeficientes.
  • Lasso (regularización L1): penaliza la suma del valor absoluto de los coeficientes, lo que puede forzar algunos coeficientes exactamente a cero (selección de características implícita).

Ridge Regressión (L2)

En Ridge, la función de coste es:

J(w) = ||Xw - y||² + alpha * ||w||²

El parámetro alpha controla la fuerza de la penalización. Un alpha grande reduce más los coeficientes, aumentando el sesgo pero reduciendo la varianza.

from sklearn.linear_model import Ridge
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np

# Generar datos sintéticos con ruido
X, y = make_regression(n_samples=200, n_features=20, noise=15, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Entrenar modelo Ridge con alpha=1.0
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
y_pred = ridge.predict(X_test)

print(f"R²: {r2_score(y_test, y_pred):.4f}")
print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")
print(f"Coeficientes (primeros 5): {ridge.coef_[:5]}")

Efecto de alpha en Ridge

Podemos analizar cómo varía el rendimiento y los coeficientes al cambiar alpha:

from sklearn.linear_model import Ridge
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
import numpy as np

X, y = make_regression(n_samples=200, n_features=20, noise=15, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

alphas = [0.001, 0.1, 1.0, 10.0, 100.0, 1000.0]

for alpha in alphas:
    ridge = Ridge(alpha=alpha)
    ridge.fit(X_train, y_train)
    r2 = r2_score(y_test, ridge.predict(X_test))
    norma = np.linalg.norm(ridge.coef_)
    print(f"alpha={alpha:8.3f} -> R²={r2:.4f}, ||w||={norma:.2f}")

A medida que alpha crece, la norma de los coeficientes disminuye pero también puede bajar el R².

Lasso Regressión (L1)

La función de coste de Lasso es:

J(w) = ||Xw - y||² + alpha * ||w||₁

La penalización L1 puede llevar coeficientes exactamente a cero, actuando como un mecanismo de selección de características.

from sklearn.linear_model import Lasso
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
import numpy as np

# Datos con solo 5 características relevantes de 20
X, y = make_regression(n_samples=200, n_features=20, n_informative=5,
                        noise=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

lasso = Lasso(alpha=1.0)
lasso.fit(X_train, y_train)

print(f"R²: {r2_score(y_test, lasso.predict(X_test)):.4f}")
print(f"Características no nulas: {np.sum(lasso.coef_ != 0)}")
print(f"Coeficientes: {lasso.coef_}")

Con n_informative=5, Lasso idealmente forzará los otros 15 coeficientes a cero.

Comparación: LinearRegressión vs Ridge vs Lasso

from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score, mean_squared_error
import numpy as np

X, y = make_regression(n_samples=300, n_features=30, n_informative=10,
                        noise=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

modelos = {
    'LinearRegression': LinearRegression(),
    'Ridge(alpha=1)': Ridge(alpha=1.0),
    'Lasso(alpha=1)': Lasso(alpha=1.0),
}

for nombre, modelo in modelos.items():
    modelo.fit(X_train, y_train)
    y_pred = modelo.predict(X_test)
    r2 = r2_score(y_test, y_pred)
    mse = mean_squared_error(y_test, y_pred)
    coef_no_nulos = np.sum(modelo.coef_ != 0)
    print(f"{nombre:25s} R²={r2:.4f}  MSE={mse:.1f}  coefs≠0: {coef_no_nulos}")

ElasticNet: combinando L1 y L2

ElasticNet combina las penalizaciones de Ridge y Lasso mediante el parámetro l1_ratio:

from sklearn.linear_model import ElasticNet
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score

X, y = make_regression(n_samples=200, n_features=20, n_informative=8,
                        noise=15, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# l1_ratio=0 -> Ridge puro, l1_ratio=1 -> Lasso puro
elastic = ElasticNet(alpha=0.5, l1_ratio=0.5)
elastic.fit(X_train, y_train)
print(f"R²: {r2_score(y_test, elastic.predict(X_test)):.4f}")

Selección automática de alpha con RidgeCV y LassoCV

Scikit-learn ofrece versiones con validación cruzada integrada para seleccionar el mejor alpha automáticamente:

from sklearn.linear_model import RidgeCV, LassoCV
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split

X, y = make_regression(n_samples=300, n_features=20, noise=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# RidgeCV prueba cada alpha con validación cruzada
alphas = [0.01, 0.1, 1.0, 10.0, 100.0]
ridge_cv = RidgeCV(alphas=alphas, cv=5)
ridge_cv.fit(X_train, y_train)
print(f"Ridge - Mejor alpha: {ridge_cv.alpha_}")
print(f"Ridge - R² test: {ridge_cv.score(X_test, y_test):.4f}")

# LassoCV hace lo mismo con validación cruzada
lasso_cv = LassoCV(alphas=alphas, cv=5, max_iter=5000)
lasso_cv.fit(X_train, y_train)
print(f"Lasso - Mejor alpha: {lasso_cv.alpha_}")
print(f"Lasso - R² test: {lasso_cv.score(X_test, y_test):.4f}")

Cuándo usar cada técnica

| Situación | Técnica recomendada | |-----------|---------------------| | Sobreajuste con muchas características correlacionadas | Ridge | | Datos con muchas características irrelevantes | Lasso (selección implícita) | | Combinación de correlaciones y características irrelevantes | ElasticNet | | Selección automática de alpha | RidgeCV / LassoCV |

La elección entre Ridge y Lasso depende del problema concreto: si se sospecha que pocas características son realmente relevantes, Lasso puede ofrecer un modelo más interpretable al forzar coeficientes a cero. Si todas las características aportan algo, Ridge suele comportarse mejor.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Scikit Learn es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Scikit Learn

Explora más contenido relacionado con Scikit Learn y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Comprender la regularización L1 (Lasso) y L2 (Ridge) y su efecto en los coeficientes del modelo. Implementar Ridge y Lasso con Scikit-learn y ajustar el hiperparámetro alpha. Comparar el rendimiento de LinearRegressión, Ridge y Lasso sobre un mismo conjunto de datos. Utilizar ElasticNet como combinación de ambas regularizaciones. Seleccionar el valor óptimo de alpha mediante validación cruzada con RidgeCV y LassoCV.