Propósito de la sesión

En los negocios, muchas variables no se observan una sola vez: se registran día tras día, semana tras semana, mes tras mes o año tras año. Ventas, demanda, inventarios, precios, tasas de cambio, número de clientes, exportaciones, costos logísticos y tiempos de entrega son ejemplos naturales.

Cuando el orden temporal importa, ya no basta con resumir los datos con una media o una desviación estándar. La pregunta cambia:

¿Cómo ha evolucionado la variable en el tiempo y qué patrones pueden explicar su comportamiento?

Esta sesión introduce el análisis de series de tiempo con un enfoque aplicado a los negocios. No pretende desarrollar todavía modelos ARIMA ni técnicas avanzadas de pronóstico. El objetivo es aprender a leer, describir, separar y modelar los principales patrones temporales.

Idea guía de la sesión

Una serie de tiempo no se estudia solo para describir el pasado. En negocios se analiza para entender patrones, anticipar comportamientos y apoyar decisiones sobre inventario, ventas, compras, precios y capacidad.

Al finalizar, se espera que el estudiante pueda:

  1. reconocer cuándo un conjunto de datos constituye una serie de tiempo;
  2. identificar tendencia, estacionalidad, movimientos cíclicos y variación irregular;
  3. distinguir entre modelos aditivos y multiplicativos;
  4. utilizar suavizamiento para observar mejor la tendencia;
  5. ajustar e interpretar modelos de tendencia lineal, cuadrática y exponencial;
  6. reconocer la presencia de sesgo en datos o pronósticos;
  7. comprender qué significa que una variable esté censurada;
  8. interpretar los resultados en términos de una decisión de negocio.

1. ¿Qué es una serie de tiempo?

Cowpertwait y Metcalfe (2009) señalan que muchas variables de la ciencia, la ingeniería y el comercio son medidas secuencialmente en el tiempo. Una idea central de su definición es:

“When a variable is measured sequentially in time … the resulting data form a time series.”

En términos prácticos:

Una serie de tiempo es un conjunto de observaciones de una variable registradas en orden temporal.

La podemos representar mediante

\[ \{Y_t\}=\{Y_1,Y_2,\ldots,Y_n\}, \]

donde:

  • \(Y_t\) es el valor observado de la variable en el periodo \(t\);
  • \(t\) indica la posición temporal;
  • \(n\) es el número total de observaciones.

Ejemplos empresariales

  • ventas mensuales de una cadena de tiendas;
  • exportaciones trimestrales de café;
  • tasa representativa del mercado observada diariamente;
  • número de pedidos recibidos cada hora;
  • costo mensual de transporte internacional;
  • inventario disponible al cierre de cada semana;
  • número de clientes activos cada mes;
  • precio diario de una acción.

Mini ejemplo aplicado

Si una empresa registra las ventas totales de cada mes durante 5 años, entonces tiene una serie de tiempo mensual. Si además registra el número de pedidos cada día, también dispone de una serie diaria. Ambas son series de tiempo, pero responden preguntas distintas.

1.1 El intervalo de observación

El tiempo entre dos observaciones consecutivas se denomina intervalo de muestreo.

Una serie puede ser:

  • horaria;
  • diaria;
  • semanal;
  • mensual;
  • trimestral;
  • semestral;
  • anual.

La frecuencia no es un detalle menor. Determina qué patrones pueden observarse.

Por ejemplo, una serie anual de ventas puede mostrar crecimiento de largo plazo, pero difícilmente permitirá estudiar el comportamiento particular de diciembre.

Pregunta para discutir

Una empresa registra únicamente sus ventas anuales. ¿Podría determinar con esos datos si diciembre es sistemáticamente mejor que enero?

1.2 El orden temporal importa

En datos de corte transversal, cambiar el orden de las filas normalmente no cambia el análisis. En una serie de tiempo sí.

Si tenemos:

\[ 120,\;130,\;140,\;150, \]

observamos una evolución diferente de:

\[ 150,\;120,\;140,\;130. \]

Los mismos cuatro valores producen una historia temporal distinta.

Además, Cowpertwait y Metcalfe resaltan otra característica fundamental: observaciones cercanas en el tiempo suelen estar relacionadas entre sí. En otras palabras, lo que ocurre hoy puede estar relacionado con lo ocurrido ayer.

Esta dependencia temporal es una de las razones por las cuales el análisis de series de tiempo requiere métodos particulares.


2. Antes de modelar: graficar la serie

Un principio sencillo y poderoso es:

\[ \boxed{\text{Primero observar; después modelar}} \]

Una gráfica temporal puede revelar:

  • tendencia;
  • estacionalidad;
  • cambios estructurales;
  • valores atípicos;
  • periodos faltantes;
  • cambios en la variabilidad;
  • posibles errores de registro.

Cowpertwait y Metcalfe (2009) enfatizan que el gráfico temporal permite reconocer patrones, pero también puede poner en evidencia observaciones atípicas o valores erróneos.


3. Caso de trabajo: Nova Market

Trabajaremos con una empresa ficticia llamada Nova Market, que registra mensualmente la demanda y las ventas de una categoría de productos.

El caso ha sido diseñado para contener varias situaciones típicas de negocios:

  • crecimiento gradual de la demanda;
  • meses de alta y baja actividad;
  • promociones comerciales;
  • variación aleatoria;
  • meses con inventario insuficiente.

La ventaja de trabajar con datos simulados es que conocemos la demanda real no observada por la empresa, lo cual permitirá explicar el censuramiento.

3.1 Generación reproducible de los datos

set.seed(410)

fechas <- seq(
  from = as.Date("2021-01-01"),
  to   = as.Date("2025-12-01"),
  by   = "month"
)

n <- length(fechas)
t <- 1:n

mes_num <- month(fechas)
anio <- year(fechas)

