Proyecto de Series de Tiempo

Estimación de Revenue en Aerolíneas

Juan Sebastian Ramirez Ayala

Profesor: Wilmer Pineda Rios

Escuela Colombiana de Ingeniería Julio Garavito

2026-04-12

Guía de trabajo

Este documento está diseñado para desarrollar paso a paso un proyecto de series de tiempo en R usando el conjunto de datos de aerolíneas.

Contexto del problema

Se cuenta con un conjunto de datos que incluye las variables:

  • UNIQUE_CARRIER
  • YEAR
  • MONTH
  • DAY
  • REVENUE
  • PROFIT
  • NET_EARNINGS
  • EPS_BASIC
  • EPS_DILUTED

Para este proyecto, las variables de interés principal son:

  • UNIQUE_CARRIER
  • YEAR
  • MONTH
  • DAY
  • REVENUE

Significado de las variables de interés

  • UNIQUE_CARRIER: identificador único de la aerolínea. Permite distinguir qué empresa generó el registro.
  • YEAR: año correspondiente al registro.
  • MONTH: mes del registro.
  • DAY: día del registro.
  • REVENUE: ingreso o facturación reportada por la aerolínea en la fecha correspondiente.

Unidad de análisis

areolineas %>% 
  group_by(MONTH) %>% 
  summarise(conteo = n())


areolineas %>%
  count(YEAR, MONTH) %>%
  arrange(YEAR, MONTH)

unique(areolineas$DAY)

El análisis exploratorio permitió identificar que los datos no corresponden a una frecuencia diaria, sino a observaciones registradas en los meses de marzo, junio, septiembre y diciembre de cada año. Asimismo, la variable DAY toma valores asociados al último día de cada trimestre, lo que sugiere que cada observación representa un valor agregado trimestral. En consecuencia, la unidad de análisis se define como el ingreso por aerolínea en cada trimestre, configurando así un conjunto de series temporales de tipo panel con frecuencia trimestral (4 observaciones por año).

Objetivo general

Estimar la variable REVENUE usando modelos de series de tiempo, considerando un enfoque univariado.

Modelos a estudiar

  • MA
  • AR
  • ARMA
  • ARIMA
  • SARIMA

Estructura del trabajo

  1. Análisis exploratorio
    • Descripción general del conjunto de datos
    • Identificación de la frecuencia temporal
    • Revisión de la calidad temporal de la base
    • Análisis descriptivo de la variable REVENUE
    • Selección de la aerolínea para el análisis univariado
  2. Análisis univariado de la serie seleccionada
    • Construcción de la serie temporal
    • Descomposición en tendencia, estacionalidad y componente aleatoria
    • Evaluación de estacionariedad y raíces unitarias
    • Análisis de la ACF y la PACF
    • Ajuste y comparación de modelos MA, AR, ARMA, ARIMA y SARIMA
    • Diagnóstico de residuos
    • Generación de pronósticos
  3. Conclusiones
    • Principales hallazgos del análisis exploratorio
    • Justificación del modelo final seleccionado
    • Interpretación general de los pronósticos obtenidos
    • Limitaciones del estudio y posibles extensiones

Sección 1. Exploratorio simple

1.1 Objetivo del paso

Preguntas a revisar:

  • ¿La serie está realmente ordenada en el tiempo?
  • ¿La frecuencia es diaria y está completa?
  • ¿Hay fechas faltantes?
  • ¿Hay varias aerolíneas con longitudes distintas?
  • ¿REVENUE presenta tendencia, estacionalidad o valores atípicos?
  • ¿Conviene trabajar con una sola aerolínea o con varias?

1.2 Qué se busca en este análisis

Para este dataset, el análisis exploratorio debe cubrir cinco bloques:

A. Estructura del dataset

dim(areolineas)
[1] 483   9

El conjunto de datos está compuesto por 483 observaciones, las cuales corresponden a registros del ingresos trimestral de nueve aerolíneas.

Tipos de variables

