# A tibble: 1 × 3
observaciones_train variables_base columnas_modelo
<int> <dbl> <int>
1 5162 9 60
Regularización: Ridge, LASSO y Elastic Net
2026-07-29
Antes
GLM, logit, inferencia, bootstrap: modelos donde nosotros elegimos la forma.
Hoy
qué hacer cuando ya no confiamos en que esa forma sea la correcta.
Después
dejar que el propio algoritmo aprenda la forma: árboles y ensambles.
Durante todo el curso, cada modelo (LPM, logit, Poisson) compartió un mismo supuesto: nosotros elegimos qué variables entran, qué interacciones importan, qué transformaciones usar. El modelo solo estima los coeficientes.
Las clases 16–18 exploran una pregunta distinta: ¿qué pasa cuando dejamos de confiar en que esa forma elegida a mano sea la correcta? ¿Puede el propio procedimiento de ajuste decidir cuánta complejidad usar — o incluso qué forma tomar?
Referencia principal para las tres clases: James et al. (2021), An Introduction to Statistical Learning, 2ª ed., capítulos 5–6, 8 y 10 (sitio oficial).
Al cierre de cada día, estimar qué horas del día siguiente tendrán demanda alta, para priorizar el rebalanceo de bicicletas.
| Elemento | Se mantiene desde la clase 15 |
|---|---|
| Unidad y horizonte | una hora, hasta 24 horas |
| Target | sobre el percentil 75 aprendido en train |
| Información | calendario, hora y pronóstico meteorológico |
| Costo | falso negativo = 3; falso positivo = 1 |
| Evaluación | partición temporal 60/20/20 |
Hoy no cambiamos la pregunta para favorecer al método. Cambiamos solo cómo se controla una matriz de predictores amplia y correlacionada.
Sigamos usando la misma pregunta sustantiva del curso — ¿cuándo hay demanda alta de bicicletas? — pero démosle al logit una interacción completa entre hora (24 categorías) y mes (12 categorías): mucho más flexible que la interacción hora × día hábil que usamos hasta ahora. Agreguemos esas variables de a poco y observemos qué pasa.
Nótese algo importante: no sabíamos de antemano cuál de estas variables hora×mes era señal y cuál era ruido — todas entraron con la misma justificación teórica (“la demanda varía por hora y por estación”). Hasta ahora controlábamos la complejidad a mano, decidiendo qué interacciones incluir. La pregunta de hoy es si el propio procedimiento de ajuste puede controlar esa complejidad automáticamente, de forma validada.
Antes de la solución, pongamos nombre al fenómeno que acabamos de ver, con una analogía simple.
Sesgo = qué tan lejos del centro caen los tiros en promedio. Varianza = qué tan dispersos están entre sí.
Para un punto x_0, el error cuadrático esperado de un estimador \hat f se descompone en tres piezas:
\mathbb{E}\big[(y_0-\hat f(x_0))^2\big] = \underbrace{\big(\mathbb{E}[\hat f(x_0)]-f(x_0)\big)^2}_{\text{sesgo}^2} + \underbrace{\mathrm{Var}(\hat f(x_0))}_{\text{varianza}} + \underbrace{\sigma^2}_{\text{irreducible}}.
| Símbolo | Significado |
|---|---|
| f(x_0) | la relación verdadera (desconocida) entre predictores y outcome |
| \hat f(x_0) | nuestra estimación, que cambiaría si cambiara la muestra |
| \mathbb{E}[\hat f(x_0)]-f(x_0) | sesgo: error sistemático por usar un modelo demasiado rígido |
| \mathrm{Var}(\hat f(x_0)) | varianza: cuánto cambia el ajuste de muestra a muestra |
| \sigma^2 | ruido irreducible; ninguna técnica lo elimina |
Regularizar aumenta el sesgo a propósito para reducir la varianza — conviene exactamente cuando la caída de varianza supera el aumento de sesgo, que es lo que vimos en la curva de validación.
Sesgo, varianza y error total en función de la complejidad del modelo.
Antes de cualquier fórmula, la idea completa en tres oraciones:
Todo lo que sigue en esta clase es la formalización — y luego la implementación — de estas tres frases.
El módulo completo (clases 15–18) comparte la misma preparación de datos. Primero definimos el outcome y partimos los datos:
Sobre esos datos construimos la matriz de predictores X que usarán Ridge, LASSO y Elastic Net:
# A tibble: 1 × 3
observaciones_train variables_base columnas_modelo
<int> <dbl> <int>
1 5162 9 60
La expansión incluye no linealidad en clima, indicadores de calendario e interacción hora × día hábil — exactamente el tipo de términos que, en la curva de arriba, empujaba el modelo hacia el sobreajuste. temp y atemp son además deliberadamente casi idénticas: veremos que ese tipo de colinealidad es precisamente donde Ridge resulta más útil.
Antes de penalizar nada, fijemos la disciplina de evaluación — ya la usamos antes (bootstrap, validación) pero aquí es central, no un anexo:
| Conjunto | Proporción | Función |
|---|---|---|
| Entrenamiento | 60% | estimar coeficientes |
| Validación | 20% | elegir \alpha y \lambda |
| Test | 20% | estimar desempeño final, una sola vez |
Mirar el test durante el tuning produce filtración de información: el desempeño deja de ser genuinamente fuera de muestra — el mismo problema, en miniatura, que acabamos de ver en la curva de sobreajuste.
# A tibble: 3 × 4
conjunto primer_día último_día horas
<chr> <dbl> <dbl> <int>
1 Entrenamiento 1 219 5162
2 Validación 220 292 1735
3 Test 293 365 1748
Entrenamos con el pasado, elegimos hiperparámetros en un período posterior y reservamos los últimos días para test: una partición aleatoria sería optimista si horas vecinas comparten patrones no observados.
temp y atemp están altamente correlacionadas. En un GLM sin penalizar, esto genera un problema específico: X^\top X se vuelve casi no invertible, y pequeños cambios en la muestra producen coeficientes muy distintos — alta varianza, tal como vimos arriba.
Ridge ataca exactamente ese síntoma: en vez de dejar que los coeficientes crezcan sin control para “explicar” la colinealidad, los penaliza por tamaño.
En la geometría familiar de mínimos cuadrados, agregar una penalización por el tamaño de \boldsymbol\beta es “tirar” al estimador hacia el origen, un poco menos lejos de donde los datos solos lo llevarían.
El estimador Ridge (verde) es el punto donde las curvas de nivel de la pérdida (elipses) tocan primero la región de restricción circular.
Partimos de la pérdida logística y agregamos un costo por coeficientes grandes:
\widehat{\boldsymbol\beta}^{\text{ridge}} =\arg\min_{\boldsymbol\beta} \left\{-\ell(\boldsymbol\beta)+\lambda \underbrace{\frac{1}{2}\sum_{j=1}^{p}\beta_j^2}_{P(\boldsymbol\beta)}\right\}.
| Símbolo | Significado |
|---|---|
| \ell(\boldsymbol\beta) | log-verosimilitud logística: qué tan bien predicen las probabilidades |
| P(\boldsymbol\beta) | penalización: qué tan grandes son los coeficientes |
| \lambda\ge 0 | intensidad de la penalización: el “dial” que elegiremos con validación |
\lambda=0 recupera el ajuste sin penalizar; \lambda grande empuja todos los coeficientes hacia 0. El intercepto nunca se penaliza — no tiene sentido “encogerlo” hacia una demanda promedio de cero.
Con log-odds \eta_i=\beta_0+x_i^\top\boldsymbol\beta y p_i=\sigma(\eta_i):
\ell(\boldsymbol\beta)=\sum_{i=1}^{n}\big[\,y_i\,\eta_i-\log(1+e^{\eta_i})\,\big].
Minimizar -\ell+\lambda P(\boldsymbol\beta) es, entonces, “ajustar bien las probabilidades sin coeficientes desmesurados”.
En regresión lineal, Ridge tiene solución explícita — útil para ver qué hace la penalización:
\widehat{\boldsymbol\beta}^{\text{ridge}}=(X^\top X+\lambda I)^{-1}X^\top y.
temp y atemp) — resuelve exactamente el problema que motivó esta técnica.Con la descomposición X=UDV^\top (columnas estandarizadas), las predicciones Ridge se contraen dirección por dirección:
\widehat y=\sum_{j}u_j\,\frac{d_j^{2}}{d_j^{2}+\lambda}\,u_j^\top y.
Las direcciones de menor varianza —donde viven combinaciones como temp\approxatemp— son las más contraídas. Ridge no las elimina; les quita influencia.
La penalización opera sobre el tamaño numérico de cada coeficiente. Si temp variara entre 0 y 1 y otra variable entre 0 y 1.000, una misma magnitud de coeficiente no sería comparable — la penalización castigaría por unidades, no por importancia real.
z_{ij}=\frac{x_{ij}-\bar{x}_{j,\text{train}}}{s_{j,\text{train}}}.
glmnet estandariza los predictores por defecto, usando solo estadísticas del conjunto de entrenamiento (nunca de validación o test).
Ridge resuelve la inestabilidad, pero deja un problema abierto: nunca elimina un predictor. Con muchas variables (interacciones, indicadores de calendario), sería útil que el propio ajuste nos dijera cuáles sobran — no solo que las encoja un poco.
LASSO cambia la forma de la penalización para lograr justamente eso: contracción y selección de variables, en el mismo procedimiento.
Ridge penaliza \sum\beta_j^2 (un círculo, en dos dimensiones). LASSO penaliza \sum|\beta_j| (un diamante). La diferencia de forma no es cosmética: cambia dónde el óptimo puede caer.
Elipses = curvas de nivel de -\ell; círculo = restricción Ridge; diamante = restricción LASSO. El estimador penalizado vive donde esas curvas tocan por primera vez la región de restricción. El diamante tiene vértices sobre los ejes — es fácil tocar justo ahí, y en un vértice algún \beta_j=0. El círculo no tiene esquinas: contrae, pero casi nunca anula.
\widehat{\boldsymbol\beta}^{\text{lasso}} =\arg\min_{\boldsymbol\beta} \left\{-\ell(\boldsymbol\beta)+\lambda \underbrace{\sum_{j=1}^{p}|\beta_j|}_{P(\boldsymbol\beta)}\right\}.
Misma estructura que Ridge — mismo \ell, mismo rol de \lambda — la única diferencia es la forma de P(\boldsymbol\beta). Eso basta para cambiar por completo el comportamiento del estimador, como acabamos de ver.
La selección no implica causalidad: que un coeficiente sea exactamente 0 no prueba que esa variable sea irrelevante sustantivamente, solo que no ayudó a predecir en esta muestra bajo esta penalización.
Con predictores ortonormales, la solución LASSO es explícita — y deja ver el mecanismo exacto de la selección:
\widehat\beta_j^{\text{lasso}} =\operatorname{sign}\!\big(\widehat\beta_j^{\text{OLS}}\big)\, \big(|\widehat\beta_j^{\text{OLS}}|-\lambda\big)_+ .
glmnet usa descenso por coordenadas: fija todos los coeficientes menos uno y lo actualiza con la fórmula de soft-thresholding sobre los residuos parciales, ciclando hasta converger. En logística se combina con IRLS (mínimos cuadrados ponderados iterados, la misma idea que vimos en la clase de MLE).
Compare esta trayectoria con la de Ridge: aquí las variables entran y salen del modelo en puntos concretos de \lambda, no se contraen todas parejo. Cada vez que una línea toca el cero y se queda ahí, esa variable fue excluida para ese nivel de penalización.
LASSO selecciona, pero con predictores muy correlacionados (temp, atemp, mes, estacionalidad) tiende a elegir uno arbitrariamente y descartar el resto — muestras parecidas pueden terminar con variables distintas seleccionadas.
Elastic Net combina ambas penalizaciones para resolver esto:
P_{\alpha}(\boldsymbol\beta)= (1-\alpha)\frac{1}{2}\sum_j\beta_j^2+ \alpha\sum_j|\beta_j|.
| \alpha | Modelo | Comportamiento típico |
|---|---|---|
| 0 | Ridge | conserva todos los predictores |
| 1 | LASSO | produce soluciones dispersas |
| entre 0 y 1 | Elastic Net | combina estabilidad y selección |
El término L_2 reparte el peso entre variables correlacionadas (efecto de agrupamiento); el término L_1 conserva la capacidad de anular bloques irrelevantes.
La misma familia de penalizaciones (L_1, L_2, combinadas) aparece, con el mismo objetivo — controlar complejidad cuando hay muchos predictores o predictores correlacionados —, en dominios muy distintos:
| Dominio | Uso típico |
|---|---|
| Genómica | LASSO para seleccionar genes relevantes entre miles, con pocos pacientes |
| Finanzas | Ridge para estabilizar modelos de riesgo con indicadores macroeconómicos correlacionados |
| Texto / NLP | LASSO sobre miles de frecuencias de palabras, para quedarse con las predictivas |
| Marketing | Elastic Net en modelos de churn con decenas de variables de comportamiento correlacionadas |
| Neuroimagen | Elastic Net para seleccionar vóxeles relevantes entre decenas de miles |
En todos los casos, el problema de fondo es el mismo que vimos hoy: muchos predictores, posible colinealidad, y la necesidad de controlar complejidad sin decidir a mano qué variable entra.
| Ridge | LASSO | Elastic Net | |
|---|---|---|---|
| Penalización | L_2 | L_1 | L_1+L_2 |
| Coeficientes | todos se achican, ninguno en 0 | algunos exactamente 0 | algunos en 0, resto achicado |
| Supuesto implícito | todos los predictores aportan algo | pocos predictores realmente importan | hay bloques correlacionados |
| Hiperparámetros | \lambda | \lambda | \lambda y \alpha (2 dimensiones) |
| Costo computacional | bajo (ruta cerrada por dirección) | bajo (coordenadas) | bajo, pero grilla 2D más cara |
| Interpretabilidad | media (todos los coeficientes activos) | alta (modelo disperso) | media-alta |
| Debilidad típica | no simplifica el modelo | descarta arbitrariamente entre correlacionados | más costoso de tunear |
La decisión final es empírica: se compara desempeño de validación, no una preferencia a priori — lo hacemos a continuación.
factor(hr)) entran o salen juntos.Todas resuelven variantes del mismo problema — controlar complejidad automáticamente — con ajustes a cómo se reparte la penalización.
Elegimos \alpha y \lambda; ninguno de los dos se estima maximizando la verosimilitud del modelo. Si los eligiéramos mirando qué tan bien ajustan el conjunto de entrenamiento, siempre ganaría \lambda=0 — el problema con el que empezamos la clase. Por eso la validación no es un paso posterior: es la forma concreta de resolver el compromiso sesgo-varianza sin hacer trampa.
La idea de fondo de cualquier validación: en vez de “memorizar una única prueba”, evaluar el modelo como si rindiera varios exámenes distintos y ver si el desempeño es consistente.
\text{CV}(\lambda)=\frac{1}{k}\sum_{f=1}^{k}\text{pérdida}_f(\lambda).
k-fold cross-validation: los datos se dividen en k bloques; en cada ronda uno actúa como validación y el resto como entrenamiento.
Con dependencia temporal como la nuestra, la CV aleatoria de la figura es optimista: horas vecinas se filtran entre pliegues. Por eso usamos un conjunto de validación fijo, cronológico.
El análogo correcto de k-fold cuando los datos son series de tiempo se llama validación cruzada de series de tiempo (rolling-origin / walk-forward): cada “pliegue” entrena solo con el pasado y valida con un bloque futuro, avanzando el origen de entrenamiento en cada ronda. Es la generalización, a k rondas, de la partición cronológica única que usamos hoy.
Otras alternativas para elegir \lambda sin re-ajustar muchas veces: validación cruzada generalizada (GCV), y criterios de información como AIC/BIC.
# A tibble: 5 × 3
alpha lambda loss
<dbl> <dbl> <dbl>
1 0 0.003 0.351
2 0 0.004 0.351
3 0 0.005 0.352
4 0 0.006 0.352
5 0 0.007 0.353
# A tibble: 1 × 3
alpha lambda validation_log_loss
<dbl> <dbl> <dbl>
1 0 0.003 0.351
El umbral se elige en validación minimizando el mismo costo de la clase 15: un falso negativo cuesta tres veces un falso positivo. El test no participó en ninguna de estas decisiones.
# A tibble: 2 × 7
modelo log_loss accuracy sensitivity specificity precision cost_per_100
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Logit sin penalizar 0.323 0.822 0.937 0.781 0.605 21.100
2 Ridge 0.306 0.747 0.991 0.659 0.510 25.800
La penalización se juzga contra el logit sin penalizar bajo el mismo protocolo. Puede mejorar log-loss o estabilidad sin reducir el costo operacional; en ese caso, la solicitud predictiva —no la novedad del método— decide cuál preferir.
predicho
observado baja alta
baja 848 439
alta 4 457
Los falsos negativos son horas de demanda alta que el sistema no anticipó. Discriminación (matriz de confusión) y calibración (¿las probabilidades predichas se cumplen en la frecuencia correcta?) son propiedades distintas — un modelo puede discriminar bien y calibrar mal, o viceversa.
# A tibble: 1 × 10
día hora temperatura alpha lambda probabilidad umbral acción demanda_observada clase_observada
<dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <chr>
1 354 8 0.420 0 0.003 0.997 0.100 priorizar 432 alta
La regularización modifica cómo se estiman los coeficientes; la interfaz operacional sigue siendo la misma: fila futura → probabilidad → umbral → acción.
# A tibble: 10 × 3
variable coefficient selected
<chr> <dbl> <lgl>
1 factor(hr)8:workingday 8.590 TRUE
2 factor(hr)7:workingday 5.650 TRUE
3 factor(hr)10:workingday -4.550 TRUE
4 factor(hr)16 4.120 TRUE
5 factor(hr)14 4.090 TRUE
6 atemp 4.010 TRUE
7 factor(hr)17 3.990 TRUE
8 factor(hr)11:workingday -3.860 TRUE
9 factor(hr)13 3.760 TRUE
10 factor(hr)12 3.730 TRUE
Un coeficiente igual a cero no demuestra irrelevancia sustantiva: solo dice que, bajo esta penalización y esta muestra, esa variable no ayudó a predecir. La selección puede cambiar entre muestras parecidas — no es una prueba de hipótesis.
| Método | Controla complejidad | Selección | Nota |
|---|---|---|---|
| Mejor subconjunto | prueba todas las combinaciones | dura (0/1) | inviable con p grande |
| Paso a paso (stepwise) | agrega/quita una variable a la vez | dura | greedy, inestable |
| Ridge / LASSO / Elastic Net | penalización continua | según método | convexo, reproducible |
La regularización reemplaza la selección discreta (combinatoria, inestable, la que un GLM clásico haría “a mano” comparando AIC entre modelos) por una continua — el mismo objetivo del stepwise selection de la clase 15, resuelto de forma más estable.
La regularización es una respuesta directa al compromiso sesgo–varianza con el que abrimos la clase: introducimos un sesgo controlado (\lambda P_\alpha) a cambio de mucha menos varianza y un ajuste reproducible.
Todo el resto del flujo —partición, estandarización, test intacto, calibración— existe para que ese compromiso se resuelva honestamente, sin volver a caer en la curva de sobreajuste del comienzo.
workingday y factor(hr).Regularización controla la complejidad de un modelo cuya forma seguimos eligiendo nosotros: seguimos escribiendo a mano I(temp^2), factor(hr) * workingday, y esperando haber adivinado las interacciones correctas.
¿Qué pasa si no sabemos qué interacciones importan? ¿Puede el algoritmo, además de controlar cuánta complejidad usar, descubrir por sí solo qué variables interactúan y cómo? Esa es exactamente la pregunta que abre la próxima clase.
Seguimos usando bicicletas como único caso — pero el mismo procedimiento (penalizar, validar sin mirar el test, elegir hiperparámetros honestamente) es exactamente el que corre detrás de un puntaje de crédito o un score de riesgo: la disciplina que practicamos aquí es la misma que se exige cuando el error afecta a una persona, no a una bicicleta.
Hasta la próxima clase
Mauricio Bucca