nombres_mes <- c(
  "Enero", "Febrero", "Marzo", "Abril",
  "Mayo", "Junio", "Julio", "Agosto",
  "Septiembre", "Octubre", "Noviembre", "Diciembre"
)

# Patrón estacional de la demanda
factor_estacional <- c(
  0.82, 0.86, 0.92, 0.96,
  1.00, 1.04, 1.00, 0.98,
  1.03, 1.08, 1.18, 1.34
)

# Tendencia de largo plazo
tendencia <- 420 + 5.5 * t

# Promociones comerciales
promocion <- rbinom(n, size = 1, prob = 0.20)

# Demanda latente: lo que los clientes realmente quisieron comprar
demanda_latente <- round(
  tendencia * factor_estacional[mes_num] +
    55 * promocion +
    rnorm(n, mean = 0, sd = 25)
)

demanda_latente <- pmax(demanda_latente, 1)

# En condiciones normales hay inventario suficiente
inventario <- round(
  demanda_latente + runif(n, min = 35, max = 110)
)

# Se fuerzan algunos meses con quiebre de inventario,
# especialmente en periodos de demanda alta.
meses_quiebre <- c(24, 36, 47, 48, 58, 59, 60)

inventario[meses_quiebre] <- round(
  demanda_latente[meses_quiebre] *
    runif(length(meses_quiebre), min = 0.72, max = 0.90)
)

# Las ventas observadas no pueden superar el inventario disponible
ventas <- pmin(demanda_latente, inventario)

datos <- tibble(
  fecha = fechas,
  t = t,
  anio = anio,
  mes_num = mes_num,
  mes = factor(
    nombres_mes[mes_num],
    levels = nombres_mes
  ),
  promocion = factor(
    promocion,
    levels = c(0, 1),
    labels = c("No", "Sí")
  ),
  demanda_latente = demanda_latente,
  inventario = inventario,
  ventas = ventas,
  quiebre_stock = ventas < demanda_latente
)

head(datos, 12)

En una empresa real, normalmente no conoceríamos la demanda latente en los meses con agotamiento de inventario. Aquí la conservamos únicamente porque los datos son simulados y queremos estudiar el problema de censuramiento.

3.2 Primera gráfica temporal

ggplot(datos, aes(x = fecha, y = ventas)) +
  geom_line(linewidth = 1, color = "#1f77b4") +
  geom_point(size = 2.1, color = "#d62728") +
  labs(
    title = "Nova Market: ventas mensuales",
    subtitle = "Serie mensual 2021–2025",
    x = "Fecha",
    y = "Unidades vendidas"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    plot.subtitle = element_text(color = "#5d6d7e"),
    axis.title = element_text(face = "bold")
  )

Antes de calcular cualquier modelo, observe la gráfica y responda mentalmente:

  1. ¿Las ventas parecen aumentar con el tiempo?
  2. ¿Se observan picos que se repiten?
  3. ¿Todos los años parecen comportarse igual?
  4. ¿Hay meses inusualmente bajos o altos?
  5. ¿La variabilidad parece mantenerse constante?

4. Componentes de una serie de tiempo

Una serie temporal puede contener varios tipos de comportamiento simultáneamente.

Para esta introducción distinguiremos:

\[ \boxed{ \text{Tendencia}+ \text{Estacionalidad}+ \text{Ciclo}+ \text{Variación irregular} } \]

No todas las series presentan todos los componentes.


5. Tendencia

La tendencia describe la dirección general o evolución de largo plazo de una serie.

Puede ser:

  • creciente;
  • decreciente;
  • aproximadamente constante;
  • curvilínea;
  • cambiante.

Por ejemplo, si una empresa aumenta gradualmente su número de clientes durante cinco años, la serie puede presentar una tendencia creciente.

Interpretación empresarial

Una tendencia creciente en ventas podría relacionarse con expansión del mercado, apertura de nuevos canales, aumento de clientes, inflación, crecimiento poblacional o una combinación de factores.

Pero una tendencia no demuestra por sí sola causalidad.

5.1 Tendencia determinística y tendencia estocástica

Los textos base distinguen entre tendencias determinísticas y tendencias estocásticas.

Cowpertwait y Metcalfe (2009) explican que una tendencia puede modelarse de manera determinística cuando existe una evolución relativamente regular que puede representarse mediante una función del tiempo. En cambio, ciertas series económicas y financieras pueden mostrar cambios de dirección difíciles de explicar mediante una función fija.

Cryer y Chan (2008) también separan explícitamente el estudio de tendencias determinísticas y procesos no estacionarios de naturaleza estocástica.

En este curso introductorio trabajaremos principalmente con modelos determinísticos de tendencia, por ejemplo:

\[ Y_t=\beta_0+\beta_1t+\varepsilon_t. \]


6. Estacionalidad

Cowpertwait y Metcalfe (2009) describen la variación estacional como un patrón que se repite dentro de un periodo fijo.

No necesariamente tiene que tratarse de estaciones climáticas.

Puede existir estacionalidad:

  • por mes del año;
  • por trimestre;
  • por día de la semana;
  • por hora del día;
  • alrededor de fechas comerciales.

Ejemplos

  • aumento de ventas minoristas en diciembre;
  • mayor ocupación hotelera en temporadas vacacionales;
  • reducción de tráfico empresarial los domingos;
  • aumento de pedidos de comida durante ciertas horas;
  • mayor demanda de útiles escolares antes del inicio de clases.

6.1 Estacionalidad no es lo mismo que ciclo

Una diferencia importante:

Estacionalidad: se repite con una periodicidad conocida y aproximadamente fija.

Ciclo: presenta oscilaciones de mayor duración, pero sin una periodicidad necesariamente fija.