Este conjunto de datos contiene nueve variables:

Variable Tipo
UNIQUE_CARRIER character
YEAR integer
MONTH integer
DAY integer
REVENUE numeric
PROFIT numeric
NET_EARNINGS numeric
EPS_BASIC numeric
EPS_DILUTED numeric
  • character: 1 variable
  • integer: 3 variables
  • numeric: 5 variables

Presencia de valores faltantes

diagnose(areolineas)

Desde el punto de vista técnico, no se identificaron valores faltantes explícitos (NA) en las variables del conjunto de datos. Es decir, las variables observadas no presentan ausencias directas en sus registros.

Sin embargo, a partir de la revisión por aerolínea, se detectó un fenómeno: algunas aerolíneas no tienen información para ciertos trimestres. Esto indica la existencia de faltantes estructurales en el tiempo, más que valores faltantes tradicionales dentro de la base.

Series Completas

Las siguientes aerolíneas presentan series completas, con 56 observaciones:

  • AS
  • DL
  • HA
  • WN
Series incompletas

Se identificaron aerolíneas con distinto nivel de incompletitud:

  • AA, B6 y G4: presentan faltantes ligeros (55).
  • UA: presenta faltantes moderados (54).
  • NK: presenta una serie más corta, con información disponible únicamente desde 2010 (40).

B. Construcción de la fecha

Las variables temporales vienen separadas en YEAR, MONTH y DAY, por lo que es necesario crear una variable DATE.

# Variable Date
areolineas <- areolineas %>%
  mutate(
    DATE = make_date(YEAR, MONTH, DAY)
  )

# Variable Trimestral
areolineas <- areolineas %>%
  mutate(
    QUARTER = case_when(
      MONTH == 3 ~ 1,
      MONTH == 6 ~ 2,
      MONTH == 9 ~ 3,
      MONTH == 12 ~ 4
    )
  )

C. Calidad temporal

# Ferificar que las fechas esten bien formateadas
# Ver estructura
str(areolineas$DATE)

# Resumen
summary(areolineas$DATE)

# Contar NA
sum(is.na(areolineas$DATE))

# Verificar duplicados
duplicados <- areolineas %>%
  count(UNIQUE_CARRIER, DATE) %>%
  filter(n > 1)

nrow(duplicados)

Se verificó la correcta construcción de la variable temporal DATE, confirmando que presenta formato adecuado y ausencia de valores faltantes. El rango temporal de la serie abarca desde el primer trimestre de 2006 hasta el cuarto trimestre de 2019, lo que garantiza una cobertura completa del periodo de estudio.

Asimismo, se comprobó la unicidad de las observaciones por aerolínea y periodo temporal, evidenciando la ausencia de duplicados.

D. Comportamiento general de REVENUE

La variable REVENUE presenta una distribución asimétrica positiva, con una concentración de valores en rangos bajos y una cola larga hacia valores elevados. Adicionalmente, se observa un comportamiento multimodal, lo cual sugiere la existencia de distintos grupos estructurales asociados a las diferentes aerolíneas.

El análisis de las estadísticas descriptivas de la variable REVENUE revela una distribución altamente asimétrica, con una media significativamente superior a la mediana, lo que indica la presencia de valores extremos en los niveles superiores de ingresos. Asimismo, el coeficiente de variación cercano a la unidad evidencia una elevada dispersión relativa.

A nivel desagregado, se observa una clara heterogeneidad entre aerolíneas, identificándose distintos grupos según su nivel de ingresos. Las aerolíneas de mayor tamaño presentan mayores valores absolutos de ingresos y menor variabilidad relativa, mientras que las aerolíneas más pequeñas exhiben mayor volatilidad.

Estos resultados sugieren que las series no son directamente comparables en términos de escala.

Sección 2. Análisis univariado

2.1 Objetivo

Seleccionar una sola aerolínea y desarrollar sobre ella el proceso formal de análisis de series de tiempo, desde la visualización y revisión de estacionariedad hasta el ajuste y comparación de modelos.

