C.G.

De las series temporales al producto

Una serie temporal no se convierte en producto por entrenar un modelo. Se convierte cuando los datos están limpios, la validación no hace trampa, el servicio responde a tiempo y alguien puede detectar cuándo deja de funcionar. Esta guía recorre ese camino completo, con el caso de TradeScope AI.

Qué es una serie temporal y por qué falla la intuición

Una serie temporal es una secuencia de observaciones ordenadas en el tiempo. A diferencia de una tabla tradicional, el orden importa: cada fila depende de las anteriores y el futuro no puede usarse para explicar el pasado. Una serie financiera suele combinar tendencia, estacionalidad, ciclos, ruido y cambios de régimen, y la relación entre señal y ruido es baja.

La intuición falla por dos motivos. Primero, un modelo puede verse excelente en el histórico y fallar en la siguiente ventana. Segundo, el error medio oculta los momentos que más importan: los cambios bruscos. Por eso el diseño empieza por la decisión que el pronóstico debe apoyar, no por la arquitectura.

Define el problema antes de elegir el modelo

Antes de escribir código responde qué se predice, con qué horizonte y qué cuesta equivocarse. No es lo mismo pronosticar el precio de mañana para una alerta que estimar la demanda de la próxima semana para comprar inventario. El horizonte cambia las variables, la métrica y hasta la frecuencia de reentrenamiento.

Define también un baseline. La persistencia del último valor es una referencia barata y honesta: si el modelo no la supera de forma consistente, no hay producto. En TradeScope AI el objetivo era un pronóstico estable para una decisión, no ganar un benchmark aislado.

Datos: la parte que decide el resultado

La mayor parte del trabajo ocurre antes de entrenar. Fija una frecuencia, alinea las series, revisa huecos y valores atípicos, y documenta cómo se rellenan. Un valor imputado con el futuro es una fuga de información; uno imputado con la media histórica puede ser aceptable si esa media solo usa el pasado.

La normalización se ajusta únicamente con el tramo de entrenamiento y se reutiliza en validación y test. Es un detalle fácil de olvidar y una de las formas más comunes de contaminar un experimento. Lo mismo aplica a la selección de variables exógenas: si una variable no está disponible en el momento de predecir, no puede entrar al modelo.

Validación temporal: cómo no engañarte

Barajar las filas antes de partir el dataset es el error clásico. En una serie temporal equivale a entrenar con el futuro y evaluar con el pasado. La alternativa es la validación walk-forward: entrenar con un bloque, predecir el siguiente, avanzar la ventana y repetir. También puedes usar ventanas expansivas o separar un bloque final que nunca se toque hasta la evaluación definitiva.

Además de MAE y RMSE, mira la precisión direccional y la distribución del error por ventana. Un modelo con un error medio ligeramente peor pero mucho más estable suele ser mejor para una decisión real. Si el sistema genera operaciones, incluye los costes y el retraso de ejecución en la evaluación; un acierto teórico que llega tarde no es un acierto.

Familias de modelos y cuándo usar cada una

FamiliaFortalezasLímitesCuándo usarla
Baseline naiveTrivial y explicableNo capta estructuraSiempre, como referencia
ARIMA / SARIMAXInterpretable, rápido, intervalosRelación lineal, difícil con muchas seriesSeries univariadas estables
ProphetEstacionalidad y festivos, fácil de ajustarMenos preciso con alta frecuenciaNegocio con estacionalidad clara
LSTMDependencias locales y secuencias largasCoste de entrenamiento, poca transparenciaPatrones no lineales con datos suficientes
TransformerRelaciones de largo alcanceMás datos y cómputoEventos distantes y series multivariadas
EnsembleReduce varianza y sesgoMás infraestructura y mantenimientoProducción con requisitos de estabilidad

Empieza por lo simple y sube solo cuando la evidencia lo justifique. Un ARIMA bien validado puede ser suficiente para una serie limpia; un ensemble tiene sentido cuando varias familias capturan patrones distintos y el coste de mantenimiento está justificado.

El ensemble LSTM + Transformer

La LSTM captura dependencias locales y de corto plazo; el Transformer modela relaciones de largo alcance entre eventos distantes. Combinar ambas reduce el sesgo de una sola familia y estabiliza las predicciones. La combinación no es un promedio ciego: cada rama tiene un peso según la ventana y el régimen, y el sistema registra su contribución para poder explicar el resultado.

El entrenamiento se hace en PyTorch, con ventanas deslizantes, una semilla fija y una separación temporal estricta entre train y test. No mezclo filas ni barajo el dataset. También guardo el modelo y el preprocesador como una unidad: servir una normalización distinta a la del entrenamiento es una fuente silenciosa de errores.