Cowpertwait y Metcalfe mencionan como ejemplo los ciclos de negocios, que no tienen por qué repetirse exactamente cada cierto número de meses.

Por tanto:

\[ \boxed{\text{repetición fija} \Rightarrow \text{estacionalidad}} \]

mientras que

\[ \boxed{\text{oscilación sin periodo fijo} \Rightarrow \text{componente cíclico}} \]


7. Variación irregular

Incluso después de explicar tendencia y estacionalidad, siempre queda una parte de la serie que no sigue un patrón perfectamente predecible.

Puede deberse a:

  • ruido aleatorio;
  • errores de medición;
  • promociones inesperadas;
  • problemas logísticos;
  • huelgas;
  • cierres;
  • eventos climáticos;
  • cambios regulatorios;
  • acontecimientos extraordinarios.

Esta parte suele denominarse componente irregular, error o residuo, dependiendo del enfoque utilizado.


8. Descomposición de una serie

Cowpertwait y Metcalfe (2009) presentan una descomposición aditiva básica:

\[ X_t=m_t+s_t+z_t, \]

donde:

  • \(X_t\): valor observado;
  • \(m_t\): tendencia;
  • \(s_t\): efecto estacional;
  • \(z_t\): componente de error.

Esta representación es muy útil porque obliga a pensar en una observación como la combinación de distintas fuentes de variación.

8.1 Modelo aditivo

Usamos un modelo aditivo cuando el efecto estacional tiene aproximadamente el mismo tamaño absoluto a lo largo del tiempo:

\[ X_t=T_t+S_t+E_t. \]

Ejemplo

Si cada diciembre una empresa vende aproximadamente 100 unidades adicionales, independientemente del nivel general de ventas, un esquema aditivo puede ser razonable.

8.2 Modelo multiplicativo

Cowpertwait y Metcalfe proponen considerar un esquema multiplicativo cuando el efecto estacional aumenta junto con el nivel de la serie:

\[ X_t=T_tS_t+E_t. \]

En una interpretación empresarial sencilla, el efecto estacional se comporta más como un porcentaje que como una cantidad fija.

Ejemplo

Si diciembre suele vender alrededor de 30 % más que un mes normal, el efecto aumenta cuando crece el nivel general de ventas.

8.3 ¿Aditivo o multiplicativo?

Una regla visual inicial:

  • si las oscilaciones estacionales mantienen amplitud aproximadamente constante, considere un modelo aditivo;
  • si las oscilaciones aumentan cuando aumenta el nivel de la serie, considere un modelo multiplicativo.

Esto debe complementarse con el análisis de los residuos y el contexto del negocio.


9. Suavizamiento y medias móviles

Las series reales pueden tener mucho ruido. Para observar mejor su dirección de largo plazo se pueden usar técnicas de suavizamiento.

Una media móvil simple de orden \(k\) puede escribirse como:

\[ MA_t= \frac{ Y_t+Y_{t-1}+\cdots+Y_{t-k+1} }{k}. \]

La idea es sencilla:

reemplazar parte de la variación de corto plazo por un promedio local para visualizar mejor el comportamiento subyacente.

Cowpertwait y Metcalfe (2009) presentan las medias móviles como una forma de estimar tendencia sin imponer inicialmente una forma funcional específica.

9.1 Media móvil de tres meses

datos <- datos %>%
  mutate(
    media_movil_3 = as.numeric(
      stats::filter(
        ventas,
        filter = rep(1/3, 3),
        sides = 2
      )
    )
  )

ggplot(datos, aes(x = fecha)) +
  geom_line(aes(y = ventas), linewidth = 0.8, color = "#7f8c8d") +
  geom_line(
    aes(y = media_movil_3),
    linewidth = 1.2,
    color = "#e67e22"
  ) +
  labs(
    title = "Ventas y media móvil centrada de 3 meses",
    x = "Fecha",
    y = "Unidades"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    axis.title = element_text(face = "bold")
  )

La media móvil suaviza los cambios mensuales, pero también elimina información de corto plazo.

Para discutir

¿Una serie más suave es necesariamente una serie mejor?

No. Suavizar ayuda a observar patrones, pero puede ocultar cambios importantes para la operación.

9.2 Media móvil centrada 2×12

En una serie mensual con estacionalidad anual, una forma clásica de estimar la tendencia es utilizar una media móvil centrada de 12 meses.

Como 12 es un número par, el centrado exacto se obtiene aplicando una media \(2\times12\), con pesos:

\[ \frac{1}{24}, \frac{1}{12}, \ldots, \frac{1}{12}, \frac{1}{24}. \]

pesos_2x12 <- c(0.5, rep(1, 11), 0.5) / 12

datos <- datos %>%
  mutate(
    tendencia_ma_2x12 = as.numeric(
      stats::filter(
        ventas,
        filter = pesos_2x12,
        sides = 2
      )
    )
  )

ggplot(datos, aes(x = fecha)) +
  geom_line(aes(y = ventas), linewidth = 0.7, color = "#95a5a6") +
  geom_line(
    aes(y = tendencia_ma_2x12),
    linewidth = 1.3,
    color = "#16a085",
    na.rm = TRUE
  ) +
  labs(
    title = "Ventas y tendencia suavizada con media móvil 2×12",
    x = "Fecha",
    y = "Unidades"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    axis.title = element_text(face = "bold")
  )


10. Descomposición clásica en R

Convertimos las ventas mensuales en un objeto ts con frecuencia 12.

ventas_ts <- ts(
  datos$ventas,
  start = c(2021, 1),
  frequency = 12
)

ventas_ts
##      Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
## 2021 376 348 441 417 405 456 492 446 512 495 561 610
## 2022 345 485 494 500 557 610 583 516 572 583 587 669
## 2023 473 546 511 568 603 592 622 595 617 707 705 672
## 2024 524 645 630 573 590 734 645 658 769 727 658 667
## 2025 577 616 630 674 703 779 721 761 768 655 799 822