2.2 Selección de la aerolínea

carrier_sel <- "DL"

df_DL <- areolineas %>%
  filter(UNIQUE_CARRIER == carrier_sel) %>%
  arrange(DATE)
serie_DL = 
  ts(
    df_DL$REVENUE, 
    start = c(2006, 1), # año y trimestre de inicio
    frequency = 4 # Van a pasar 4 periodos antes del primer ciclo
  )
autoplot(serie_DL) +
  labs(title = "Serie temporal de DL")

Descomposición de la serie

x <- decompose(serie_DL)
plot(x)

La serie temporal presenta una tendencia creciente a lo largo del tiempo, lo que indica un comportamiento no estacionario en media. Esta tendencia no es estrictamente lineal, observándose periodos de desaceleración seguidos de nuevas fases de crecimiento.

La componente estacional evidencia un patrón claramente definido y recurrente con periodicidad trimestral. En particular, se observa que el segundo trimestre presenta sistemáticamente los valores más altos de ingresos, mientras que el cuarto trimestre tiende a registrar los valores más bajos. La amplitud de la estacionalidad se mantiene relativamente constante en el tiempo, lo que sugiere una estructura estacional estable.

Por su parte, la componente aleatoria muestra fluctuaciones alrededor de cero sin un patrón definido, lo que indica que gran parte de la estructura de la serie es capturada por la tendencia y la estacionalidad. No obstante, se identifican algunos periodos con desviaciones importantes respecto al comportamiento esperado, como alrededor del año 2008, donde los ingresos fueron inferiores a lo proyectado por los componentes estructurales.

En conjunto, estos resultados evidencian que la serie presenta tanto tendencia como estacionalidad, lo cual implica que no es estacionaria y que requerirá transformaciones adecuadas para su modelación.


Sección 3. Estacionariedad y raíces unitarias

3.1 Objetivo

Determinar si la serie seleccionada es estacionaria en media y varianza, o si requiere transformaciones y diferenciación antes de ajustar modelos AR, MA, ARMA, ARIMA o SARIMA.

3.2 Marco conceptual breve

Una serie estacionaria mantiene propiedades estadísticas relativamente constantes a lo largo del tiempo, especialmente su media, varianza y estructura de autocorrelación.

Una raíz unitaria suele indicar no estacionariedad. Por eso se aplican pruebas como ADF.

Raiz unitaria

adf.test(serie_DL)

    Augmented Dickey-Fuller Test

data:  serie_DL
Dickey-Fuller = -1.2968, Lag order = 3, p-value = 0.8581
alternative hypothesis: stationary

Se aplicó la prueba de Dickey-Fuller aumentada (ADF) con el objetivo de evaluar la estacionariedad de la serie. El valor del estadístico fue de -1.2968 con un p-valor de 0.8581, lo cual impide rechazar la hipótesis nula de presencia de raíz unitaria. En consecuencia, la serie no es estacinaria, por lo que estaríamos pensando en implementar alguna transformación.

lambda_opt <- BoxCox.lambda(serie_DL)

serie_DL_bc <- BoxCox(serie_DL, lambda_opt)
diff_serie <- diff(serie_DL_bc, differences = 1)
adf.test(diff_serie)

    Augmented Dickey-Fuller Test

data:  diff_serie
Dickey-Fuller = -3.4948, Lag order = 3, p-value = 0.05019
alternative hypothesis: stationary

Tras aplicar una transformación Box-Cox y una diferenciación de primer orden, se observa una reducción significativa en la no estacionariedad de la serie. Sin embargo, la prueba ADF arroja un p-valor de 0.05019, lo que indica que no se puede rechazar de manera concluyente la hipótesis nula de presencia de raíz unitaria al nivel de significancia del 5%.

Este resultado sugiere que, aunque la tendencia ha sido prácticamente eliminada, aún persisten componentes de dependencia temporal, probablemente asociados a la estructura estacional de la serie.

