Arquitectura de red neuronal
Eaternity Forecast utiliza una sofisticada red neuronal basada en transformadores con mecanismos de atención para predecir la demanda diaria de artículos del menú de restaurantes. Este documento explica la arquitectura técnica y la metodología de inteligencia artificial.
Visión general de la arquitectura
Tipo de modelo: Arquitectura de transformadores
Forecast emplea una arquitectura de transformadores, la misma tecnología fundamental detrás de los modelos de lenguaje modernos como GPT y BERT, adaptada específicamente para la previsión de demanda de series temporales.
¿Por qué transformadores para la previsión de demanda?
Los métodos de pronóstico tradicionales (modelo autorregresivo integrado de media móvil, suavizado exponencial) tienen dificultades con:
- Relaciones complejas multifactoriales
- Dependencias temporales de largo alcance
- Patrones no estacionarios
- Múltiples ciclos estacionales simultáneos
Los transformadores destacan en:
- Reconocimiento de patrones a través de diferentes escalas temporales (diario, semanal, estacional)
- Mecanismos de atención que identifican períodos históricos relevantes
- Integración multifactorial (clima, eventos, cambios de menú)
- Manejo de patrones irregulares (festivos, eventos especiales)
Componentes principales
Capa de entrada
↓
Incrustación temporal
↓
Atención multicabezal (×4 capas)
↓
Redes de alimentación directa
↓
Proyección de salida
↓
Predicción + Intervalos de confianza
Arquitectura detallada
1. Capa de entrada
Propósito: Transformar datos de ventas en bruto y factores externos en representaciones numéricas
Características de entrada (por artículo, por día):
Características de ventas históricas
- Ventas de los 7 días anteriores (cantidades diarias)
- Ventas del mismo día de la semana de las 4 semanas anteriores
- Ventas promedio del mes anterior
- Ventas de la misma fecha del año anterior (si están disponibles)
Características temporales
- Día de la semana (codificación de un solo activo: Lunes=1, Martes=2, etc.)
- Semana del año (1-52)
- Mes (1-12)
- Es fin de semana (binario: 0/1)
- Es festivo (binario: 0/1)
Características externas
- Temperatura (°C, normalizada)
- Precipitación (mm, normalizada)
- Pronóstico del tiempo para el día siguiente
- Eventos locales (banderas binarias o categóricas)
Características del menú
- Categoría del artículo (entrante, plato principal, postre, etc.)
- Punto de precio (normalizado)
- Días desde el lanzamiento del artículo (para artículos nuevos)
- Disponibilidad del artículo (binario: 0/1)
Ejemplo de ingeniería de características:
Vector de entrada para "Pasta Carbonara" el miércoles, 20 de enero de 2024:
Ventas históricas:
[52, 48, 45, 51, 49, 0, 0] # Últimos 7 días (0 = cerrado)
[49, 51, 48, 52] # Últimos 4 miércoles
47.3 # Promedio del mes pasado
Temporal:
[0, 0, 1, 0, 0, 0, 0] # Día de la semana (Mié = posición 3)
3 # Semana del año
1 # Mes (enero)
0 # Es fin de semana
0 # Es festivo
Externo:
8.2 # Temperatura (°C)
0.0 # Precipitación
7.5 # Temperatura prevista mañana
Menú:
[0, 1, 0, 0] # Categoría (Plato principal)
14.50 # Precio (normalizado a escala 0-1)
450 # Días desde el lanzamiento
1 # Disponible hoy
2. Incrustación temporal
Propósito: Codificar patrones basados en el tiempo y relaciones cíclicas
Codificación posicional:
Usa funciones sinusoidales para capturar patrones periódicos:
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
Donde:
pos= posición en la secuencia (número del día)i= dimensiónd_model= dimensión de incrustación (256)
¿Por qué codificación sinusoidal?
- Captura múltiples ciclos (diario, semanal, mensual, anual)
- El modelo aprende qué ciclos son relevantes para cada artículo
- Permite extrapolación más allá del período de entrenamiento
- Maneja espaciado irregular (festivos, días cerrados)
Ejemplo:
# Codificación del ciclo semanal para el día de la semana
weekly_encoding = [
sin(day_of_week / 7 * 2π),
cos(day_of_week / 7 * 2π)
]
# Codificación del ciclo anual
annual_encoding = [
sin(day_of_year / 365 * 2π),
cos(day_of_year / 365 * 2π)
]
3. Mecanismo de atención multicabezal
Propósito: Identificar qué períodos históricos son más relevantes para la predicción actual
Cómo funciona la atención:
El modelo pregunta: "Al predecir el almuerzo del miércoles, ¿a qué días anteriores debo prestar atención?"
Fórmula de atención:
Attention(Q, K, V) = softmax(QK^T / √d_k) V
Donde:
- Q (Consulta): Lo que intentamos predecir (demanda de hoy)
- K (Claves): Días históricos a considerar
- V (Valores): Ventas reales de esos días
- d_k: Dimensión de los vectores clave
Enfoque multicabezal:
En lugar de un mecanismo de atención, usamos 8 cabezales de atención paralelos:
-
Cabezal 1: Se enfoca en patrones del mismo día de la semana
- "Los miércoles son similares a los miércoles anteriores"
-
Cabezal 2: Se enfoca en tendencias recientes
- "El patrón de la semana pasada continúa"
-
Cabezal 3: Se enfoca en patrones estacionales
- "Similar a esta época del año pasado"
-
Cabezal 4: Se enfoca en correlaciones meteorológicas
- "Días fríos como hoy tienen demanda similar"
-
Cabezal 5: Se enfoca en patrones de eventos
- "Días con eventos similares cercanos"
-
Cabezal 6: Se enfoca en dinámica del menú
- "Días con composición de menú similar"
-
Cabezal 7: Se enfoca en sensibilidad al precio
- "Días con estrategias de precios similares"
-
Cabezal 8: Se enfoca en tendencias de largo alcance
- "Dirección de tendencia de varios meses"
Ejemplo de pesos de atención:
Prediciendo miércoles, 20 de enero de 2024 para Pasta Carbonara:
Atención del cabezal 1 (día de la semana) a miércoles anteriores:
13 de enero (último mié): 0.35 (más reciente, mayor peso)
6 de enero: 0.28
30 de diciembre: 0.18
23 de diciembre: 0.12
Otros miércoles: 0.07
Atención del cabezal 2 (tendencia reciente) a los últimos 7 días:
19 de enero (ayer): 0.42
18 de enero: 0.24
17 de enero: 0.15
16 de enero: 0.10
Más antiguos: 0.09
Atención del cabezal 3 (estacional) al año pasado:
21 de enero de 2023: 0.55 (misma fecha del año pasado)
14-28 de enero de 2023: 0.45 (fechas circundantes)
4. Redes de alimentación directa
Propósito: Transformación no lineal y combinación de características
Arquitectura:
Entrada (256 dimensiones)
↓
Capa lineal 1 (256 → 1024)
↓
Activación ReLU
↓
Abandono (0.1)
↓
Capa lineal 2 (1024 → 256)
↓
Abandono (0.1)
↓
Conexión residual + Normalización de capa
¿Por qué dos capas?
- Expansión (256→1024): Crea espacio de representación de alta dimensión
- Compresión (1024→256): Extrae las características más relevantes
Regularización por abandono:
Desactiva aleatoriamente el 10% de las neuronas durante el entrenamiento para evitar el sobreajuste:
- El modelo aprende patrones robustos, no memorización
- Mejora la generalización a nuevos datos
- Crítico para conjuntos de datos pequeños (algunos restaurantes, artículos nuevos)
5. Apilamiento de capas
Cuatro bloques de transformadores apilados secuencialmente:
Bloque 1: Reconocimiento inicial de patrones
↓
Bloque 2: Extracción refinada de patrones
↓
Bloque 3: Aprendizaje de características de alto nivel
↓
Bloque 4: Representación final
Cada bloque contiene:
- Capa de atención multicabezal
- Normalización de capa
- Red de alimentación directa
- Conexiones residuales
¿Por qué cuatro capas?
Equilibrio entre:
- Complejidad: Más capas = más patrones reconocidos
- Eficiencia: Menos capas = entrenamiento e inferencia más rápidos
- Riesgo de sobreajuste: Demasiadas capas = memorización en lugar de aprendizaje
Las pruebas empíricas mostraron que 4 capas son óptimas para la previsión de demanda de restaurantes.
6. Proyección de salida
Propósito: Convertir la representación aprendida en predicción de cantidad
Enfoque de regresión cuantílica:
En lugar de predecir un solo valor, el modelo produce tres cuantiles:
Capa lineal (256 → 3)
↓
Salidas:
- Percentil 10 (límite inferior)
- Percentil 50 (mediana/estimación puntual)
- Percentil 90 (límite superior)
Ejemplo de salida:
{
"item": "Pasta Carbonara",
"date": "2024-01-20",
"predictions": {
"lower_bound": 45, // Percentil 10
"point_estimate": 52, // Percentil 50 (mediana)
"upper_bound": 59 // Percentil 90
}
}
¿Por qué regresión cuantílica?
- Captura la incertidumbre de la predicción de forma natural
- Proporciona intervalos de confianza accionables
- Más robusta a valores atípicos que enfoques basados en varianza
- Se alinea con las necesidades de toma de decisiones (preparar para el rango, no para un solo valor)
Proceso de entrenamiento
Preparación de datos
1. Recopilación de datos
Requisitos mínimos:
- 30 días de datos históricos de ventas (más de 90 días recomendado)
- Registros diarios completos (sin lagunas)
- Cantidades a nivel de artículo
2. Preprocesamiento de datos
Normalización:
# Normalización de puntuación Z para cantidades
normalized_quantity = (quantity - mean) / std_dev
# Normalización mín-máx para características externas
normalized_temp = (temp - min_temp) / (max_temp - min_temp)
Manejo de valores faltantes:
- Días cerrados: Marcados explícitamente (no imputados)
- Ventas faltantes: Relleno hacia adelante si son menos de 3 días consecutivos
- Datos meteorológicos: Interpolar desde estaciones cercanas
Detección de valores atípicos:
# Identificar y marcar (pero no eliminar) valores atípicos
z_score = (quantity - rolling_mean) / rolling_std
if abs(z_score) > 3:
flag_as_potential_outlier()
Valores atípicos preservados pero con menor peso durante el entrenamiento.
3. Generación de secuencias
Crear secuencias de entrada de longitudes variables:
Contexto corto (últimos 7 días):
[día-7, día-6, día-5, día-4, día-3, día-2, día-1] → [predecir: día-0]
Contexto medio (últimas 4 semanas):
[semana-4-mismo-día, semana-3-mismo-día, semana-2-mismo-día, semana-1-mismo-día] → [predecir: hoy]
Contexto largo (estacional):
[mes-12-misma-fecha, mes-6-misma-fecha, mes-3-misma-fecha] → [predecir: hoy]
Algoritmo de entrenamiento
Función de pérdida: Pérdida cuantílica
Para cada cuantil q (0.1, 0.5, 0.9):
L_q = (q - 1) * error si error < 0 (subpredicción)
q * error si error ≥ 0 (sobrepredicción)
Pérdida total = L_0.1 + L_0.5 + L_0.9
¿Por qué esta pérdida?
- Penaliza más la subpredicción para el cuantil superior (90)
- Penaliza más la sobrepredicción para el cuantil inferior (10)
- Equilibrada para la mediana (50)
- Asegura el orden correcto de los cuantiles (inferior < mediana < superior)
Optimización
Optimizador: AdamW (Adam con decaimiento de pesos)
Hiperparámetros:
learning_rate = 0.001 # Tasa de aprendizaje inicial
weight_decay = 0.01 # Regularización L2
beta_1 = 0.9 # Momento
beta_2 = 0.999 # Tasa de aprendizaje adaptativa
epsilon = 1e-8 # Estabilidad numérica
Programación de tasa de aprendizaje: Recocido cosenoidal con calentamiento
# Fase de calentamiento (primer 10% del entrenamiento)
lr = initial_lr * (step / warmup_steps)
# Fase de recocido cosenoidal
lr = min_lr + 0.5 * (max_lr - min_lr) * (1 + cos(π * step / total_steps))
Beneficios:
- El calentamiento gradual evita la divergencia temprana
- El decaimiento cosenoidal permite el ajuste fino cerca del final
- Múltiples ciclos permiten escapar de mínimos locales
Iteraciones de entrenamiento
Épocas: 100-200 dependiendo del tamaño de los datos
Tamaño de lote: 32 secuencias
División de validación: 20% de los datos reservados
Detención temprana:
if validation_loss_not_improved_for(patience=15_epochs):
stop_training()
restore_best_model()
Técnicas de regularización
1. Abandono
- Abandono de atención: 0.1
- Abandono de alimentación directa: 0.1
- Abandono de incrustación: 0.05
2. Decaimiento de pesos
- Penalización L2 en pesos: 0.01
- Evita que los pesos crezcan demasiado
3. Suavizado de etiquetas
- Difumina ligeramente los valores objetivo
- Mejora la calibración de los intervalos de confianza
4. Aumento de datos
- Fluctuación aleatoria de valores históricos (±5%)
- Simula la incertidumbre de medición
- Mejora la robustez
Validación y pruebas
División entrenamiento/validación/prueba
Datos históricos (180 días en total):
- Entrenamiento: Días 1-126 (70%)
- Validación: Días 127-162 (20%)
- Prueba: Días 163-180 (10%)
Validación de avance progresivo:
En lugar de división aleatoria, usar división temporal:
- Entrenar solo con datos pasados
- Validar con datos futuros
- Evita la fuga de datos (usar el futuro para predecir el pasado)
Métricas de rendimiento
Error porcentual absoluto medio:
Error porcentual absoluto medio = (1/n) * Σ |real - predicho| / real * 100%
Puntuación de calibración:
Esperado: 80% de los reales dentro del intervalo de confianza
Real: Contar cuántos reales caen dentro de [inferior, superior]
Calibración = Cobertura real / Cobertura esperada
Pérdida cuantílica:
Pérdida cuantílica = Σ todos los cuantiles (pérdida cuantílica como se definió arriba)
Proceso de inferencia
Generación de predicciones diarias
Cronograma: Se ejecuta automáticamente a las 3:00 AM hora local
Proceso:
-
Recopilación de datos (3:00-3:05 AM)
- Obtener datos de ventas finales de ayer
- Recuperar pronóstico del tiempo para los próximos 7 días
- Comprobar calendario de eventos para próximas fechas
- Cargar configuración actual del menú
-
Ingeniería de características (3:05-3:10 AM)
- Calcular promedios móviles y tendencias
- Codificar características temporales
- Normalizar variables externas
- Crear secuencias de entrada
-
Inferencia del modelo (3:10-3:15 AM)
- Paso hacia adelante a través de la red neuronal
- Generar predicciones para los próximos 7 días
- Calcular intervalos de confianza
- Computar métricas de precisión
-
Posprocesamiento (3:15-3:20 AM)
- Redondear predicciones a enteros
- Aplicar reglas de negocio (mínimo=0, máximo=capacidad)
- Marcar predicciones inusuales para revisión
- Generar informes de precisión
-
Entrega (3:20-3:25 AM)
- Enviar a puntos finales de la interfaz de programación de aplicaciones
- Actualizar interfaz del panel de control
- Enviar alertas por correo (si está configurado)
- Registrar predicciones para seguimiento
Latencia: menos de 5 minutos para restaurante típico (100 artículos del menú)
Aprendizaje continuo
Cómo mejora el modelo con el tiempo:
Reentrenamiento semanal
Cada lunes a las 4:00 AM:
- Incorporar las ventas reales de la semana anterior
- Reentrenar el modelo con datos actualizados
- Evaluar mejoras de rendimiento
- Implementar el modelo actualizado si mejora la precisión
Integración de comentarios
Variaciones reportadas por usuarios retroalimentadas al entrenamiento:
- Eventos especiales marcados manualmente
- Circunstancias inusuales documentadas
- Razones de anulación analizadas
- Ingeniería de características mejorada
Detección de deriva conceptual
Monitorizar cambios en patrones de demanda:
if recent_accuracy < historical_accuracy - threshold:
trigger_model_refresh()
investigate_potential_concept_drift()
Causas comunes:
- Cambios de menú
- Nueva competencia
- Transiciones estacionales
- Cambios operacionales
Características avanzadas
Correlación entre artículos
Atención cruzada entre artículos:
El modelo aprende relaciones entre artículos:
- Efectos de sustitución: "Si el salmón es popular, la demanda de ensalada disminuye"
- Efectos complementarios: "Las ventas de postres se correlacionan con el volumen de platos principales"
- Ingeniería del menú: "Los especiales canibalizan artículos regulares"
Implementación:
# Atender no solo al historial propio del artículo, sino a artículos relacionados
attention_context = [
item_own_history,
substitute_items_history,
complement_items_history,
category_average_history
]
Predicciones de conjunto
Múltiples variantes de modelo:
Entrenar varios modelos con diferentes arquitecturas:
- Modelo A: Transformador (principal)
- Modelo B: Memoria de corto y largo plazo (referencia recurrente)
- Modelo C: Potenciación de gradiente (basado en árboles)
Combinación ponderada:
final_prediction = (
0.70 * transformer_prediction +
0.20 * lstm_prediction +
0.10 * gbm_prediction
)
Pesos determinados por la precisión histórica.
Cuantificación de incertidumbre
Fuentes de incertidumbre:
-
Aleatoria (aleatoriedad irreducible)
- Comportamiento del cliente inherentemente impredecible
- Eventos aleatorios (fluctuaciones meteorológicas)
-
Epistémica (incertidumbre del modelo)
- Datos de entrenamiento insuficientes
- Limitaciones de capacidad del modelo
- Nuevos escenarios que no están en el conjunto de entrenamiento
Puntuación de confianza:
confidence_score = f(
data_quality, # ¿Qué tan limpios son los datos históricos?
training_data_volume, # ¿Cuántos datos están disponibles?
similarity_to_training, # ¿Qué tan similar es el día de predicción a los días de entrenamiento?
model_agreement # ¿Los modelos del conjunto están de acuerdo?
)
Mayor confianza → intervalos más estrechos Menor confianza → intervalos más amplios
Aprendizaje por transferencia
Aprendizaje entre ubicaciones:
Para cadenas de restaurantes:
- Preentrenar con datos de todas las ubicaciones
- Ajustar con datos de ubicación individual
- Transferir patrones (estacionales, meteorológicos, eventos)
- Inicio más rápido para nuevas ubicaciones
Beneficios:
- Predicciones para nueva ubicación disponibles inmediatamente
- Mayor precisión inicial
- Convergencia más rápida del modelo
- Aprendizaje compartido en toda la organización
Rendimiento del modelo
Puntos de referencia
Precisión vs referencias:
| Método | Error porcentual absoluto medio | Notas |
|---|---|---|
| Eaternity Forecast | 12,8% | Arquitectura de transformadores |
| Pronosticador humano experto | 17,1% | 25% menos preciso |
| Mismo día de la semana anterior | 22,4% | Referencia ingenua |
| Promedio de 4 semanas | 19,7% | Referencia estadística simple |
| Modelo autorregresivo integrado de media móvil | 16,2% | Series temporales tradicionales |
| Memoria de corto y largo plazo | 14,1% | Red neuronal recurrente |
Calibración del intervalo de confianza:
Esperado: 80% de los reales dentro de [inferior, superior] Logrado: 78,5% (bien calibrado)
Requisitos computacionales
Entrenamiento:
- Unidad de procesamiento gráfico: NVIDIA RTX 4090 o equivalente
- Memoria: 32 GB mínimo
- Tiempo de entrenamiento: 2-6 horas (depende del volumen de datos)
- Almacenamiento: 5-20 GB por restaurante
Inferencia:
- Unidad de procesamiento central: Suficiente para predicciones en tiempo real
- Memoria: 8 GB
- Latencia: menos de 100ms por predicción
- Almacenamiento: menos de 1 GB para modelo implementado
Fundamento de investigación
Referencias académicas
Forecast se basa en investigación revisada por pares:
-
Arquitectura de transformadores
- Vaswani et al. (2017) "Attention Is All You Need"
- Artículo original de transformadores para procesamiento de lenguaje natural
-
Previsión de series temporales
- Zhou et al. (2021) "Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting"
- Transformadores temporales para previsión
-
Previsión de demanda
- Taylor & Letham (2018) "Forecasting at Scale" (Facebook Prophet)
- Sistemas de previsión a escala industrial
-
Regresión cuantílica
- Koenker & Bassett (1978) "Regression Quantiles"
- Teoría fundamental de regresión cuantílica
-
Operaciones de restaurantes
- Miller et al. (2015) "Forecasting Restaurant Demand"
- Desafíos de previsión específicos del dominio
Mejoras futuras
Hoja de ruta
T2 2024: Visualización de atención
- Mostrar qué días históricos el modelo enfoca
- Explicar predicciones a los usuarios
T3 2024: Previsión a nivel de receta
- Predecir requisitos de ingredientes directamente
- Integración con sistemas de inventario
T4 2024: Inferencia causal
- Comprender el impacto de cambios de menú antes de la implementación
- Simular efectos promocionales
2025: Aprendizaje multimodal
- Incorporar sentimiento de redes sociales
- Análisis visual del menú
- Sentimiento de reseñas de clientes
Ved también
- Estudio de rendimiento — Resultados de validación y puntos de referencia
- Confianza en las predicciones — Comprender la incertidumbre
- Guía de implementación — Mejores prácticas de uso
- Referencia de la interfaz de programación de aplicaciones — Detalles técnicos de integración