10.1 Descomposición aditiva

descomp_aditiva <- decompose(
  ventas_ts,
  type = "additive"
)

plot(descomp_aditiva)

La salida separa visualmente:

  • serie observada;
  • tendencia;
  • componente estacional;
  • componente aleatorio.

La descomposición no “descubre la verdad”. Es una forma de representar la serie bajo determinados supuestos. Los componentes obtenidos deben interpretarse en el contexto del negocio.

10.2 Serie ajustada estacionalmente

En el modelo aditivo:

\[ Y_t^{(ajustada)} = Y_t-\widehat{S}_t. \]

datos <- datos %>%
  mutate(
    componente_estacional = as.numeric(descomp_aditiva$seasonal),
    ventas_ajustadas = ventas - componente_estacional
  )

ggplot(datos, aes(x = fecha)) +
  geom_line(aes(y = ventas), linewidth = 0.8, color = "#2980b9") +
  geom_line(aes(y = ventas_ajustadas), linewidth = 1.1, color = "#c0392b") +
  labs(
    title = "Ventas observadas y ventas ajustadas por estacionalidad",
    x = "Fecha",
    y = "Unidades"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    axis.title = element_text(face = "bold")
  )

La serie ajustada ayuda a responder preguntas como:

¿El negocio realmente creció o solamente estaba entrando en su temporada alta?


11. Análisis estacional por mes

Una forma exploratoria sencilla consiste en comparar la distribución de ventas por mes.

ggplot(datos, aes(x = mes, y = ventas, fill = mes)) +
  geom_boxplot(alpha = 0.85, color = "#34495e") +
  scale_fill_hue() +
  labs(
    title = "Distribución de ventas según el mes",
    x = "Mes",
    y = "Unidades vendidas"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    axis.text.x = element_text(
      angle = 45,
      hjust = 1
    ),
    legend.position = "none"
  )

Si diciembre aparece sistemáticamente por encima de enero, tenemos evidencia visual de una diferencia estacional.

Pero cuidado:

\[ \boxed{ \text{un diciembre alto una sola vez} \neq \text{estacionalidad} } \]

Para hablar de estacionalidad necesitamos observar un patrón que se repite en varios ciclos.


12. Índices estacionales multiplicativos

También podemos usar una descomposición multiplicativa.

descomp_mult <- decompose(
  ventas_ts,
  type = "multiplicative"
)

indices_estacionales <- tibble(
  mes = factor(nombres_mes, levels = nombres_mes),
  indice = as.numeric(descomp_mult$figure)
)

kable(
  indices_estacionales,
  digits = 3,
  col.names = c("Mes", "Índice estacional")
)
Mes Índice estacional
Enero 0.793
Febrero 0.946
Marzo 0.925
Abril 0.939
Mayo 0.991
Junio 1.085
Julio 1.034
Agosto 0.964
Septiembre 1.067
Octubre 1.074
Noviembre 1.072
Diciembre 1.110

Una interpretación aproximada es:

  • índice \(=1\): comportamiento cercano al nivel esperado;
  • índice \(>1\): periodo por encima del nivel esperado;
  • índice \(<1\): periodo por debajo del nivel esperado.

Por ejemplo:

\[ S_{\text{diciembre}}=1.20 \]

se interpretaría como:

diciembre tiende a ubicarse aproximadamente 20 % por encima del nivel de la serie, una vez considerado el esquema multiplicativo.


13. Modelos de tendencia

Además del suavizamiento, podemos representar la tendencia mediante una función matemática.

Trabajaremos con tres modelos básicos:

  1. tendencia lineal;
  2. tendencia cuadrática;
  3. tendencia exponencial.

La finalidad no es “encontrar una ecuación bonita”, sino producir una representación interpretable del cambio de largo plazo.


14. Tendencia lineal

El modelo lineal es:

\[ Y_t=\beta_0+\beta_1t+\varepsilon_t. \]

donde:

  • \(\beta_0\): nivel de referencia;
  • \(\beta_1\): cambio promedio por periodo;
  • \(\varepsilon_t\): parte no explicada por la tendencia.
modelo_lineal <- lm(
  ventas ~ t,
  data = datos
)

summary(modelo_lineal)
## 
## Call:
## lm(formula = ventas ~ t, data = datos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -152.140  -27.101   -4.598   37.096  118.353 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  425.731     15.678   27.16   <2e-16 ***
## t              5.493      0.447   12.29   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 59.96 on 58 degrees of freedom
## Multiple R-squared:  0.7225, Adjusted R-squared:  0.7177 
## F-statistic:   151 on 1 and 58 DF,  p-value: < 2.2e-16

La pendiente se obtiene con:

coef(modelo_lineal)["t"]
##       t 
## 5.49297

Si, por ejemplo, la pendiente fuera \(5.2\), interpretaríamos:

según el modelo lineal, las ventas aumentan en promedio aproximadamente 5.2 unidades por mes.

14.1 Visualización

datos <- datos %>%
  mutate(
    ajuste_lineal = predict(
      modelo_lineal,
      newdata = datos
    )
  )

ggplot(datos, aes(x = fecha, y = ventas)) +
  geom_line(linewidth = 0.7, color = "#7f8c8d") +
  geom_point(size = 1.8, color = "#7f8c8d") +
  geom_line(
    aes(y = ajuste_lineal),
    linewidth = 1.2,
    color = "#8e44ad"
  ) +
  labs(
    title = "Ajuste de una tendencia lineal",
    x = "Fecha",
    y = "Unidades vendidas"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    axis.title = element_text(face = "bold")
  )


15. Tendencia cuadrática

Si la velocidad de crecimiento cambia a través del tiempo, una línea recta puede resultar demasiado rígida.