Dado que la serie presenta una periodicidad trimestral (s = 4), es razonable suponer que la no estacionariedad restante se debe a un patrón estacional no removido. En consecuencia, se justifica la aplicación de una diferenciación estacional adicional.

A partir de este análisis, se plantea como hipótesis que un modelo adecuado para describir la dinámica de la serie es un modelo SARIMA, el cual permite capturar simultáneamente la estructura autorregresiva, de medias móviles y la componente estacional.


Sección 4. ACF y PACF

4.1 Objetivo

Usar la función de autocorrelación y la función de autocorrelación parcial para entender la dependencia temporal de la serie y orientar la selección inicial de modelos.

4.2 Código sugerido

diff_final <- diff(diff_serie, lag = 4)


par(mfrow = c(1, 2))
acf(diff_final, main = paste("ACF -", carrier_sel))
pacf(diff_final, main = paste("PACF -", carrier_sel))

par(mfrow = c(1, 1))

El análisis de la función de autocorrelación (ACF) muestra un corte claro en el primer rezago, lo que indica una dependencia temporal de corto plazo característica de un proceso de medias móviles de orden uno. Por su parte, la función de autocorrelación parcial (PACF) no presenta un patrón de corte definido, evidenciando la ausencia de una estructura autorregresiva significativa.

En conjunto, estos resultados sugieren un modelo MA(1) para la componente no estacional. Adicionalmente, la presencia de dependencia en rezagos múltiplos de cuatro indica la existencia de una componente estacional, consistente con la frecuencia trimestral de la serie. En consecuencia, se propone como modelo inicial un \[SARIMA(0,1,1)(0,1,1)_4\].

Sección 5. Ajuste de modelos MA, AR, ARMA, ARIMA y SARIMA

5.1 Objetivo

Ajustar distintos modelos clásicos de series de tiempo y compararlos para identificar cuál ofrece una mejor representación y capacidad predictiva para REVENUE.

5.2 Código base

# Ejemplos iniciales, ajustar órdenes según análisis previo
modelo_ar   <- arima(diff_final, order = c(1, 0, 0), include.mean = FALSE)
modelo_ma   <- arima(diff_final, order = c(0, 0, 1), include.mean = FALSE)
modelo_arma <- arima(diff_final, order = c(1, 0, 1), include.mean = FALSE)


modelo_arima <- Arima(
  serie_DL_bc,
  order = c(1, 1, 1),
  include.constant = FALSE
)


modelo_sarima <- Arima(
  serie_DL_bc,
  order = c(0, 1, 1),
  seasonal = list(order = c(0, 1, 1), period = 4),
  include.constant = FALSE
)
# ------------------------------------------------
# 6. Comparación
# ------------------------------------------------
comparacion <- data.frame(
  Modelo = c("AR(1)", "MA(1)", "ARMA(1,1)", "ARIMA(1,1,1)", "SARIMA(0,1,1)(0,1,1)[4]"),
  AIC = round(c(
    AIC(modelo_ar),
    AIC(modelo_ma),
    AIC(modelo_arma),
    AIC(modelo_arima),
    AIC(modelo_sarima)
  ), 2),
  BIC = round(c(
    BIC(modelo_ar),
    BIC(modelo_ma),
    BIC(modelo_arma),
    BIC(modelo_arima),
    BIC(modelo_sarima)
  ), 2)
)

DT::datatable(
  comparacion[order(comparacion$AIC), ],
  options = list(
    pageLength = 35,
    scrollY = "400px",
    scrollX = T,
    scrollCollapse = TRUE,
    autoWidth = FALSE,         # Desactiva el ajuste automático de ancho
    scrollX = FALSE,            # Desactiva el scroll horizontal
    columnDefs = list(
      list(width = '400px', targets = "_all")
    )
  ),
  caption = "Estadísticas Descriptivas por Areolinea"
) %>% 
  DT::formatStyle(columns = colnames(comparacion[order(comparacion$AIC), ]), `white-space` = "normal")