Del notebook al servicio

Un modelo que solo vive en Jupyter no es un producto. El backend está construido con FastAPI y expone las predicciones por WebSocket; el dashboard se actualiza sin recargar y muestra el histórico junto al pronóstico. Elegí WebSocket porque el panel necesita varias actualizaciones por minuto y abrir conexiones nuevas era más caro. Para un pronóstico diario, una API REST sería suficiente.

El modelo se carga una vez al arrancar, se mantiene en memoria y se sirve con un contrato de entrada y salida explícito. Si falla, el servicio devuelve el último pronóstico válido y registra el error en lugar de romper la interfaz. Esa última milla —contrato, latencia y recuperación— es parte del producto, no un detalle de infraestructura.

Infraestructura y operación

Todo corre en contenedores Docker sobre un VPS Linux propio. El despliegue incluye variables de entorno para los secretos, volúmenes para los datos y un túnel de Cloudflare para exponer el servicio sin abrir puertos. La operación es parte del producto: logs con contexto, healthchecks, reinicio automático y una alerta cuando el flujo de datos se detiene.

Sin esa vigilancia, el dashboard parece funcionar hasta que alguien mira una gráfica con datos de hace tres días. Un panel vacío se nota; uno con datos viejos engaña.

Reproducibilidad y métricas que importan

Un resultado que no se puede repetir no es un resultado. Fijo la semilla, congelo las versiones de las librerías, guardo la configuración del experimento junto al modelo y registro qué dataset se usó. Así puedo comparar dos ejecuciones sin depender de la memoria. También registro MAE, RMSE y precisión direccional por ventana, y comparo la distribución, no solo el promedio.

El rendimiento del servicio cuenta: mido el tiempo de respuesta del endpoint y la tasa de pronósticos servidos desde caché. Si el modelo tarda más de lo que dura la ventana de decisión, la precisión es irrelevante.

Monitoreo y deriva

Un modelo no se degrada solo por un bug; se degrada porque el mundo cambia. Mido la distribución de las entradas, el error reciente y la tasa de predicciones fuera de rango. Cuando una de esas señales se sale de su banda durante varias ventanas, se dispara una revisión.

No reentreno automáticamente en cada alerta. Primero distingo entre un cambio real y un dato roto; después decido si hace falta reentrenar, recalibrar o solo corregir la ingesta. Esa distinción evita modelos que persiguen ruido.

Checklist para llevar un modelo a producción

  • Baseline definido y superado con la misma validación.
  • Separación temporal estricta y sin barajado.
  • Preprocesador ajustado solo con train y guardado con el modelo.
  • Contrato de entrada y salida documentado.
  • Fallback cuando el modelo o los datos fallan.
  • Healthcheck y alerta de datos detenidos.
  • Logs con contexto y versión del modelo.
  • Latencia medida contra la ventana de decisión.
  • Semilla, versiones y configuración reproducibles.
  • Plan de reentrenamiento y criterio de rollback.

Errores comunes

  • Barajar la serie antes de partirla: filtra futuro al pasado.
  • Optimizar solo el error medio: el modelo se vuelve conservador en los cambios de régimen.
  • Medir el modelo en el notebook y no la latencia del servicio.
  • Desplegar sin alerta de datos detenidos.
  • Comparar modelos con validaciones distintas.
  • Ignorar el coste de la decisión y el retraso de ejecución.

Preguntas frecuentes

¿Necesito deep learning para una serie temporal?

No. Empieza con un baseline y un modelo estadístico bien validado. El deep learning aporta cuando hay suficientes datos, relaciones no lineales y varias series relacionadas; si no, añade complejidad sin garantía de mejora.

¿Cuántos datos necesito?

Depende de la señal y del horizonte, no solo del número de filas. Pocos datos favorecen modelos simples; muchas series ruidosas no se arreglan con más parámetros. La validación walk-forward te dirá si el modelo generaliza.

¿Cómo evito filtrar información del futuro?

Separa por tiempo, nunca al azar. Ajusta la normalización y cualquier transformación solo con el pasado. Revisa que cada variable exógena esté disponible en el momento de predecir.

¿Cuándo debo reentrenar?

Cuando el error o la distribución de los datos cambie de forma sostenida. Combina un calendario con disparadores por drift; reentrenar cada día sin evidencia solo añade riesgo operativo.

Para seguir

El código y la arquitectura están en TradeScope AI. Si estás montando algo parecido, el orden que me funcionó fue: datos, validación, baseline, modelo y solo después interfaz. La parte de infraestructura está en Docker para Desarrolladores, y si quieres discutir el enfoque puedes escribirme desde la página de contacto.

← Volver