Podemos considerar:

\[ Y_t= \beta_0+\beta_1t+\beta_2t^2+\varepsilon_t. \]

modelo_cuadratico <- lm(
  ventas ~ t + I(t^2),
  data = datos
)

summary(modelo_cuadratico)
## 
## Call:
## lm(formula = ventas ~ t + I(t^2), data = datos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -151.954  -27.724   -2.969   40.699  119.596 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 407.22659   24.01185  16.959  < 2e-16 ***
## t             7.28373    1.81630   4.010 0.000178 ***
## I(t^2)       -0.02936    0.02886  -1.017 0.313356    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 59.94 on 57 degrees of freedom
## Multiple R-squared:  0.7275, Adjusted R-squared:  0.7179 
## F-statistic: 76.07 on 2 and 57 DF,  p-value: < 2.2e-16
datos <- datos %>%
  mutate(
    ajuste_cuadratico = predict(
      modelo_cuadratico,
      newdata = datos
    )
  )

ggplot(datos, aes(x = fecha, y = ventas)) +
  geom_line(linewidth = 0.7, color = "#95a5a6") +
  geom_point(size = 1.8, color = "#95a5a6") +
  geom_line(
    aes(y = ajuste_cuadratico),
    linewidth = 1.2,
    color = "#27ae60"
  ) +
  labs(
    title = "Ajuste de una tendencia cuadrática",
    x = "Fecha",
    y = "Unidades vendidas"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    axis.title = element_text(face = "bold")
  )

Un polinomio de mayor grado puede ajustarse muy bien a los datos históricos y aun así producir extrapolaciones absurdas.

Cowpertwait y Metcalfe advierten que los polinomios de alto orden no son una buena elección para extrapolar tendencias a largo plazo.


16. Tendencia exponencial

Cuando el crecimiento parece proporcional al nivel de la serie, podemos utilizar un modelo exponencial:

\[ Y_t=ae^{bt}. \]

Aplicando logaritmo natural:

\[ \log(Y_t)=\log(a)+bt. \]

Así podemos estimarlo mediante regresión lineal.

modelo_exponencial <- lm(
  log(ventas) ~ t,
  data = datos
)

summary(modelo_exponencial)
## 
## Call:
## lm(formula = log(ventas) ~ t, data = datos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.35393 -0.05190 -0.00161  0.07307  0.22564 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 6.0718874  0.0290009  209.37   <2e-16 ***
## t           0.0096608  0.0008269   11.68   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1109 on 58 degrees of freedom
## Multiple R-squared:  0.7018, Adjusted R-squared:  0.6967 
## F-statistic: 136.5 on 1 and 58 DF,  p-value: < 2.2e-16

Reconstruimos el ajuste en la escala original:

datos <- datos %>%
  mutate(
    ajuste_exponencial = exp(
      predict(
        modelo_exponencial,
        newdata = datos
      )
    )
  )

ggplot(datos, aes(x = fecha, y = ventas)) +
  geom_line(linewidth = 0.7, color = "#bdc3c7") +
  geom_point(size = 1.8, color = "#bdc3c7") +
  geom_line(
    aes(y = ajuste_exponencial),
    linewidth = 1.2,
    color = "#e74c3c"
  ) +
  labs(
    title = "Ajuste de una tendencia exponencial",
    x = "Fecha",
    y = "Unidades vendidas"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    axis.title = element_text(face = "bold")
  )

16.1 Interpretación de la tasa de crecimiento

Si \(b\) es el coeficiente de t, una aproximación más precisa de la tasa porcentual por periodo es:

\[ g=100(e^b-1). \]

b <- coef(modelo_exponencial)["t"]

tasa_crecimiento <- 100 * (exp(b) - 1)

tasa_crecimiento
##         t 
## 0.9707663

17. Comparación descriptiva de los modelos

No conviene seleccionar un modelo solamente porque tenga el mayor \(R^2\).

Podemos comparar, entre otros aspectos:

  • coherencia gráfica;
  • interpretación;
  • magnitud de los errores;
  • comportamiento de los residuos;
  • sentido empresarial;
  • desempeño fuera de la muestra.

Definimos el error:

\[ e_t=Y_t-\widehat{Y}_t. \]

Dos medidas de ajuste muy utilizadas son:

\[ MAE= \frac{1}{n} \sum_{t=1}^{n} |e_t| \]

y

\[ RMSE= \sqrt{ \frac{1}{n} \sum_{t=1}^{n} e_t^2 }. \]

metricas <- bind_rows(
  tibble(
    Modelo = "Lineal",
    MAE = mean(abs(datos$ventas - datos$ajuste_lineal)),
    RMSE = sqrt(mean((datos$ventas - datos$ajuste_lineal)^2))
  ),
  tibble(
    Modelo = "Cuadrático",
    MAE = mean(abs(datos$ventas - datos$ajuste_cuadratico)),
    RMSE = sqrt(mean((datos$ventas - datos$ajuste_cuadratico)^2))
  ),
  tibble(
    Modelo = "Exponencial",
    MAE = mean(abs(datos$ventas - datos$ajuste_exponencial)),
    RMSE = sqrt(mean((datos$ventas - datos$ajuste_exponencial)^2))
  )
)

kable(
  metricas,
  digits = 2
)
Modelo MAE RMSE
Lineal 46.99 58.95
Cuadrático 46.73 58.43
Exponencial 47.78 60.43

Estas métricas se calcularon sobre los mismos datos utilizados para ajustar los modelos. Por tanto, sirven para comparar ajuste histórico, no para demostrar cuál pronosticará mejor el futuro.


18. Un cuidado importante: regresión y series de tiempo

En una regresión convencional solemos asumir que los errores son independientes.

En series de tiempo, esa condición puede fallar porque los residuos también están ordenados temporalmente.