Los resultados muestran que el modelo SARIMA(0,1,1)(0,1,1)_4 presenta los menores valores de AIC y BIC, lo que indica el mejor equilibrio entre calidad de ajuste y parsimonia. La diferencia respecto a los demás modelos es considerable, evidenciando que la inclusión de la componente estacional mejora significativamente la capacidad explicativa del modelo. En contraste, los modelos AR, MA y ARMA, al no considerar la estructura estacional, presentan un ajuste inferior. Asimismo, el modelo ARIMA(1,1,1), aunque incorpora diferenciación regular, no captura la estacionalidad, resultando en un desempeño significativamente peor.

A partir de la búsqueda en rejilla de modelos SARIMA, se identificó que el modelo SARIMA(2,1,0)(0,1,1)_4 presenta el menor valor de AIC y MSE, lo que indica un mejor ajuste y capacidad predictiva en comparación con los demás modelos evaluados. Aunque el criterio BIC favorece un modelo más parsimonioso, la diferencia en términos de ajuste y error sugiere que el modelo SARIMA(2,1,0)(0,1,1)_4 captura de manera más adecuada la dinámica de la serie. En consecuencia, este modelo se selecciona como el modelo final.

modelo_final <- Arima(
  serie_DL,
  order = c(2, 1, 0),
  seasonal = list(order = c(0, 1, 1), period = 4),
  lambda = lambda_opt,
  biasadj = TRUE,
  include.constant = FALSE
)

Se utilizó la opción biasadj = TRUE para corregir el sesgo introducido por la transformación Box-Cox al retornar a la escala original. Asimismo, se estableció include.constant = FALSE, dado que el modelo incorpora diferenciación, evitando así la inclusión de un término de tendencia adicional que podría sesgar la interpretación de la dinámica de la serie.

Adicionalmente, se incorporó el parámetro lambda = λ_opt, correspondiente a la transformación Box-Cox óptima, con el objetivo de estabilizar la varianza de la serie y aproximar su distribución a la normalidad, mejorando así las propiedades estadísticas del modelo y la calidad de los pronósticos.


Sección 6. Diagnóstico de residuos

6.1 Objetivo

Verificar si los residuos del modelo seleccionado se comportan como ruido blanco.

checkresiduals(modelo_final)


    Ljung-Box test

data:  Residuals from ARIMA(2,1,0)(0,1,1)[4]
Q* = 0.74674, df = 5, p-value = 0.9803

Model df: 3.   Total lags used: 8

\[ \begin{cases} H_0: \text{No hay aouto correlación (residuos independientes)} \\ H_1: \text{Hay autocorrelación} \end{cases} \]

El análisis de los residuos del modelo \(SARIMA(2,1,0)(0,1,1)_4\) indica que estos se comportan como ruido blanco. La prueba de Ljung-Box no rechaza la hipótesis nula de independencia (p-value = 0.9803), lo que sugiere ausencia de autocorrelación residual. Asimismo, la función de autocorrelación de los residuos no presenta valores significativos, y el gráfico temporal no evidencia patrones sistemáticos. Finalmente, la distribución de los residuos es aproximadamente normal. En conjunto, estos resultados validan la adecuación del modelo seleccionado.

Box.test(residuals(modelo_final), lag = 20, type = "Ljung-Box")

    Box-Ljung test

data:  residuals(modelo_final)
X-squared = 6.3144, df = 20, p-value = 0.9984

La prueba de Ljung-Box aplicada a los residuos del modelo \(SARIMA(2,1,0)(0,1,1)_4\) no rechaza la hipótesis nula de independencia (p-value = 0.9984), lo que indica ausencia de autocorrelación residual incluso al considerar hasta 20 rezagos. Este resultado confirma que el modelo captura adecuadamente la estructura temporal de la serie, dejando residuos consistentes con un proceso de ruido blanco.

Sección 7. Pronóstico

7.1 Objetivo

Generar predicciones de REVENUE con el modelo seleccionado.

