Los Hiperparámetros Detrás de Cada Modelo
Qué palancas ajustamos, por qué, y cómo afectan el pronóstico epidemiológico.
EpiForecast-MX — 6 modelos × 258 series — AWS SageMaker v5-full
Qué son los hiperparámetros
Los "botones y perillas" que ajustamos antes de entrenar un modelo.
Un modelo de machine learning tiene dos tipos de configuración: los parámetros (que el modelo aprende automáticamente de los datos) y los hiperparámetros (que nosotros definimos antes de entrenar).
Imagina un auto de carreras: los parámetros son como la habilidad del piloto — mejora con práctica. Los hiperparámetros son como la configuración del motor, la presión de las llantas y la aerodinámica — los ingenieros los ajustan antes de la carrera.
Elegir mal los hiperparámetros puede hacer que un modelo excelente funcione pésimamente. Elegirlos bien es la diferencia entre un pronóstico mediocre y uno que supera al baseline naive en el 86% de las series.
Grid Search: Para Prophet, probamos múltiples combinaciones de hiperparámetros (hasta 24 por serie) y seleccionamos la mejor mediante validación cruzada temporal. Para los modelos de deep learning (TFT, DeepAR, LightGBM+LSTM) y ML clásico (XGBoost, Ridge), usamos una configuración fija optimizada previamente, ya que su entrenamiento es más costoso computacionalmente.
Pipeline de Transformación de Datos
Todos los modelos reciben los mismos datos, transformados de la misma manera.
De conteos crudos a la entrada del modelo
y_tasa = (incidencia_semanal / población_estado) × 100,000
y_final = log(1 + y_tasa)
modelo.fit(y_final)
yhat_tasa = exp(yhat) - 1
yhat_conteo = yhat_tasa × población / 100,000
¿Por qué tasas? Normaliza la escala entre estados con poblaciones muy diferentes (CDMX ~9M vs Colima ~730K). Sin esto, CDMX dominaría todas las métricas por volumen.
¿Por qué log-transform? Las series epidemiológicas tienen varianza proporcional al nivel (más casos = más variabilidad). El logaritmo estabiliza esto y comprime los picos extremos de Depresión.
Períodos atípicos
COVID-19
Inicio: 2020-03-23
Duración: 913 días (~2.5 años)
Prophet lo trata como "holiday" para no ajustar la tendencia al colapso pandémico.
Cambio régimen Tabasco 2023
Inicio: 2023-01-09
Duración: 365 días
Solo aplica a Depresión en Tabasco. Cambio estructural en el reporte.
Validación Cruzada Temporal
Cómo evaluamos cada modelo: 4 folds expansivos con ponderación anti-COVID.
Ponderación de folds
El Fold 1 contiene el choque de COVID-19, que es un evento anómalo e irrepetible. Si ponderamos todos los folds igual, el modelo se sesga hacia rigidez excesiva (para no sobreajustar al dip pandémico). Por eso penalizamos el Fold 1 y favorecemos los folds recientes.
| Fold | Período de validación | Peso | Contexto |
| 1 | 2020-12 → 2021-12 | 0.50 | Pleno COVID — anomalía irrepetible, se penaliza |
| 2 | 2021-12 → 2022-12 | 0.75 | Recuperación post-COVID |
| 3 | 2022-12 → 2023-12 | 1.00 | Normalización |
| 4 | 2024-01 → 2024-12 | 1.25 | Datos más recientes — se favorece |
El RMSE final ponderado = ∑(pesoi × RMSEi) / ∑(pesoi). Esto permite que el modelo priorice el desempeño en datos recientes sin ignorar completamente el período COVID.
Prophet descompone la serie en tres componentes: tendencia (dirección general), estacionalidad (patrones cíclicos anuales/semanales), y holidays (eventos especiales como COVID-19). Es el único modelo con grid search completo: probamos múltiples combinaciones y elegimos la mejor por validación cruzada.
Hiperparámetros del Grid Search
| Hiperparámetro | Valores probados | Descripción |
| seasonality_mode |
multiplicative additive |
Multiplicative: La estacionalidad es un porcentaje del nivel actual. Si la incidencia sube, los picos estacionales también crecen proporcionalmente.
Additive: La estacionalidad es una cantidad fija que se suma/resta, independiente del nivel.
Resultado: multiplicative domina (62%) excepto en Depresión con log-transform donde additive gana
|
| changepoint_prior_scale |
0.01 0.03 0.05 |
Controla la flexibilidad de la tendencia. Valores bajos (0.01) = tendencia rígida, pocos cambios de dirección. Valores altos (0.05) = tendencia flexible, se adapta más rápido a cambios.
Analogía: Es como la "dureza de la suspensión" de un auto. Muy blanda (0.05) y absorbe cada bache (sobreajuste al COVID). Muy dura (0.01) y no detecta curvas reales.
Resultado: 0.03 ganó en 39%, seguido de 0.01 con 31%
|
| seasonality_prior_scale |
0.1 0.5 1.0 |
Controla la fuerza del patrón estacional. Valores bajos (0.1) = patrón estricto y suave. Valores altos (1.0+) = permite estacionalidad más irregular y detallada.
Analogía: Es como el "zoom" en la estacionalidad. Zoom bajo (0.1) ve la forma general (invierno sube, verano baja). Zoom alto (1.0) captura mini-picos semana a semana.
Resultado: 0.5 ganó en 30%, seguido de 0.05 con 25%
|
| fourier_order |
5 (fijo) |
Número de términos de Fourier para modelar la estacionalidad anual. Más términos = curva más detallada. El default de Prophet es 10, pero nuestros experimentos anteriores confirmaron que 5 es óptimo para evitar sobreajuste en series cortas.
Analogía: Fourier 5 = dibujar la estacionalidad con 5 ondas. Fourier 20 = usar 20 ondas (captura cada micro-patrón pero puede sobreajustar al ruido).
|
Grid por padecimiento
Cada padecimiento tiene un grid diferente porque sus patrones temporales son distintos.
Depresión
24
2 seasonality_mode × 3 cp × 4 sp × 1 fourier
El grid más amplio: Depresión tiene patrones más complejos y variados.
Parkinson
18
2 seasonality_mode × 3 cp × 3 sp × 1 fourier
cp empieza en 0.03 (no 0.01): Parkinson requiere más flexibilidad.
Alzheimer
6
1 seasonality_mode × 2 cp × 3 sp × 1 fourier
Solo multiplicative: series estables con baja incidencia. Grid pequeño = entrenamiento rápido.
Parámetros fijos
| Parámetro | Valor | Razón |
| yearly_seasonality | False | Desactivada la estacionalidad anual automática. Usamos una personalizada con add_seasonality('yearly_custom', period=52.18, fourier_order=5) para tener control del fourier_order. |
| weekly_seasonality | False | Datos semanales (1 observación/semana), no hay variación intra-semanal. |
| daily_seasonality | False | No aplica para datos semanales. |
| holidays | COVID-19 (913d) | El período pandémico se marca como "holiday" para que Prophet no ajuste su tendencia a la caída de 2020-2022. |
| cv_timeout_por_combo | 90s | Tiempo máximo por combinación. Si Prophet entra en "modo Newton lento" (optimizador L-BFGS diverge), se corta el entrenamiento y se usa el resultado parcial. |
Ventajas
- Grid search completo: se adapta a cada serie individual
- Descomposición interpretable (tendencia + estacionalidad + holidays)
- Manejo nativo de datos faltantes y valores atípicos
- Predicción a horizontes largos (120 semanas) sin acumulación de error
- Los médicos del IMSS pueden entender y validar los componentes
- Mediana MASE de 0.745 — la mejor de los 6 modelos
Limitaciones
- Lento: 93.5s promedio por serie (68% del tiempo total)
- Problemas de convergencia (Newton fallback) en algunas series
- No captura relaciones no lineales complejas
- Grid search es costoso: 6-24 combos × 4 folds por serie
- Depende de hipótesis de descomposición aditiva/multiplicativa
- No aprovecha información cruzada entre series
TFT es una arquitectura de deep learning basada en el mecanismo de atención (el mismo concepto detrás de GPT y ChatGPT). Aprende automáticamente qué momentos del pasado son más relevantes para predecir el futuro. Puede capturar patrones no lineales y relaciones complejas que Prophet no detecta.
| Hiperparámetro | Valor | Descripción |
| hidden_size |
16 |
Dimensión del espacio de representación interno del Transformer. 16 es deliberadamente pequeño: nuestras series tienen ~500 observaciones, un hidden_size grande (64-256) sobreajustaría. Es como usar un telescopio pequeño para un objeto cercano — no necesitas el Hubble. Trade-off: menos expresividad, pero más estable con datos limitados |
| learning_rate |
0.01 |
Tamaño del paso de optimización. 0.01 es relativamente alto para deep learning, pero con solo 100 pasos de entrenamiento, necesitamos avanzar rápido. Analogía: caminar con pasos grandes en un laberinto pequeño. |
| max_steps |
100 |
Número máximo de iteraciones de entrenamiento. 100 es conservador — preferimos subentrenar ligeramente a sobreajustar. El default típico es 200-1000, pero con series cortas, menos es más. |
| n_head |
1 (fijo) |
Número de "cabezas de atención". Con 1 cabeza, el modelo enfoca su atención en un solo aspecto a la vez. Múltiples cabezas permitirían atender patrones simultáneos, pero con series pequeñas, 1 es suficiente. |
| dropout |
0.1 (fijo) |
Probabilidad de "apagar" neuronas aleatoriamente durante el entrenamiento. Previene sobreajuste. 0.1 = 10% de las neuronas se desactivan en cada paso. |
| input_size |
104 (fijo) |
Ventana de retrospectiva: 104 semanas = 2 años de datos históricos como contexto. Permite capturar 2 ciclos anuales completos de estacionalidad. |
| scaler_type |
standard (fijo) |
Estandarización (media=0, desviación=1) antes de entrenar. Las redes neuronales requieren inputs normalizados para converger correctamente. |
¿Por qué no hay grid search para TFT? Entrenar un TFT es ~30 segundos por serie, vs ~94 para Prophet con grid. Si probáramos incluso 4 combinaciones, cada serie tomaría 2 minutos. Con 258 series, pasaríamos de 2.2 horas a 8.6 horas solo para TFT. El costo no se justifica dado que la configuración actual ya produce resultados competitivos (68 victorias, más que cualquier otro modelo).
Ventajas
- Mayor número de victorias individuales (68/258 = 26.4%)
- Mecanismo de atención captura dependencias temporales complejas
- Maneja naturalmente la no linealidad
- Proporciona intervalos de predicción probabilísticos
- Relativamente rápido para deep learning (30s/serie)
Limitaciones
- Caja negra: difícil explicar por qué predice lo que predice
- Mediana MASE (0.773) inferior a Prophet (0.745)
- Sensible al tamaño del dataset — puede fallar con pocas observaciones
- No tiene grid search — podría mejorar con optimización de HPs
- Requiere PyTorch/GPU para entrenamiento eficiente
DeepAR es una red neuronal recurrente (LSTM) desarrollada por Amazon. A diferencia de TFT (que "mira" todo el pasado a la vez con atención), DeepAR procesa la serie paso a paso, como leer un libro página por página. Genera predicciones probabilísticas: no solo dice "la incidencia será 45", sino "será 45 ± 12 con 95% de confianza".
| Hiperparámetro | Valor | Descripción |
| hidden_size |
32 |
Dimensión del estado oculto LSTM. 32 es el doble que TFT (16) porque LSTM necesita más capacidad para su procesamiento secuencial. Es la "memoria de trabajo" de la red. |
| learning_rate |
0.001 |
10x más bajo que TFT (0.01). Los modelos probabilísticos son más sensibles a pasos de optimización grandes. Pasos pequeños = convergencia más estable pero más lenta. |
| max_steps |
100 |
Igual que TFT. 100 iteraciones con learning_rate bajo producen una convergencia suave. |
| n_layers |
2 (fijo) |
Dos capas LSTM apiladas. La primera captura patrones de bajo nivel (tendencias locales), la segunda aprende patrones de alto nivel (estacionalidad, régimen). |
| dropout |
0.1 (fijo) |
Dropout recurrente del 10%. Ayuda a evitar que la red "memorice" secuencias exactas del entrenamiento. |
| input_size |
104 (fijo) |
Ventana de 2 años (104 semanas). Idéntico a TFT para comparación justa. |
Ventajas
- Predicciones probabilísticas nativas (intervalos de confianza)
- 40 victorias (15.5%) — competitivo en todas las categorías
- Muy rápido: solo 8 segundos promedio por serie
- LSTM captura bien dependencias de largo plazo
- Puede aprender patrones de múltiples series simultáneamente
Limitaciones
- Procesamiento secuencial es más lento que la atención paralela de TFT
- Difícil de interpretar — el estado oculto LSTM es opaco
- Puede olvidar patrones muy antiguos (vanishing gradients)
- Sensible a la inicialización aleatoria
- Sin grid search — configuración fija no optimizada por serie
Este es nuestro modelo híbrido: combina la velocidad y robustez de LightGBM (árboles de decisión potenciados) con la capacidad secuencial de LSTM (red neuronal recurrente). La predicción final es un promedio ponderado de ambos: y = 0.5 × LightGBM + 0.5 × LSTM. La idea: donde uno falla, el otro compensa.
| Hiperparámetro | Valor | Componente | Descripción |
| lgbm_n_estimators |
300 |
LightGBM |
Número de árboles. 300 es 3x más que XGBoost (100) porque LightGBM usa árboles más ligeros (leaf-wise vs level-wise). Más árboles = más refinamiento, pero con learning_rate bajo no sobreajusta. |
| lgbm_max_depth |
5 |
LightGBM |
Profundidad máxima de cada árbol. 5 niveles = hasta 32 hojas. Suficiente para capturar interacciones entre features (lag_52 × mes del año) sin sobreajustar. |
| lgbm_learning_rate |
0.05 (fijo) |
LightGBM |
Contribución de cada árbol nuevo. 0.05 = cada árbol aporta solo 5% de corrección. Entrenamiento lento pero estable. |
| lstm_hidden_size |
32 (fijo) |
LSTM |
Misma dimensión que DeepAR. El componente LSTM del ensemble aprende patrones secuenciales complementarios a los árboles. |
| lstm_max_steps |
100 |
LSTM |
Iteraciones de entrenamiento del componente LSTM. Igual que DeepAR y TFT. |
| ensemble_weight_lgbm |
0.5 |
Ensemble |
50% LightGBM + 50% LSTM. Peso igual a ambos componentes. No se optimizó este peso por serie — un valor fijo de 0.5 es robusto como punto de partida. |
Features de ingeniería (componente LightGBM)
El componente LightGBM necesita features manuales (a diferencia de Prophet que las descubre automáticamente):
Lags temporales
lag_1 lag_2 lag_4 lag_8 lag_12 lag_52
Valores de hace 1, 2, 4, 8, 12 y 52 semanas. El lag_52 captura la estacionalidad anual.
Estadísticas móviles
rolling_mean_4 rolling_std_4
rolling_mean_12 rolling_std_12
rolling_mean_26 rolling_std_26
Media y desviación móvil de 1, 3 y 6 meses.
Variables calendario
week_of_year month quarter year week_sin week_cos month_sin month_cos
Codificación cíclica (seno/coseno) para que la semana 52 esté "cerca" de la semana 1, evitando discontinuidad artificial.
Ventajas
- 48 victorias (18.6%) — tercer modelo más exitoso
- Menor tasa de último lugar: solo 14/258 (5.4%)
- Diversificación: si LightGBM falla, LSTM puede compensar y viceversa
- Rápido: 4.8s promedio (LightGBM es casi instantáneo)
- Features interpretables (importancia de features disponible)
Limitaciones
- El peso fijo 50/50 puede no ser óptimo para todas las series
- Features manuales requieren ingeniería previa
- LightGBM no captura tendencia nativa (depende de lag_52)
- Predicción multi-step es recursiva = acumula error
- Complejidad de implementación: dos modelos que mantener
XGBoost es el "caballo de batalla" del machine learning tabular. Construye cientos de árboles de decisión pequeños, donde cada nuevo árbol corrige los errores del anterior. Es extremadamente rápido (0.5s por serie) pero no tiene componentes explícitas de tendencia ni estacionalidad — debe aprenderlas de los features.
| Hiperparámetro | Valor | Descripción |
| n_estimators |
100 |
Número de árboles. 100 es conservador — suficiente para series cortas sin riesgo de sobreajuste. Compárese con 300 de LightGBM (que usa árboles más ligeros). |
| max_depth |
5 |
Profundidad máxima de cada árbol. Igual que LightGBM. Árboles poco profundos capturan patrones generales sin memorizar ruido. |
| learning_rate |
0.05 |
Tasa de aprendizaje. 0.05 = cada árbol contribuye poco individualmente. Esto, combinado con 100 árboles, da un modelo conservador y estable. |
Features idénticas a LightGBM: XGBoost usa exactamente los mismos lags (1,2,4,8,12,52), estadísticas móviles (4,12,26 semanas) y variables calendario con codificación cíclica. La diferencia es que XGBoost construye árboles "nivel por nivel" (level-wise) mientras LightGBM lo hace "hoja por hoja" (leaf-wise), y no tiene el componente LSTM complementario.
Ventajas
- Ultra-rápido: 0.5 segundos por serie
- Robusto ante datos faltantes y outliers
- Importancia de features interpretable
- Amplia comunidad y documentación
- No requiere GPU
Limitaciones
- 73 veces último lugar (28.3%) — el peor registro
- Mediana MASE 0.832 — significativamente peor que Prophet (0.745)
- Predicción recursiva multi-step acumula error progresivamente
- Sin tendencia ni estacionalidad explícita
- Solo 22 victorias (8.5%) — 5to de 6 modelos
Ridge es nuestro baseline: el modelo más simple posible. Es una regresión lineal con regularización L2 que penaliza coeficientes grandes. Su propósito es establecer un piso de rendimiento: si un modelo sofisticado no puede vencer a una línea recta, algo anda mal. Sorprendentemente, Ridge gana 20 series, lo que sugiere que algunas series son tan simples que la complejidad adicional perjudica.
| Hiperparámetro | Valor | Descripción |
| alpha |
1.0 |
Fuerza de regularización L2. Controla cuánto se penalizan los coeficientes grandes.
Alpha = 0: regresión lineal pura (sin regularización, riesgo de sobreajuste).
Alpha = 1.0: regularización moderada. Los coeficientes se "encogen" hacia cero pero no desaparecen.
Alpha → ∞: todos los coeficientes se vuelven ~0, el modelo predice la media.
1.0 es el valor por defecto de scikit-learn — un balance conservador
|
| StandardScaler |
Sí (fijo) |
Todas las features se estandarizan (media=0, desviación=1) antes de entrenar. Crítico para Ridge porque la regularización L2 depende de la escala de las features. |
Mismo set de features que XGBoost y LightGBM: Lags (1,2,4,8,12,52), rolling stats (4,12,26), y calendario cíclico. La diferencia es que Ridge busca una combinación lineal de estos features, mientras los árboles pueden capturar interacciones no lineales (ej. "si lag_52 > 2.0 Y mes = enero, entonces subir").
Ventajas
- El más rápido de todos: 0.1 segundos por serie
- Completamente interpretable: coeficientes lineales
- Imposible de sobreajustar con alpha=1.0
- 20 victorias: gana en series con patrones lineales simples
- Baseline sólido para validar modelos más complejos
Limitaciones
- 67 veces último lugar (26%) — segundo peor
- No captura patrones no lineales ni interacciones
- Predicción recursiva multi-step acumula error
- Sin componente de tendencia ni estacionalidad
- Mediana MASE 0.822 — por debajo de todos excepto XGBoost
Tabla Comparativa Final
Los 6 modelos lado a lado: hiperparámetros, complejidad, resultados y velocidad.
| Aspecto |
Prophet |
TFT |
DeepAR |
LGB+LSTM |
XGBoost |
Ridge |
| Tipo |
Aditivo / descomposición |
Transformer |
LSTM recurrente |
Ensemble híbrido |
Gradient boosting |
Regresión lineal |
| Grid search |
6-24 combos |
1 (fijo) |
1 (fijo) |
1 (fijo) |
1 (fijo) |
1 (fijo) |
| HPs clave |
season_mode, cp, sp, fourier |
hidden=16, lr=0.01, steps=100 |
hidden=32, lr=0.001, steps=100 |
trees=300, depth=5, w=0.5 |
trees=100, depth=5, lr=0.05 |
alpha=1.0 |
| Lookback |
Todo el histórico |
104 sem (2 años) |
104 sem (2 años) |
52 sem + lags |
Lags manuales |
Lags manuales |
| Victorias |
60 (23.3%) |
68 (26.4%) |
40 (15.5%) |
48 (18.6%) |
22 (8.5%) |
20 (7.8%) |
| Mediana MASE |
0.745 |
0.773 |
0.748 |
0.748 |
0.832 |
0.822 |
| Último lugar |
33 (12.8%) |
37 (14.3%) |
34 (13.2%) |
14 (5.4%) |
73 (28.3%) |
67 (26.0%) |
| Velocidad |
93.5s |
30.2s |
8.0s |
4.8s |
0.5s |
0.1s |
| Interpretable |
Alta |
Baja |
Baja |
Media |
Media |
Alta |
| Multi-step nativo |
Sí |
Sí |
Sí |
No (recursivo) |
No (recursivo) |
No (recursivo) |
Conclusión sobre hiperparámetros: Prophet es el único modelo con optimización individual por serie (grid search). Si aplicáramos grid search a TFT y DeepAR, podrían mejorar significativamente, pero el costo computacional se multiplicaría por 4-10x. La decisión de usar configuración fija para deep learning es un trade-off pragmático: resultados competitivos al 26% del costo. Para producción, Prophet con HPs óptimos por serie ofrece la mejor relación calidad-costo-interpretabilidad.