Cowpertwait y Metcalfe (2009) advierten que, cuando los residuos presentan autocorrelación positiva, los errores estándar obtenidos mediante una regresión ordinaria pueden ser demasiado pequeños y los valores \(p\) demasiado optimistas.

Por eso, en esta sesión utilizaremos los modelos principalmente para:

  • describir la tendencia;
  • visualizar el patrón;
  • interpretar el cambio.

Una inferencia formal sobre la tendencia requiere revisar con mayor cuidado la estructura temporal de los residuos.


19. ¿Qué entendemos por sesgo?

La palabra sesgo puede utilizarse en varios sentidos. En esta sesión distinguiremos dos:

  1. sesgo del pronóstico o del modelo;
  2. sesgo producido por la forma en que se generan u observan los datos.

No debe confundirse con la asimetría (skewness) de una distribución.


20. Sesgo del pronóstico

Definimos:

\[ e_t=Y_t-\widehat{Y}_t. \]

El error medio es:

\[ ME= \frac{1}{n} \sum_{t=1}^{n} e_t. \]

Su interpretación depende de cómo definamos el error. Con nuestra convención:

\[ e_t= \text{observado}-\text{pronosticado}. \]

Entonces:

  • \(ME>0\): el modelo tiende a quedarse corto; subestima;
  • \(ME<0\): el modelo tiende a pronosticar demasiado alto; sobreestima;
  • \(ME\approx0\): no se observa un sesgo promedio importante.

20.1 Ejemplo con datos de entrenamiento y prueba

Utilizaremos los primeros 48 meses para estimar una tendencia y los últimos 12 meses para evaluarla.

entrenamiento <- datos %>%
  filter(t <= 48)

prueba <- datos %>%
  filter(t > 48)

modelo_entrenamiento <- lm(
  ventas ~ t,
  data = entrenamiento
)

prueba <- prueba %>%
  mutate(
    pronostico = predict(
      modelo_entrenamiento,
      newdata = prueba
    ),
    error = ventas - pronostico
  )

kable(
  prueba %>%
    select(
      fecha,
      ventas,
      pronostico,
      error
    ),
  digits = 2
)
fecha ventas pronostico error
2025-01-01 577 709.93 -132.93
2025-02-01 616 715.87 -99.87
2025-03-01 630 721.81 -91.81
2025-04-01 674 727.75 -53.75
2025-05-01 703 733.69 -30.69
2025-06-01 779 739.63 39.37
2025-07-01 721 745.57 -24.57
2025-08-01 761 751.51 9.49
2025-09-01 768 757.45 10.55
2025-10-01 655 763.39 -108.39
2025-11-01 799 769.33 29.67
2025-12-01 822 775.27 46.73
ME <- mean(prueba$error)
MAE <- mean(abs(prueba$error))
RMSE <- sqrt(mean(prueba$error^2))

tibble(
  ME = ME,
  MAE = MAE,
  RMSE = RMSE
) %>%
  kable(digits = 2)
ME MAE RMSE
-33.85 56.48 68.96

La magnitud y el signo del ME deben interpretarse junto con la gráfica.

ggplot(prueba, aes(x = fecha)) +
  geom_line(aes(y = ventas), linewidth = 0.9, color = "#2980b9") +
  geom_point(aes(y = ventas), size = 2.2, color = "#2980b9") +
  geom_line(
    aes(y = pronostico),
    linewidth = 1.1,
    linetype = 2,
    color = "#e67e22"
  ) +
  labs(
    title = "Evaluación fuera de muestra",
    subtitle = "Ventas observadas frente a tendencia pronosticada",
    x = "Fecha",
    y = "Unidades"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    plot.subtitle = element_text(color = "#5d6d7e"),
    axis.title = element_text(face = "bold")
  )


21. Sesgo en los datos

Un modelo puede estar perfectamente calculado y aun así producir conclusiones incorrectas si los datos observados no representan adecuadamente el fenómeno.

Ejemplos empresariales:

  • medir satisfacción únicamente entre clientes que regresan;
  • analizar tiempos de espera únicamente entre quienes completan la compra;
  • estudiar ventas solo en tiendas que permanecieron abiertas;
  • inferir demanda a partir de ventas sin considerar agotamientos de inventario;
  • comparar periodos cuando cambió el sistema de registro.

Idea clave

\[ \boxed{ \text{un buen modelo no corrige automáticamente un mal proceso de medición} } \]


22. Censuramiento

Los dos textos base utilizados en esta sesión desarrollan ampliamente tendencias, estacionalidad, descomposición, suavizamiento y modelación temporal. El censuramiento no constituye uno de sus temas introductorios centrales; se incorpora aquí porque forma parte del microcurrículo y es especialmente relevante en problemas de negocios.

El censuramiento aparece cuando no conocemos el valor exacto de una observación, pero sí conocemos información parcial sobre ella.

Por ejemplo, si una tienda tenía 500 unidades disponibles y vendió las 500, no sabemos si la demanda era:

\[ 500,\;550,\;700,\;1000,\ldots \]

Solo sabemos que:

\[ D_t\geq500. \]

La demanda está censurada por la disponibilidad de inventario.


23. Ventas observadas y demanda real

En un escenario sencillo:

\[ V_t=\min(D_t,I_t), \]

donde:

  • \(V_t\): ventas observadas;
  • \(D_t\): demanda;
  • \(I_t\): inventario disponible.

Si:

\[ D_t<I_t, \]

entonces:

\[ V_t=D_t. \]

Pero si:

\[ D_t\ge I_t, \]

entonces:

\[ V_t=I_t \]

y únicamente sabemos que la demanda fue al menos igual al inventario vendido.

Por eso:

\[ \boxed{ \text{ventas observadas} \neq \text{demanda real} } \]