Los resultados del pronóstico en la escala original indican una tendencia creciente en los ingresos a lo largo del horizonte de predicción, manteniendo un patrón estacional consistente con el comportamiento histórico de la serie. En particular, se observa que los ingresos alcanzan sus valores más altos durante el segundo y tercer trimestre de cada año, mientras que los valores más bajos se presentan en el primer y cuarto trimestre. Asimismo, los intervalos de confianza se amplían a medida que aumenta el horizonte de pronóstico, reflejando el incremento en la incertidumbre asociado a predicciones de largo plazo. En conjunto, el modelo proporciona estimaciones coherentes y consistentes con la dinámica observada en los datos históricos.

Conclusiones

A partir del análisis exploratorio se concluye que el conjunto de datos corresponde a un sistema de series de tiempo de tipo panel, conformado por nueve aerolíneas observadas con frecuencia trimestral entre 2006 y 2019. La estructura temporal de la base permitió establecer que cada observación representa el ingreso trimestral de una aerolínea en un periodo específico. Asimismo, aunque no se identificaron valores faltantes explícitos (NA), sí se evidenciaron faltantes estructurales en algunas aerolíneas, lo que hizo necesario priorizar series completas para el análisis univariado.

El estudio descriptivo de la variable REVENUE mostró una distribución asimétrica positiva, con alta dispersión y una marcada heterogeneidad entre aerolíneas. Esto indicó que las series no eran directamente comparables en escala y justificó la selección de una sola aerolínea para desarrollar el modelado univariado de forma más rigurosa. En este caso, la aerolínea DL resultó adecuada por presentar una serie completa.

La descomposición de la serie temporal de DL permitió identificar dos componentes estructurales relevantes: una tendencia creciente de largo plazo y una estacionalidad trimestral. En particular, se observó que los ingresos presentan un patrón recurrente a lo largo de los trimestres, lo que confirmó que la serie original no era estacionaria y que requería transformaciones previas antes del ajuste de modelos.

La prueba de Dickey-Fuller aumentada corroboró formalmente la no estacionariedad de la serie original, mientras que la transformación Box-Cox y la diferenciación regular redujeron de manera importante este problema. Sin embargo, la persistencia de dependencia estacional indicó la necesidad de incorporar una diferenciación estacional adicional. Este resultado fue consistente con el comportamiento observado en la ACF y la PACF, las cuales sugirieron una estructura compatible con un modelo de tipo SARIMA.

En la comparación de modelos, se encontró que la inclusión de la componente estacional mejora sustancialmente el ajuste respecto a modelos no estacionales como AR, MA, ARMA y ARIMA. En particular, el modelo SARIMA(2,1,0)(0,1,1)_4 fue seleccionado como modelo final al presentar el mejor desempeño global según los criterios de información y el error cuadrático medio. Esto evidencia que la dinámica del REVENUE no puede describirse adecuadamente sin considerar de forma explícita la estructura estacional trimestral.

El diagnóstico de residuos mostró que el modelo final captura adecuadamente la dependencia temporal de la serie. Tanto la inspección gráfica como la prueba de Ljung-Box indicaron que los residuos pueden considerarse consistentes con un proceso de ruido blanco, lo que valida la especificación del modelo ajustado. En consecuencia, el modelo seleccionado no solo presenta buen ajuste, sino también consistencia estadística en términos de supuestos residuales.

Finalmente, los pronósticos obtenidos sugieren una trayectoria creciente de los ingresos, conservando el patrón estacional histórico de la serie. Los valores proyectados muestran máximos recurrentes en los trimestres intermedios y menores niveles en los trimestres inicial y final, mientras que los intervalos de confianza aumentan con el horizonte de predicción, reflejando la incertidumbre inherente al proceso de pronóstico. En conjunto, los resultados permiten concluir que el modelo SARIMA(2,1,0)(0,1,1)_4 constituye una herramienta adecuada para describir y proyectar el comportamiento trimestral del ingreso de la aerolínea analizada.