cuando existen quiebres de inventario.


24. El censuramiento en Nova Market

Identifiquemos los meses en los cuales las ventas quedaron limitadas por el inventario.

datos %>%
  filter(quiebre_stock) %>%
  select(
    fecha,
    demanda_latente,
    inventario,
    ventas
  ) %>%
  kable()
fecha demanda_latente inventario ventas
2022-12-01 797 669 669
2023-12-01 828 672 672
2024-11-01 804 658 658
2024-12-01 900 667 667
2025-10-01 837 655 655
2025-11-01 903 799 799
2025-12-01 1024 822 822

En la práctica no observaríamos demanda_latente; la incluimos porque la simulación nos permite conocerla.

24.1 Comparación visual

ggplot(datos, aes(x = fecha)) +
  geom_line(
    aes(y = demanda_latente),
    linewidth = 1,
    linetype = 2,
    color = "#8e44ad"
  ) +
  geom_line(
    aes(y = ventas),
    linewidth = 0.95,
    color = "#27ae60"
  ) +
  geom_point(
    data = datos %>% filter(quiebre_stock),
    aes(y = ventas),
    size = 3,
    color = "#e74c3c"
  ) +
  labs(
    title = "Demanda latente y ventas observadas",
    subtitle = "Los puntos corresponden a meses con quiebre de inventario",
    x = "Fecha",
    y = "Unidades"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", color = "#1f3c88"),
    plot.subtitle = element_text(color = "#5d6d7e"),
    axis.title = element_text(face = "bold")
  )


25. ¿Qué problema produce ignorar el censuramiento?

Supongamos que la empresa ajusta una tendencia únicamente con las ventas observadas.

Comparemos la tendencia estimada para:

  1. ventas observadas;
  2. demanda real simulada.
modelo_ventas <- lm(
  ventas ~ t,
  data = datos
)

modelo_demanda <- lm(
  demanda_latente ~ t,
  data = datos
)

comparacion_pendientes <- tibble(
  Serie = c(
    "Ventas observadas",
    "Demanda latente"
  ),
  Pendiente = c(
    coef(modelo_ventas)["t"],
    coef(modelo_demanda)["t"]
  )
)

kable(
  comparacion_pendientes,
  digits = 3
)
Serie Pendiente
Ventas observadas 5.493
Demanda latente 6.629

Si la pendiente de las ventas es menor que la pendiente de la demanda, el negocio podría concluir que está creciendo más lentamente de lo que realmente crece su mercado.

Este es un problema serio para decisiones de:

  • inventario;
  • compras;
  • capacidad;
  • contratación;
  • almacenamiento;
  • logística;
  • presupuesto.

26. Censuramiento, dato faltante y truncamiento

No son exactamente lo mismo.

Situación ¿Qué sabemos? Ejemplo
Dato faltante No observamos el valor El sistema no registró las ventas del día
Censuramiento Conocemos un límite o información parcial Se vendió todo el inventario: demanda \(\geq\) stock
Truncamiento Ciertos casos ni siquiera aparecen en la base Solo se almacenan pedidos superiores a cierto monto

Esta distinción afecta la forma en que debe analizarse la información.


27. Estacionalidad y censuramiento: una combinación peligrosa

Imagine que los agotamientos de inventario ocurren principalmente en diciembre.

Entonces justamente los meses de mayor demanda quedan limitados por el stock disponible.

Como resultado, al analizar ventas, podríamos:

  • subestimar la estacionalidad;
  • subestimar el crecimiento;
  • subestimar la demanda máxima;
  • planear nuevamente un inventario insuficiente.

Se produce un círculo vicioso:

\[ \text{inventario bajo} \rightarrow \text{ventas censuradas} \rightarrow \text{demanda subestimada} \rightarrow \text{inventario bajo}. \]

Ese es un excelente ejemplo de por qué el análisis estadístico necesita comprender cómo se generan los datos.


28. ¿Qué modelo de tendencia elegir?

No existe una regla universal basada en un único número.

Una decisión razonable debe combinar:

\[ \boxed{ \text{gráfico} + \text{error} + \text{residuos} + \text{sentido del negocio} } \]

Preguntas útiles:

  1. ¿El patrón visual parece lineal?
  2. ¿La tasa de crecimiento parece constante?
  3. ¿El crecimiento parece porcentual?
  4. ¿El modelo produce valores razonables?
  5. ¿Qué ocurre al extrapolar?
  6. ¿Existen cambios estructurales?
  7. ¿Hay promociones o intervenciones?
  8. ¿Existen datos censurados?
  9. ¿La estacionalidad fue considerada?
  10. ¿El comportamiento reciente es diferente del histórico?

29. No confundir ajuste con explicación

Suponga que una tendencia cuadrática presenta un \(R^2\) muy alto.

Eso no significa que:

  • el tiempo “cause” las ventas;
  • el modelo describa correctamente el mecanismo económico;
  • el patrón continuará para siempre;
  • el modelo pronosticará mejor.

El tiempo funciona aquí como una variable que resume una evolución, no necesariamente como una causa.


30. Intervenciones y cambios en el negocio

Cryer y Chan (2008) muestran que una serie puede cambiar debido a una intervención que modifica su nivel o su tendencia.

En negocios podrían ser:

  • lanzamiento de una campaña;
  • entrada de un competidor;
  • cambio de regulación;
  • apertura de una nueva sede;
  • modificación del precio;
  • huelga;
  • cierre de una planta;
  • cambio tecnológico.

Una tendencia estimada sobre todo el periodo puede ocultar esos cambios.

Si una empresa duplicó su número de tiendas en julio de 2024, ¿tendría sentido interpretar toda la serie como si nada hubiera cambiado?


31. Una ruta de análisis para series de tiempo en negocios

Ante una nueva serie, una secuencia inicial razonable es:

Paso 1. Comprender la variable

Pregunte:

  • ¿qué se está midiendo?
  • ¿en qué unidad?
  • ¿con qué frecuencia?
  • ¿durante qué periodo?
  • ¿cómo se registra?

Paso 2. Verificar la calidad de los datos

Revise:

  • fechas repetidas;
  • periodos faltantes;
  • valores imposibles;
  • cambios de definición;
  • valores atípicos;
  • censuramiento.

Paso 3. Graficar la serie

Nunca empiece el análisis temporal únicamente con una tabla.

Paso 4. Identificar patrones

Busque:

  • tendencia;
  • estacionalidad;
  • ciclos;
  • irregularidad;
  • intervenciones.

Paso 5. Suavizar cuando sea útil

Use medias móviles para facilitar la observación de la tendencia.

Paso 6. Considerar una descomposición

Pregunte si el comportamiento parece aditivo o multiplicativo.

Paso 7. Ajustar modelos simples de tendencia

Compare:

  • lineal;
  • cuadrático;
  • exponencial.

Paso 8. Evaluar errores

No seleccione modelos únicamente por \(R^2\).

Paso 9. Revisar sesgos y limitaciones

Pregunte qué parte del fenómeno realmente observa la base de datos.

Paso 10. Interpretar para decidir

El análisis debe terminar en una conclusión de negocio, no en una salida de R.


32. Ejemplo de interpretación ejecutiva

Una mala conclusión sería:

“El modelo cuadrático tiene un RMSE de 49.6.”

Una conclusión útil sería:

“Las ventas muestran una trayectoria creciente y un patrón estacional marcado al final del año. Sin embargo, varios meses de alta demanda presentan agotamiento de inventario, por lo que las ventas observadas probablemente subestiman la demanda real. En consecuencia, la tendencia y los índices estacionales calculados con ventas deben interpretarse con cautela antes de utilizarse para decisiones de abastecimiento.”

La diferencia está en pasar de:

\[ \text{resultado estadístico} \]

a:

\[ \text{interpretación} \rightarrow \text{decisión}. \]


33. Actividad breve durante la clase

Con base en los resultados obtenidos para Nova Market, responda:

  1. ¿Existe evidencia gráfica de una tendencia?
  2. ¿Qué meses parecen presentar mayor actividad?
  3. ¿La estacionalidad parece más cercana a un comportamiento aditivo o multiplicativo?
  4. ¿Qué información elimina una media móvil y qué información conserva?
  5. ¿Cómo interpreta la pendiente del modelo lineal?
  6. ¿Qué diferencia conceptual existe entre el modelo lineal y el exponencial?
  7. ¿Cuál de los modelos presenta menor MAE histórico?
  8. ¿Eso demuestra que será el mejor modelo de pronóstico? Justifique.
  9. ¿Qué meses presentan censuramiento por inventario?
  10. ¿Qué consecuencias empresariales tendría confundir ventas con demanda?

34. Conceptos que deben quedar claros

Al terminar la sesión, el estudiante debería poder explicar con sus propias palabras:

Serie de tiempo: observaciones de una variable ordenadas temporalmente.

Frecuencia: periodicidad con la cual se registran las observaciones.

Tendencia: evolución general de largo plazo.

Estacionalidad: patrón que se repite en intervalos regulares.

Ciclo: movimiento recurrente sin periodicidad fija.

Componente irregular: variación no explicada por los patrones sistemáticos considerados.

Suavizamiento: reducción de fluctuaciones de corto plazo para facilitar la observación de patrones.

Descomposición: separación conceptual de la serie en componentes.

Ajuste estacional: eliminación o control del efecto estacional para estudiar otros movimientos.

Modelo de tendencia: función utilizada para representar la evolución sistemática de una serie.

Sesgo: desviación sistemática producida por el modelo o por el proceso de observación.

Censuramiento: situación en la que no observamos el valor exacto, pero conocemos un límite o información parcial.


35. Ideas finales

Una serie de tiempo no es simplemente una columna de números con fechas.

Contiene información sobre:

\[ \text{historia} + \text{patrones} + \text{cambios} + \text{incertidumbre}. \]

En negocios, una lectura adecuada de esos elementos permite mejorar decisiones de:

  • abastecimiento;
  • inventarios;
  • ventas;
  • precios;
  • capacidad;
  • presupuesto;
  • logística;
  • mercadeo.

Pero hay una advertencia fundamental:

\[ \boxed{ \text{el modelo solo puede aprender de lo que los datos permiten observar} } \]

Si la demanda está censurada, si el sistema cambió, si existen periodos faltantes o si el proceso de medición está sesgado, el análisis debe reconocerlo explícitamente.


36. Referencias base

Cowpertwait, P. S. P., & Metcalfe, A. V. (2009). Introductory Time Series with R. Springer. DOI: 10.1007/978-0-387-88698-5.

Cryer, J. D., & Chan, K.-S. (2008). Time Series Analysis: With Applications in R (2nd ed.). Springer.


37. Nota bibliográfica sobre el alcance

La estructura conceptual de esta guía sobre:

  • definición de serie de tiempo;
  • intervalo temporal;
  • dependencia entre observaciones;
  • tendencia;
  • estacionalidad;
  • ciclos;
  • descomposición aditiva y multiplicativa;
  • medias móviles;
  • regresión para tendencias;
  • cuidado con la extrapolación;
  • residuos y dependencia temporal;

se apoya principalmente en Cowpertwait y Metcalfe (2009) y se complementa con el tratamiento de tendencias, pronóstico e intervenciones de Cryer y Chan (2008).

Los apartados sobre sesgo de los datos y censuramiento de demanda por inventario son una extensión didáctica para responder a los contenidos del curso y llevar los conceptos al contexto empresarial.