Contexto del sector y de la empresa

El análisis se enfoca en el sector turismo, particularmente en la actividad hotelera de Cali, debido a su impacto en la dinámica económica y de servicios de la ciudad. De acuerdo con la Secretaría de Turismo de Cali, durante 2024 la ciudad recibió aproximadamente 3,03 millones de visitantes, superando los 2,96 millones registrados en 2023. Además, la ocupación hotelera promedio regional pasó de 40,07 % en 2023 a 40,94 % en 2024, lo que evidencia la relevancia de estudiar la evolución de la demanda de alojamiento en la ciudad. La actividad turística también presenta sensibilidad frente a eventos y temporadas específicas. Por ejemplo, durante la Feria de Cali 2024, la ocupación hotelera alcanzó un promedio de 80 %, mientras que durante la Maratón de Cali 2025 llegó al 59 %, 22 puntos porcentuales por encima del mismo período de 2024. Lo que evidencia que existen eventos que impactan la demanda de alojamiento y, por tanto, hacen relevante analizar los patrones estacionales y las variaciones mensuales del sector. A nivel nacional, el turismo también representa una actividad económica significativa. El DANE reporta que la participación del valor agregado turístico en Colombia pasó de 2,3 % en 2024 a 2,4 % en 2025, mientras que el gasto del turismo receptor aumentó de $50,5 billones a $54,7 billones en el mismo período. Además, el alojamiento para visitantes representó $7,6 billones del gasto turístico receptor en 2025. Como empresa de referencia se seleccionó el Hotel InterContinental Cali, establecimiento orientado tanto al turismo, donde su actividad está directamente relacionada con la demanda de alojamiento de la ciudad y puede verse influenciada por la dinámica económica, la confianza de los consumidores y los períodos de mayor actividad turística. # Selección y justificación de las tres variables Las variables seleccionadas son las siguientes:

OCUP_HOTEL_CALI: la ocupación hotelera en cali, es una variable que se relaciona directamente con la actividad turística de la ciudad. Además, permite estimar el comportamiento de la demanda de alojamiento. ICC_CALI: se selecciona la variable de Índice de Confianza del Consumidor en Cali, ya que permite incorporar la percepción y las expectativas de los consumidores en relación con la situación económica de la ciudad. ISE: se selecciona la variable de Indicador de Seguimiento a la Economía, ya que, permite observar la evolución mensual de la actividad económica, ampliando el contexto sobre las condiciones en las que se desarrolla la actividad empresarial. # Metodología El análisis se realizará con una base de datos mensual para el período 2012–2025, utilizando tres variables relacionadas con el contexto turístico y económico de Cali: ocupación hotelera de Cali (OCUP_HOTEL_CALI), Índice de Confianza del Consumidor de Cali (ICC_CALI) e Indicador de Seguimiento a la Economía (ISE). Primero se analizará gráficamente el comportamiento de cada serie y se realizará una descomposición STL para identificar sus componentes de tendencia, estacionalidad e irregularidad. Posteriormente, se calculará la tasa de crecimiento interanual (YoY) para identificar períodos de crecimiento o disminución y cambios relevantes en el comportamiento de las variables. Las señales obtenidas se integrarán para analizar conjuntamente la evolución del entorno económico y turístico y su posible relación con la actividad hotelera. Esta etapa permitirá identificar también patrones estacionales y períodos atípicos relevantes para el Hotel InterContinental Cali. Finalmente, se seleccionará una de las tres variables para construir un modelo ARIMA o SARIMA. Se evaluará su estacionariedad mediante la prueba ADF, se utilizarán ACF y PACF para apoyar la identificación del modelo y se complementará con procedimientos automáticos de selección. El modelo será evaluado mediante el diagnóstico de residuos, validación predictiva y métricas como MAE y RMSE. Con la información disponible hasta diciembre de 2025 se realizará un pronóstico para enero o enero–marzo de 2026, cuyos resultados serán interpretados desde una perspectiva empresarial para apoyar decisiones relacionadas con la planificación y gestión del hotel.

#Instalar/Cargar librerias necesarias para el análisis

#Cargar librerías necesarias
library(readxl)  # Para leer archivos Excel
library(tseries)  # Para pruebas de estacionariedad
library(forecast)  # Para modelado ARIMA y pronósticos
library(ggplot2)  # Para visualización de datos
library(plotly)  # Para gráficos interactivos
library(timetk)   

#Cargar base de datos

library(readxl)
data_col <- read_excel("C:/Users/danie/Downloads/Base Caso1.xlsx", 
    col_types = c("date", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric", "numeric", 
        "numeric", "numeric"))
View(data_col)

#PASO INDISPENSABLE: Declarar la (s) variable (s) como serie (s) temporal (es):

#Variable 1

# Convertir/declarar variable 1=OCUP_HOTEL_CALI en serie de tiempo mensual
variable1_ts <- ts(data_col$OCUP_HOTEL_CALI, start = c(2012, 1), frequency = 12)
variable1_ts
##            Jan       Feb       Mar       Apr       May       Jun       Jul
## 2012 40.984148 48.163945 52.751647 46.186024 51.656806 50.498865 50.687476
## 2013 38.086361 51.665945 46.410769 54.389457 56.751197 55.800285 63.027240
## 2014 44.333605 52.902421 51.557234 50.734539 53.464851 47.137093 52.576386
## 2015 44.724933 49.953606 49.744313 49.554234 54.826536 58.593627 65.146502
## 2016 49.154764 58.314705 52.380638 55.823001 54.776938 55.320560 52.846760
## 2017 45.069758 62.273459 59.861433 56.527333 52.612756 53.991888 54.144508
## 2018 46.893462 58.005900 53.450816 57.588292 52.494087 55.418636 56.674943
## 2019 48.658704 61.509657 56.973252 50.175596 57.697959 57.352878 58.098882
## 2020 49.179432 55.608367 29.654494  3.380544  4.055782  4.283978  8.207688
## 2021 20.068146 25.373495 32.348885 28.251748 18.982892 27.704024 35.673503
## 2022 40.481477 53.547676 59.027372 55.387065 59.723427 54.786626 71.830717
## 2023 52.373911 54.886085 57.563905 54.693217 55.658694 54.134706 57.715428
## 2024 42.610000 53.480000 52.550000 51.640000 49.010000 49.170000 49.680000
## 2025 45.360000 49.920000 47.450000 48.010000 51.820000 55.480000 61.000000
##            Aug       Sep       Oct       Nov       Dec
## 2012 52.192862 57.394377 60.205655 58.180522 48.398649
## 2013 59.284782 55.818442 60.448391 58.622399 54.725298
## 2014 56.396331 54.141024 59.202058 59.872495 52.288622
## 2015 59.362884 67.055408 66.936527 67.067612 58.769211
## 2016 59.828018 70.739118 59.643952 67.395772 53.674790
## 2017 60.167547 54.016639 62.693815 62.530258 55.059444
## 2018 55.827297 61.863534 58.866459 62.879937 56.430991
## 2019 61.179771 61.151650 61.702467 62.644918 56.036853
## 2020  6.784319 13.733728 22.558021 30.792839 28.038383
## 2021 45.312803 49.834545 51.910932 65.583885 60.928307
## 2022 69.124634 66.829581 65.504159 66.671055 60.354868
## 2023 58.952883 55.987835 55.804281 67.270734 58.711385
## 2024 56.550000 54.800000 65.222412 61.291183 55.568770
## 2025 60.630000 54.250000 65.940000 60.330000 53.330000

#Variable 2

# Convertir/declarar variable 2=ICC_CALI en serie de tiempo mensual
variable2_ts <- ts(data_col$ICC_CALI, start = c(2012, 1), frequency = 12)
variable2_ts
##              Jan         Feb         Mar         Apr         May         Jun
## 2012  20.6494840  16.2209905  21.3682112  35.5075962  27.9512868  27.9461850
## 2013  21.6488549  12.6051387  10.9246626  26.3203653  37.4247603  32.1016607
## 2014  37.5491345  25.1249248  27.8778879  24.3306811  29.9374184  24.1863057
## 2015  23.4396497  19.0527883  17.4540529  16.6278564  26.3754264  17.2902619
## 2016 -20.5355105 -14.0463552 -11.9848367  -7.4017617  -9.0844788  -0.7744048
## 2017 -20.2376785 -22.4288605 -15.1942896   0.3580611  -5.4175193   3.6233730
## 2018  -7.3220709   1.7721575   5.9073012  15.9039006  11.9351614  29.6523819
## 2019  12.4789111   2.1410693  11.4132446   6.4854477  13.4264761   6.2842548
## 2020  -0.2758694  -5.2668595 -32.1792545 -36.1000000 -32.7000000 -26.7000000
## 2021 -31.0000000  -1.0000000 -15.8000000 -30.7000000 -25.9000000 -23.1000000
## 2022 -16.4000000 -10.0000000 -11.4000000 -15.0000000 -11.1000000   0.4000000
## 2023 -19.4000000 -28.8000000 -17.5000000 -20.5000000 -10.9000000  -7.9000000
## 2024  -4.3000000  -1.2000000   3.3000000  -6.0000000 -15.0000000  -8.3000000
## 2025  -1.6000000   0.8000000   4.2000000  13.1000000   9.8000000  11.7000000
##              Jul         Aug         Sep         Oct         Nov         Dec
## 2012  21.1211352  17.8221505  20.3694680  31.4084137  24.6462489  16.5095896
## 2013  34.2366282  17.1896433  25.3983090  33.0336158  30.5394342  27.1880100
## 2014  39.8393933  30.4635782  28.1277943  24.5499730  28.8913966  27.8887641
## 2015   8.0226272   0.6022523   9.5665847   8.1973242   6.6571188  11.3052310
## 2016  -6.6543437   1.4224251   3.5591840   6.1255237   1.4056607  -3.0097092
## 2017   2.0842358  -6.5617152  -1.1387088   4.8914476  -4.7792535   4.1918854
## 2018   4.0999989   8.6367673   4.6239430   8.3193488  -9.9388206  -0.1065663
## 2019  -3.5800292 -10.3736918  -1.8878081   0.6440034  -6.8104504  -5.9788350
## 2020 -30.7000000 -11.9000000  -6.1000000 -11.1000000  -9.6000000  -9.3000000
## 2021 -18.7000000   6.6000000  -8.9000000  -8.1000000   1.8000000   1.5000000
## 2022  -8.0000000   7.8000000  -6.8000000 -20.2000000 -17.0000000  -9.4000000
## 2023 -17.1000000 -10.5000000 -13.8000000  -8.6000000  -6.9000000  -5.3000000
## 2024  -7.6000000  -7.3000000  -4.0000000  15.2000000  -9.0000000  12.6000000
## 2025  13.2000000  11.7000000   0.9000000  25.7000000  24.8000000  24.6000000

#Variable 3

# Convertir/declarar variable 3=ISE en serie de tiempo mensual
variable3_ts <- ts(data_col$ISE, start = c(2012, 1), frequency = 12)
variable3_ts
##            Jan       Feb       Mar       Apr       May       Jun       Jul
## 2012  81.68037  84.51632  87.83168  84.06845  87.93712  87.82775  88.25721
## 2013  85.15456  86.44792  88.57971  89.82525  92.49853  91.90832  94.41630
## 2014  89.11942  92.72376  95.65359  92.13539  95.55825  95.38099  97.62941
## 2015  91.80939  94.99114  98.56449  95.31551  98.91123  99.26498 102.07327
## 2016  93.44710  99.21948  99.74312  98.06612 100.70060 101.58869 100.46836
## 2017  94.79901  98.86261 102.21842  97.75056 102.06451 104.51566 104.16710
## 2018  96.28252 100.42103 103.86803 101.68526 104.31974 106.34993 107.25595
## 2019  99.80323 103.95610 107.34393 104.13618 108.71167 108.95077 111.85249
## 2020 103.18987 107.70887 100.60622  83.11103  89.76884  95.29142  99.95936
## 2021  99.70037 104.28788 111.86952 104.27038 101.68314 109.96299 113.15155
## 2022 107.67326 111.27952 119.70560 115.14803 118.72427 118.50594 119.94641
## 2023 112.30882 114.01867 121.40610 114.27288 119.03797 121.46259 120.67058
## 2024 114.16295 116.73418 118.87851 120.61068 121.59824 119.06014 124.33195
## 2025 116.39258 118.21867 124.37117 120.82200 124.56234 123.37864 130.23594
##            Aug       Sep       Oct       Nov       Dec
## 2012  87.37441  88.85174  88.73231  93.59978  98.11226
## 2013  93.28462  94.10808  94.22677  99.36308 105.23580
## 2014  97.58678  98.51913  98.41323 102.27108 109.18026
## 2015 101.27515 101.27730 100.65431 104.62138 111.24185
## 2016 104.68155 103.66200 101.98883 107.84345 114.85774
## 2017 105.78888 104.17066 103.21316 108.88465 116.81808
## 2018 109.07291 106.77434 106.87439 112.60466 119.00842
## 2019 111.83213 108.91560 110.26942 115.24839 122.60133
## 2020 100.21522 101.87361 105.09800 111.01645 119.94404
## 2021 111.92693 115.57074 115.80542 122.71004 132.30682
## 2022 121.65503 120.45365 120.52080 122.80948 133.00024
## 2023 122.43384 119.86254 119.71535 127.43698 134.24046
## 2024 124.03954 120.49445 123.64984 127.65571 138.80816
## 2025 127.13485 125.09699 126.95107 130.71397 141.24433

Extracción de señales

#Gráfico inicial de la variable 1 en niveles -Original

library(ggplot2)
library(plotly)

# Convertir la serie temporal a un vector numérico para graficar con ggplot2
data_col$variable1 <- as.numeric(variable1_ts)

# Crear el gráfico
grafico_serie <- ggplot(data_col, aes(x = seq.Date(from = as.Date("2012-01-01"), by = "month", length.out = nrow(data_col)), 
                                      y = variable1)) +
  geom_line(color = "grey", linewidth = 0.4) +
  geom_point(color = "black", size = 0.1) +
  ggtitle("Ocupación hotelera de Cali: Serie original") +
  xlab("Tiempo") +
  ylab("Ocupación hotelera (%)") +
  theme_minimal()

ggplotly(grafico_serie)

#Extracción señales variable 1: Ocupación hotelera de Cali

# Cargar librerías necesarias
library(ggplot2)
library(plotly)

# Descomposición de la serie temporal
stl_decomp_var1 <- stl(variable1_ts, s.window = "periodic")

# Convertir la descomposición a un data frame para graficar con ggplot2
stl_df_var1 <- data.frame(
  Time = rep(time(variable1_ts), 4),
  Value = c(stl_decomp_var1$time.series[, "seasonal"], 
            stl_decomp_var1$time.series[, "trend"], 
            stl_decomp_var1$time.series[, "remainder"], 
            variable1_ts),
  Component = rep(c("Estacional", "Tendencia", "Residuo", "Serie Original"), 
                  each = length(variable1_ts))
)

# Crear gráfico con ggplot2
p <- ggplot(stl_df_var1, aes(x = Time, y = Value, color = Component)) +
  geom_line() +
  facet_wrap(~Component, scales = "free_y", ncol = 1) + 
  theme_minimal() +
  labs(title = "Descomposición temporal de la ocupación hotelera de Cali",
       x = "Tiempo",
       y = "Valor")

# Convertir a gráfico interactivo con plotly
ggplotly(p)

Extracción señales variable 2: Índice de Confianza del Consumidor de Cali

# Cargar librerías necesarias
library(ggplot2)
library(plotly)

# Descomposición de la serie temporal
stl_decomp_var2 <- stl(variable2_ts, s.window = "periodic")

# Convertir la descomposición a un data frame para graficar con ggplot2
stl_df_var2 <- data.frame(
  Time = rep(time(variable2_ts), 4),
  Value = c(stl_decomp_var2$time.series[, "seasonal"], 
            stl_decomp_var2$time.series[, "trend"], 
            stl_decomp_var2$time.series[, "remainder"], 
            variable2_ts),
  Component = rep(c("Estacional", "Tendencia", "Residuo", "Serie Original"), 
                  each = length(variable2_ts))
)

# Crear gráfico con ggplot2
p <- ggplot(stl_df_var2, aes(x = Time, y = Value, color = Component)) +
  geom_line() +
  facet_wrap(~Component, scales = "free_y", ncol = 1) + 
  theme_minimal() +
  labs(title = "Descomposición temporal del ICC de Cali",
       x = "Tiempo",
       y = "Valor")

# Convertir a gráfico interactivo con plotly
ggplotly(p)

#Extracción señales variable 3: Indicador de Seguimiento a la Economía (ISE)

# Cargar librerías necesarias
library(ggplot2)
library(plotly)

# Descomposición de la serie temporal
stl_decomp_var3 <- stl(variable3_ts, s.window = "periodic")

# Convertir la descomposición a un data frame para graficar con ggplot2
stl_df_var3 <- data.frame(
  Time = rep(time(variable3_ts), 4),
  Value = c(stl_decomp_var3$time.series[, "seasonal"], 
            stl_decomp_var3$time.series[, "trend"], 
            stl_decomp_var3$time.series[, "remainder"], 
            variable3_ts),
  Component = rep(c("Estacional", "Tendencia", "Residuo", "Serie Original"), 
                  each = length(variable3_ts))
)

# Crear gráfico con ggplot2
p <- ggplot(stl_df_var3, aes(x = Time, y = Value, color = Component)) +
  geom_line() +
  facet_wrap(~Component, scales = "free_y", ncol = 1) + 
  theme_minimal() +
  labs(title = "Descomposición temporal del ISE",
       x = "Tiempo",
       y = "Valor")

# Convertir a gráfico interactivo con plotly
ggplotly(p)

#**Para identificar las principales características de las series seleccionadas, se realizó una descomposición temporal mediante el método STL, que permite distinguir entre la tendencia, la estacionalidad y el componente irregular de cada variable. A partir de esta descomposición, se analizó el comportamiento de la ocupación hotelera de Cali, el ICC de Cali y el ISE durante el período 2012–2025. Donde se identifico lo siguiente: #Ocupación hotelera de Cali: Presenta una estacionalidad marcada, con patrones que se repiten cada año. La tendencia se mantiene relativamente estable hasta 2019, presenta una fuerte caída en 2020 y posteriormente muestra una recuperación. #ICC de Cali: Presenta una tendencia más fluctuante y una estacionalidad menos marcada que las otras variables. Se observa una caída importante alrededor de 2020 y una recuperación posterior, aunque con variaciones durante el período. #ISE: Muestra una tendencia general creciente y una estacionalidad claramente definida. En 2020 presenta una caída pronunciada, seguida de una recuperación y una nueva trayectoria creciente.

#En conjunto, las tres variables muestran patrones estacionales y un cambio importante alrededor de 2020. Esto justifica continuar con el ajuste por estacionalidad, para analizar el comportamiento de las series sin el efecto de los patrones que se repiten cada año.**

Después de la descomposición temporal de cada variable, se extrae la variable ajustada por estacionalidad para graficarla junto con la serie original:

Se crea la variable1 ajustada por estacionalidad

# Extraer los componentes de la descomposición
variable1_sa <- variable1_ts - stl_decomp_var1$time.series[, "seasonal"]

Se crea la variable 2 ajustada por estacionalidad

# Extraer los componentes de la descomposición
variable2_sa <- variable2_ts - stl_decomp_var2$time.series[, "seasonal"]

Se crea la variable 3 ajustada por estacionalidad

# Extraer los componentes de la descomposición
variable3_sa <- variable3_ts - stl_decomp_var3$time.series[, "seasonal"]

Ahora si se puede graficar las series originales versus la ajustada por estacionalidad

Gráfico serie original VS ajustada Variable 1

# Crear vector de fechas correctamente alineado con la serie
fechas_var1 <- seq.Date(
  from = as.Date("2012-01-01"),
  by = "month",
  length.out = length(variable1_ts)
)

# Crear el gráfico
grafico_ajustada_var1 <- ggplot() +
  geom_line(
    aes(x = fechas_var1, y = as.numeric(variable1_ts)),
    color = "grey",
    linewidth = 0.5
  ) +
  geom_line(
    aes(x = fechas_var1, y = as.numeric(variable1_sa)),
    color = "black",
    linewidth = 0.6
  ) +
  ggtitle("Ocupación hotelera de Cali: Serie Original vs Serie Ajustada por Estacionalidad") +
  xlab("Tiempo") +
  ylab("Ocupación hotelera (%)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Convertir a gráfico interactivo
ggplotly(grafico_ajustada_var1)

Gráfico serie original VS ajustada Variable 2

# Crear vector de fechas correctamente alineado con la serie
fechas_var2 <- seq.Date(
  from = as.Date("2012-01-01"),
  by = "month",
  length.out = length(variable2_ts)
)

# Crear el gráfico
grafico_ajustada_var2 <- ggplot() +
  geom_line(
    aes(x = fechas_var2, y = as.numeric(variable2_ts)),
    color = "grey",
    linewidth = 0.5
  ) +
  geom_line(
    aes(x = fechas_var2, y = as.numeric(variable2_sa)),
    color = "black",
    linewidth = 0.6
  ) +
  ggtitle("ICC de Cali: Serie Original vs Serie Ajustada por Estacionalidad") +
  xlab("Tiempo") +
  ylab("Índice de confianza") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Convertir a gráfico interactivo
ggplotly(grafico_ajustada_var2)

Gráfico serie original VS ajustada Variable 3

# Crear vector de fechas correctamente alineado con la serie
fechas_var3 <- seq.Date(
  from = as.Date("2012-01-01"),
  by = "month",
  length.out = length(variable3_ts)
)

# Crear el gráfico
grafico_ajustada_var3 <- ggplot() +
  geom_line(
    aes(x = fechas_var3, y = as.numeric(variable3_ts)),
    color = "grey",
    linewidth = 0.5
  ) +
  geom_line(
    aes(x = fechas_var3, y = as.numeric(variable3_sa)),
    color = "black",
    linewidth = 0.6
  ) +
  ggtitle("ISE: Serie Original vs Serie Ajustada por Estacionalidad") +
  xlab("Tiempo") +
  ylab("Índice") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Convertir a gráfico interactivo
ggplotly(grafico_ajustada_var3)

Interpretación: En conjunto, el ajuste estacional permite identificar mejor los movimientos estructurales de las tres variables. El hecho más evidente es el fuerte cambio alrededor de 2020, cuando la actividad económica, la confianza del consumidor y la ocupación hotelera presentan caídas importantes, seguidas de una recuperación. Esto constituye un punto relevante para el análisis del Hotel InterContinental Cali, aunque no permite afirmar que una variable sea causa de otra. Además, la presencia de estacionalidad en las tres series confirma que es importante considerar los períodos recurrentes de mayor y menor actividad al analizar la demanda hotelera

Ahora graficamos serie original vs tendencia Tendencia Variable 1

library(ggplot2)
library(plotly)

# Convertir la serie original y la tendencia a vectores numéricos
variable1_vec <- as.numeric(variable1_ts)
tendencia_var1 <- as.numeric(stl_decomp_var1$time.series[, "trend"])

# Crear fechas
fechas_var1 <- seq.Date(
  from = as.Date("2012-01-01"),
  by = "month",
  length.out = length(variable1_ts)
)

# Crear gráfico
grafico_tendencia_var1 <- ggplot() +
  geom_line(
    aes(x = fechas_var1, y = variable1_vec),
    color = "grey",
    size = 0.7
  ) +
  geom_line(
    aes(x = fechas_var1, y = tendencia_var1),
    color = "black",
    size = 0.8
  ) +
  ggtitle("Ocupación hotelera de Cali: Serie Original vs Tendencia") +
  xlab("Tiempo") +
  ylab("Ocupación hotelera (%)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Convertir a gráfico interactivo
ggplotly(grafico_tendencia_var1)

Tendencia Variable 2

library(ggplot2)
library(plotly)

# Convertir la serie original y la tendencia a vectores numéricos
variable2_vec <- as.numeric(variable2_ts)
tendencia_var2 <- as.numeric(stl_decomp_var2$time.series[, "trend"])

# Crear fechas
fechas_var2 <- seq.Date(
  from = as.Date("2012-01-01"),
  by = "month",
  length.out = length(variable2_ts)
)

# Crear gráfico
grafico_tendencia_var2 <- ggplot() +
  geom_line(
    aes(x = fechas_var2, y = variable2_vec),
    color = "grey",
    size = 0.7
  ) +
  geom_line(
    aes(x = fechas_var2, y = tendencia_var2),
    color = "black",
    size = 0.8
  ) +
  ggtitle("ICC de Cali: Serie Original vs Tendencia") +
  xlab("Tiempo") +
  ylab("Índice de confianza") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Convertir a gráfico interactivo
ggplotly(grafico_tendencia_var2)

Tendencia Variable 3

library(ggplot2)
library(plotly)

# Convertir la serie original y la tendencia a vectores numéricos
variable3_vec <- as.numeric(variable3_ts)
tendencia_var3 <- as.numeric(stl_decomp_var3$time.series[, "trend"])

# Crear fechas
fechas_var3 <- seq.Date(
  from = as.Date("2012-01-01"),
  by = "month",
  length.out = length(variable3_ts)
)

# Crear gráfico
grafico_tendencia_var3 <- ggplot() +
  geom_line(
    aes(x = fechas_var3, y = variable3_vec),
    color = "grey",
    size = 0.7
  ) +
  geom_line(
    aes(x = fechas_var3, y = tendencia_var3),
    color = "black",
    size = 0.8
  ) +
  ggtitle("ISE: Serie Original vs Tendencia") +
  xlab("Tiempo") +
  ylab("Índice") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Convertir a gráfico interactivo
ggplotly(grafico_tendencia_var3)

Interpretación: Ocupación hotelera de Cali: La tendencia de la ocupación hotelera se mantiene relativamente estable, alrededor del 50–60 %, durante 2012–2019. En 2020 se observa una caída muy pronunciada, seguida de una recuperación rápida entre 2021 y 2022. Posteriormente, la tendencia alcanza niveles cercanos al 60 % y vuelve a moderarse hasta 2025. Para el Hotel InterContinental Cali, esto muestra que, además de la estacionalidad, existen cambios estructurales en la demanda hotelera, especialmente durante el período de 2020. ICC de Cali: El ICC presenta una tendencia mucho más variable y cíclica. Parte de niveles positivos entre 2012 y 2015, pero disminuye progresivamente hasta ubicarse cerca de cero entre 2016 y 2017. Posteriormente presenta una recuperación temporal, seguida de una nueva caída alrededor de 2020. Desde 2021 comienza una recuperación gradual y hacia 2025 la tendencia vuelve a ubicarse en valores positivos. Esto muestra cambios importantes en las expectativas y confianza de los consumidores, que constituyen una señal relevante para el entorno de demanda turística. ISE: El ISE presenta una tendencia general creciente durante casi todo el período. Entre 2012 y 2019 aumenta progresivamente, aunque con una moderación alrededor de 2019. En 2020 registra una caída fuerte, seguida de una recuperación durante 2021–2022. Desde entonces mantiene una trayectoria creciente hasta 2025. Esto refleja una expansión general de la actividad económica, interrumpida por el choque de 2020.

Ahora calculamos la tasa de crecimiento de la serie original vs tendencia:

Tasa de crecimiento de la serie de tendencia y original para la variable 1

# Cálculo de la tasa de crecimiento anual de la serie original y la tendencia
tasa_crecimiento_var1 <- (variable1_ts[13:length(variable1_ts)] / 
                            variable1_ts[1:(length(variable1_ts) - 12)] - 1) * 100

tasa_tendencia_var1 <- (tendencia_var1[13:length(tendencia_var1)] / 
                         tendencia_var1[1:(length(tendencia_var1) - 12)] - 1) * 100

# Crear vector de fechas corregido, iniciando desde enero de 2013
fechas_corregidas_var1 <- seq(
  from = as.Date("2013-01-01"),
  by = "month",
  length.out = length(tasa_crecimiento_var1)
)

# Verificar longitudes
print(length(fechas_corregidas_var1))
## [1] 156
print(length(tasa_crecimiento_var1))
## [1] 156
print(length(tasa_tendencia_var1))
## [1] 156

Gráfico variable original y tendencia variable 1: tasa de crecimiento anual

library(ggplot2)
library(plotly)

# Gráfico de la tasa de crecimiento anual variable 1
grafico_crecimiento_var1 <- ggplot() +
  geom_line(aes(x = fechas_corregidas_var1, y = tasa_crecimiento_var1), 
            color = "grey", size = 0.7) +
  geom_line(aes(x = fechas_corregidas_var1, y = tasa_tendencia_var1), 
            color = "black", size = 0.8, linetype = "dashed") +
  ggtitle("Ocupación hotelera de Cali: Tasa de crecimiento anual % de la serie Original y la tendencia") +
  xlab("Tiempo") +
  ylab("% de Crecimiento Anual") +
  theme_minimal()

# Convertir a gráfico interactivo
ggplotly(grafico_crecimiento_var1)

Tasa de crecimiento de la serie de tendencia y original para la variable 2

# Cálculo de la tasa de crecimiento anual correctamente alineada
tasa_crecimiento_var2 <- (variable2_ts[13:length(variable2_ts)] / 
                            variable2_ts[1:(length(variable2_ts) - 12)] - 1) * 100

tasa_tendencia_var2 <- (tendencia_var2[13:length(tendencia_var2)] / 
                         tendencia_var2[1:(length(tendencia_var2) - 12)] - 1) * 100

# Crear vector de fechas corregido, es decir que inicie desde enero 2013
fechas_corregidas_var2 <- seq(
  from = as.Date("2013-01-01"),
  by = "month",
  length.out = length(tasa_crecimiento_var2)
)

# Verificar longitudes
print(length(fechas_corregidas_var2))
## [1] 156
print(length(tasa_crecimiento_var2))
## [1] 156
print(length(tasa_tendencia_var2))
## [1] 156

Gráfico variable original y tendencia variable 2: tasa de crecimiento anual

library(ggplot2)
library(plotly)

# Gráfico de la tasa de crecimiento anual variable 2
grafico_crecimiento_var2 <- ggplot() +
  geom_line(aes(x = fechas_corregidas_var2, y = tasa_crecimiento_var2), 
            color = "grey", size = 0.7) +
  geom_line(aes(x = fechas_corregidas_var2, y = tasa_tendencia_var2), 
            color = "black", size = 0.8, linetype = "dashed") +
  ggtitle("ICC de Cali: Tasa de crecimiento anual % de la serie Original y la tendencia") +
  xlab("Tiempo") +
  ylab("% de Crecimiento Anual") +
  theme_minimal()

# Convertir a gráfico interactivo
ggplotly(grafico_crecimiento_var2)

Tasa de crecimiento de la serie de tendencia y original para la variable 3

# Cálculo de la tasa de crecimiento anual de la serie original y la tendencia
tasa_crecimiento_var3 <- (variable3_ts[13:length(variable3_ts)] / 
                            variable3_ts[1:(length(variable3_ts) - 12)] - 1) * 100

tasa_tendencia_var3 <- (tendencia_var3[13:length(tendencia_var3)] / 
                         tendencia_var3[1:(length(tendencia_var3) - 12)] - 1) * 100

# Crear vector de fechas corregido, iniciando desde enero de 2013
fechas_corregidas_var3 <- seq(
  from = as.Date("2013-01-01"),
  by = "month",
  length.out = length(tasa_crecimiento_var3)
)

# Verificar longitudes
print(length(fechas_corregidas_var3))
## [1] 156
print(length(tasa_crecimiento_var3))
## [1] 156
print(length(tasa_tendencia_var3))
## [1] 156
library(ggplot2)
library(plotly)

# Gráfico de la tasa de crecimiento anual variable 3
grafico_crecimiento_var3 <- ggplot() +
  geom_line(
    aes(x = fechas_corregidas_var3, y = tasa_crecimiento_var3), 
    color = "grey", 
    size = 0.7
  ) +
  geom_line(
    aes(x = fechas_corregidas_var3, y = tasa_tendencia_var3), 
    color = "black", 
    size = 0.8, 
    linetype = "dashed"
  ) +
  ggtitle("ISE: Tasa de crecimiento anual % de la serie Original y la tendencia") +
  xlab("Tiempo") +
  ylab("% de Crecimiento Anual") +
  theme_minimal()

# Convertir a gráfico interactivo
ggplotly(grafico_crecimiento_var3)

#Interpretación: Las tres variables muestran señales mixtas, pero con una recuperación clara después del choque de 2020. La ocupación hotelera y el ISE presentan una fuerte caída durante 2020, seguida de una recuperación importante en los años posteriores, mientras que el ICC evidencia una dinámica más volátil asociada a cambios en la confianza. En conjunto, las tasas de crecimiento de la tendencia muestran que la actividad económica y la ocupación hotelera han recuperado parte de su dinámica después de la caída de 2020, aunque el ritmo de crecimiento se ha moderado hacia los últimos años. Por su parte, el comportamiento más fluctuante del ICC señala que las condiciones de confianza presentan mayor incertidumbre. Por tanto, el escenario general combina señales favorables de recuperación y estabilidad con señales de moderación e incertidumbre, lo que hace relevante monitorear conjuntamente la actividad económica, la confianza y el comportamiento del sector hotelero.

#Selección de variable para pronostico #Para la construcción del modelo ARIMA/SARIMA se selecciona la ocupación hotelera de Cali (OCUP_HOTEL_CALI), debido a que constituye la variable directamente relacionada con la actividad del sector hotelero y, por tanto, permite generar un pronóstico de corto plazo relevante para la planificación del Hotel InterContinental Cali.

# Serie seleccionada para el pronóstico
serie_pronostico <- variable1_ts

# Mostrar la serie
serie_pronostico
##            Jan       Feb       Mar       Apr       May       Jun       Jul
## 2012 40.984148 48.163945 52.751647 46.186024 51.656806 50.498865 50.687476
## 2013 38.086361 51.665945 46.410769 54.389457 56.751197 55.800285 63.027240
## 2014 44.333605 52.902421 51.557234 50.734539 53.464851 47.137093 52.576386
## 2015 44.724933 49.953606 49.744313 49.554234 54.826536 58.593627 65.146502
## 2016 49.154764 58.314705 52.380638 55.823001 54.776938 55.320560 52.846760
## 2017 45.069758 62.273459 59.861433 56.527333 52.612756 53.991888 54.144508
## 2018 46.893462 58.005900 53.450816 57.588292 52.494087 55.418636 56.674943
## 2019 48.658704 61.509657 56.973252 50.175596 57.697959 57.352878 58.098882
## 2020 49.179432 55.608367 29.654494  3.380544  4.055782  4.283978  8.207688
## 2021 20.068146 25.373495 32.348885 28.251748 18.982892 27.704024 35.673503
## 2022 40.481477 53.547676 59.027372 55.387065 59.723427 54.786626 71.830717
## 2023 52.373911 54.886085 57.563905 54.693217 55.658694 54.134706 57.715428
## 2024 42.610000 53.480000 52.550000 51.640000 49.010000 49.170000 49.680000
## 2025 45.360000 49.920000 47.450000 48.010000 51.820000 55.480000 61.000000
##            Aug       Sep       Oct       Nov       Dec
## 2012 52.192862 57.394377 60.205655 58.180522 48.398649
## 2013 59.284782 55.818442 60.448391 58.622399 54.725298
## 2014 56.396331 54.141024 59.202058 59.872495 52.288622
## 2015 59.362884 67.055408 66.936527 67.067612 58.769211
## 2016 59.828018 70.739118 59.643952 67.395772 53.674790
## 2017 60.167547 54.016639 62.693815 62.530258 55.059444
## 2018 55.827297 61.863534 58.866459 62.879937 56.430991
## 2019 61.179771 61.151650 61.702467 62.644918 56.036853
## 2020  6.784319 13.733728 22.558021 30.792839 28.038383
## 2021 45.312803 49.834545 51.910932 65.583885 60.928307
## 2022 69.124634 66.829581 65.504159 66.671055 60.354868
## 2023 58.952883 55.987835 55.804281 67.270734 58.711385
## 2024 56.550000 54.800000 65.222412 61.291183 55.568770
## 2025 60.630000 54.250000 65.940000 60.330000 53.330000
# División de la serie en conjunto de entrenamiento y conjunto de prueba

# Entrenamiento: enero 2012 - diciembre 2024
train_ts <- window(
  serie_pronostico,
  end = c(2024, 12)
)

# Prueba: enero 2025 - diciembre 2025
test_ts <- window(
  serie_pronostico,
  start = c(2025, 1)
)

# Verificar las series
train_ts
##            Jan       Feb       Mar       Apr       May       Jun       Jul
## 2012 40.984148 48.163945 52.751647 46.186024 51.656806 50.498865 50.687476
## 2013 38.086361 51.665945 46.410769 54.389457 56.751197 55.800285 63.027240
## 2014 44.333605 52.902421 51.557234 50.734539 53.464851 47.137093 52.576386
## 2015 44.724933 49.953606 49.744313 49.554234 54.826536 58.593627 65.146502
## 2016 49.154764 58.314705 52.380638 55.823001 54.776938 55.320560 52.846760
## 2017 45.069758 62.273459 59.861433 56.527333 52.612756 53.991888 54.144508
## 2018 46.893462 58.005900 53.450816 57.588292 52.494087 55.418636 56.674943
## 2019 48.658704 61.509657 56.973252 50.175596 57.697959 57.352878 58.098882
## 2020 49.179432 55.608367 29.654494  3.380544  4.055782  4.283978  8.207688
## 2021 20.068146 25.373495 32.348885 28.251748 18.982892 27.704024 35.673503
## 2022 40.481477 53.547676 59.027372 55.387065 59.723427 54.786626 71.830717
## 2023 52.373911 54.886085 57.563905 54.693217 55.658694 54.134706 57.715428
## 2024 42.610000 53.480000 52.550000 51.640000 49.010000 49.170000 49.680000
##            Aug       Sep       Oct       Nov       Dec
## 2012 52.192862 57.394377 60.205655 58.180522 48.398649
## 2013 59.284782 55.818442 60.448391 58.622399 54.725298
## 2014 56.396331 54.141024 59.202058 59.872495 52.288622
## 2015 59.362884 67.055408 66.936527 67.067612 58.769211
## 2016 59.828018 70.739118 59.643952 67.395772 53.674790
## 2017 60.167547 54.016639 62.693815 62.530258 55.059444
## 2018 55.827297 61.863534 58.866459 62.879937 56.430991
## 2019 61.179771 61.151650 61.702467 62.644918 56.036853
## 2020  6.784319 13.733728 22.558021 30.792839 28.038383
## 2021 45.312803 49.834545 51.910932 65.583885 60.928307
## 2022 69.124634 66.829581 65.504159 66.671055 60.354868
## 2023 58.952883 55.987835 55.804281 67.270734 58.711385
## 2024 56.550000 54.800000 65.222412 61.291183 55.568770
test_ts
##        Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep   Oct   Nov   Dec
## 2025 45.36 49.92 47.45 48.01 51.82 55.48 61.00 60.63 54.25 65.94 60.33 53.33
# Verificar número de observaciones

cat("Observaciones entrenamiento:", length(train_ts), "\n")
## Observaciones entrenamiento: 156
cat("Observaciones prueba:", length(test_ts), "\n")
## Observaciones prueba: 12
# Gráfico de entrenamiento y prueba

datos_train_test <- data.frame(
  Tiempo = c(time(train_ts), time(test_ts)),
  Valor = c(as.numeric(train_ts), as.numeric(test_ts)),
  Conjunto = c(
    rep("Entrenamiento", length(train_ts)),
    rep("Prueba", length(test_ts))
  )
)

grafico_train_test <- ggplot(
  datos_train_test,
  aes(x = Tiempo, y = Valor, color = Conjunto)
) +
  geom_line() +
  ggtitle("Ocupación hotelera de Cali: conjunto de entrenamiento y prueba") +
  xlab("Tiempo") +
  ylab("Ocupación hotelera (%)") +
  theme_minimal()

ggplotly(grafico_train_test)

#Paso 1 Identificación del modelo:

# Prueba de estacionariedad ADF

library(tseries)

adf_test <- adf.test(train_ts)

print(adf_test)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  train_ts
## Dickey-Fuller = -3.2609, Lag order = 5, p-value = 0.08029
## alternative hypothesis: stationary

Interpretación: La prueba de Dickey-Fuller aumentada aplicada a la serie de entrenamiento de la ocupación hotelera de Cali presenta un estadístico de -3,2609 y un p-value de 0,08029. Dado que el p-value es mayor que 0,05, no se rechaza la hipótesis nula de existencia de raíz unitaria al 5 % de significancia. Por tanto, al nivel de significancia del 5 %, la serie no presenta evidencia suficiente de estacionariedad y se considera no estacionaria en niveles. En consecuencia, se procede a realizar una primera diferenciación de la serie para evaluar si alcanza estacionariedad.

# Primera diferenciación de la serie

train_diff <- diff(
  train_ts,
  differences = 1
)

train_diff
##               Jan          Feb          Mar          Apr          May
## 2012                7.17979782   4.58770137  -6.56562236   5.47078198
## 2013 -10.31228750  13.57958316  -5.25517545   7.97868792   2.36174048
## 2014 -10.39169264   8.56881563  -1.34518726  -0.82269518   2.73031187
## 2015  -7.56368908   5.22867239  -0.20929311  -0.19007882   5.27230245
## 2016  -9.61444756   9.15994143  -5.93406742   3.44236318  -1.04606317
## 2017  -8.60503206  17.20370159  -2.41202587  -3.33410089  -3.91457683
## 2018  -8.16598264  11.11243796  -4.55508359   4.13747628  -5.09420509
## 2019  -7.77228741  12.85095365  -4.53640526  -6.79765633   7.52236361
## 2020  -6.85742056   6.42893467 -25.95387304 -26.27394986   0.67523830
## 2021  -7.97023692   5.30534852   6.97539006  -4.09713668  -9.26885673
## 2022 -20.44682991  13.06619899   5.47969583  -3.64030733   4.33636173
## 2023  -7.98095642   2.51217381   2.67781983  -2.87068842   0.96547748
## 2024 -16.10138527  10.87000000  -0.93000000  -0.91000000  -2.63000000
##               Jun          Jul          Aug          Sep          Oct
## 2012  -1.15794109   0.18861107   1.50538594   5.20151425   2.81127878
## 2013  -0.95091278   7.22695579  -3.74245894  -3.46633986   4.62994956
## 2014  -6.32775784   5.43929288   3.81994586  -2.25530725   5.06103428
## 2015   3.76709052   6.55287507  -5.78361797   7.69252376  -0.11888077
## 2016   0.54362175  -2.47379938   6.98125795  10.91110027 -11.09516592
## 2017   1.37913215   0.15262010   6.02303852  -6.15090732   8.67717610
## 2018   2.92454822   1.25630746  -0.84764641   6.03623695  -2.99707479
## 2019  -0.34508176   0.74600396   3.08088899  -0.02812061   0.55081735
## 2020   0.22819579   3.92371034  -1.42336882   6.94940841   8.82429334
## 2021   8.72113216   7.96947936   9.63929976   4.52174262   2.07638664
## 2022  -4.93680078  17.04409096  -2.70608266  -2.29505302  -1.32542194
## 2023  -1.52398782   3.58072213   1.23745500  -2.96504826  -0.18355369
## 2024   0.16000000   0.51000000   6.87000000  -1.75000000  10.42241241
##               Nov          Dec
## 2012  -2.02513344  -9.78187306
## 2013  -1.82599249  -3.89710068
## 2014   0.67043677  -7.58387274
## 2015   0.13108546  -8.29840106
## 2016   7.75181932 -13.72098195
## 2017  -0.16355776  -7.47081311
## 2018   4.01347782  -6.44894547
## 2019   0.94245023  -6.60806501
## 2020   8.23481772  -2.75445560
## 2021  13.67295343  -4.65557820
## 2022   1.16689627  -6.31618756
## 2023  11.46645298  -8.55934920
## 2024  -3.93122927  -5.72241325
# Primera diferencia logarítmica

train_diff_log <- diff(
  log(train_ts),
  differences = 1
)

train_diff_log
##                Jan           Feb           Mar           Apr           May
## 2012                0.1614253729  0.0909842699 -0.1329177397  0.1119447155
## 2013 -0.2396156488  0.3049426027 -0.1072673267  0.1586388055  0.0425064272
## 2014 -0.2105831129  0.1767061273 -0.0257565780 -0.0160856128  0.0524175240
## 2015 -0.1562476637  0.1105635503 -0.0041985515 -0.0038284357  0.1011066127
## 2016 -0.1786443360  0.1708805299 -0.1073172798  0.0636489731 -0.0189167259
## 2017 -0.1747319660  0.3233238594 -0.0395028720 -0.0573081656 -0.0717656886
## 2018 -0.1605351510  0.2126664668 -0.0817828183  0.0745573838 -0.0926187495
## 2019 -0.1481877982  0.2343634954 -0.0766122965 -0.1270531278  0.1396930384
## 2020 -0.1305340683  0.1228581824 -0.6287199997 -2.1715770914  0.1821069591
## 2021 -0.3344406030  0.2345713206  0.2428744311 -0.1354242106 -0.3976172134
## 2022 -0.4088533619  0.2797278835  0.0974288677 -0.0636551915  0.0753782684
## 2023 -0.1418330108  0.0468512661  0.0476358633 -0.0511560315  0.0174986026
## 2024 -0.3205446975  0.2272187847 -0.0175426549 -0.0174685313 -0.0522722071
##                Jun           Jul           Aug           Sep           Oct
## 2012 -0.0226710992  0.0037279989  0.0292668825  0.0950005809  0.0478199612
## 2013 -0.0168977855  0.1217880502 -0.0612143835 -0.0602483270  0.0796856528
## 2014 -0.1259642168  0.1092068539  0.0701370353 -0.0408119096  0.0893641113
## 2015  0.0664516175  0.1060126756 -0.0929694277  0.1218500766 -0.0017744472
## 2016  0.0098753593 -0.0457482135  0.1240776736  0.1675246394 -0.1706059613
## 2017  0.0258752161  0.0028227352  0.1054765662 -0.1078409800  0.1489706707
## 2018  0.0542153779  0.0224162719 -0.0150692547  0.1026679511 -0.0496594197
## 2019 -0.0059987881  0.0129233950  0.0516701748 -0.0004597446  0.0089670750
## 2020  0.0547384498  0.6501893145 -0.1904573236  0.7052407129  0.4962360166
## 2021  0.3780395347  0.2528305395  0.2391814137  0.0951188115  0.0408209782
## 2022 -0.0862782391  0.2708660851 -0.0384010281 -0.0337653535 -0.0200321741
## 2023 -0.0277627926  0.0640490268  0.0212140106 -0.0516041009 -0.0032838426
## 2024  0.0032593225  0.0103187562  0.1295227649 -0.0314350086  0.1741129645
##                Nov           Dec
## 2012 -0.0342156669 -0.1840787266
## 2013 -0.0306731088 -0.0687907646
## 2014  0.0112609090 -0.1354384174
## 2015  0.0019564395 -0.1320831497
## 2016  0.1221895231 -0.2276388546
## 2017 -0.0026122429 -0.1272371508
## 2018  0.0659556719 -0.1082086440
## 2019  0.0151586344 -0.1114729981
## 2020  0.3111914509 -0.0937077563
## 2021  0.2338006127 -0.0736321352
## 2022  0.0176572679 -0.0995293022
## 2023  0.1868746946 -0.1360916253
## 2024 -0.0621671572 -0.0980146505

#Graficar original vs diferenciada:

# Serie original
p_original <- ggplot(
  data.frame(
    Tiempo = time(train_ts),
    Valor = as.numeric(train_ts)
  ),
  aes(x = Tiempo, y = Valor)
) +
  geom_line() +
  ggtitle("Ocupación hotelera de Cali: Serie Original") +
  xlab("Tiempo") +
  ylab("Ocupación hotelera (%)")

ggplotly(p_original)
# Serie diferenciada
p_diferenciada <- ggplot(
  data.frame(
    Tiempo = time(train_diff),
    Valor = as.numeric(train_diff)
  ),
  aes(x = Tiempo, y = Valor)
) +
  geom_line() +
  ggtitle("Ocupación hotelera de Cali: Primera diferenciación") +
  xlab("Tiempo") +
  ylab("Primera diferencia")

ggplotly(p_diferenciada)

#Realizar ADF en niveles diferenciados:

# ADF sobre la serie diferenciada

adf_test_diff <- adf.test(train_diff)

print(adf_test_diff)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  train_diff
## Dickey-Fuller = -5.9162, Lag order = 5, p-value = 0.01
## alternative hypothesis: stationary
# ADF sobre la serie diferenciada en logaritmo

adf_test_diff_log <- adf.test(train_diff_log)

print(adf_test_diff_log)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  train_diff_log
## Dickey-Fuller = -6.7984, Lag order = 5, p-value = 0.01
## alternative hypothesis: stationary

#Interpretación: #La prueba ADF aplicada a la primera diferencia de la serie presenta un estadístico Dickey-Fuller de -5,9162 y un p-value de 0,01. Debido a que el p-value es inferior al nivel de significancia del 5 %, se rechaza la hipótesis nula de existencia de raíz unitaria. Por lo tanto, la primera diferencia de la serie de ocupación hotelera es estacionaria.

De manera similar, la primera diferencia logarítmica presenta un estadístico Dickey-Fuller de -6,7984 y un p-value de 0,01. Al ser inferior al 5 %, se rechaza la hipótesis nula, indicando que la serie diferenciada en logaritmos también es estacionaria.

En consecuencia, una diferenciación es suficiente para alcanzar estacionariedad, por lo que para el componente no estacional del modelo ARIMA se considera d = 1.

#Identificación Manual:

library(forecast)

# ACF
acf_plot <- ggAcf(
  train_diff_log,
  lag.max = 12
) +
  ggtitle(
    "ACF - Ocupación hotelera de Cali"
  )

# PACF
pacf_plot <- ggPacf(
  train_diff_log,
  lag.max = 12
) +
  ggtitle(
    "PACF - Ocupación hotelera de Cali"
  )

# Mostrar gráficos
ggplotly(acf_plot)
ggplotly(pacf_plot)

#Interpretación: Una vez realizada la primera diferenciación logarítmica, se analizaron las funciones de autocorrelación (ACF) y autocorrelación parcial (PACF) para identificar posibles componentes autorregresivos y de medias móviles. En el ACF se observa que la mayoría de los rezagos se encuentran dentro de las bandas de confianza, aunque se presentan valores significativos en los rezagos 6 y 12. En el PACF se destaca principalmente el rezago 6, que supera la banda inferior. Estos resultados indican la presencia de cierta dependencia temporal en la serie diferenciada, pero no muestran un patrón de corte claramente definido en los primeros rezagos.

#Modelo ARIMA automático:

# Modelo ARIMA automático sin componente estacional

library(forecast)

auto_arima_model_no_seasonal <- auto.arima(
  train_ts,
  seasonal = FALSE
)

# Mostrar modelo seleccionado
summary(auto_arima_model_no_seasonal)
## Series: train_ts 
## ARIMA(1,0,0) with non-zero mean 
## 
## Coefficients:
##          ar1     mean
##       0.8481  51.7057
## s.e.  0.0413   3.5034
## 
## sigma^2 = 47.91:  log likelihood = -522.78
## AIC=1051.57   AICc=1051.73   BIC=1060.72
## 
## Training set error measures:
##                      ME     RMSE      MAE       MPE     MAPE      MASE
## Training set 0.09017337 6.876906 5.136105 -9.352559 18.59565 0.4928162
##                     ACF1
## Training set -0.03507062

#Interpretación: El procedimiento automático seleccionó un modelo ARIMA(1,0,0), lo que indica que la ocupación hotelera presenta una relación con su propio valor del período anterior, sin requerir diferenciación. El coeficiente autorregresivo estimado fue de 0,8481, lo que evidencia una alta persistencia de la serie. Este modelo servirá como referencia para compararlo posteriormente con el modelo SARIMA y evaluar cuál presenta mejor capacidad predictiva.

# Modelo SARIMA automático

auto_sarima_model <- auto.arima(
  train_ts,
  seasonal = TRUE
)

# Mostrar modelo seleccionado
summary(auto_sarima_model)
## Series: train_ts 
## ARIMA(1,0,0)(2,0,0)[12] with non-zero mean 
## 
## Coefficients:
##          ar1    sar1    sar2     mean
##       0.8905  0.2898  0.2560  51.8571
## s.e.  0.0346  0.0768  0.0808   8.3478
## 
## sigma^2 = 37.95:  log likelihood = -505.64
## AIC=1021.28   AICc=1021.68   BIC=1036.53
## 
## Training set error measures:
##                      ME     RMSE      MAE       MPE     MAPE     MASE
## Training set 0.08559791 6.080877 4.418041 -8.027743 16.44689 0.423917
##                     ACF1
## Training set -0.03999938

#Interpretación: El procedimiento automático seleccionó un modelo SARIMA(1,0,0)(2,0,0)[12], incorporando una componente autorregresiva no estacional y dos componentes autorregresivas estacionales con periodicidad anual. El coeficiente AR(1) es de 0,8905, lo que indica una alta persistencia en la ocupación hotelera. Además, la inclusión de la componente estacional permite capturar posibles patrones que se repiten anualmente. El modelo presenta un AIC de 1021,28, que posteriormente será utilizado para compararlo con otras especificaciones.

#Comparar ARIMA automático y SARIMA automático:

# Comparación de criterios de información

comparacion_modelos <- data.frame(
  Modelo = c(
    "ARIMA automático",
    "SARIMA automático"
  ),
  AIC = c(
    AIC(auto_arima_model_no_seasonal),
    AIC(auto_sarima_model)
  ),
  BIC = c(
    BIC(auto_arima_model_no_seasonal),
    BIC(auto_sarima_model)
  )
)

comparacion_modelos
Modelo AIC BIC
ARIMA automático 1051.568 1060.718
SARIMA automático 1021.276 1036.525

#Interpretación: Al comparar los criterios de información, el modelo SARIMA automático presenta valores inferiores de AIC (1021,28) y BIC (1036,53) frente al ARIMA automático, cuyos valores son 1051,57 y 1060,72, respectivamente. Esto indica que, de acuerdo con estos criterios, el SARIMA ofrece un mejor ajuste considerando la complejidad del modelo.

#Diagnostico de residuos ARIMA

# Diagnóstico de residuos del modelo ARIMA automático

checkresiduals(
  auto_arima_model_no_seasonal
)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,0,0) with non-zero mean
## Q* = 81.144, df = 23, p-value = 2.07e-08
## 
## Model df: 1.   Total lags used: 24

#Interpretación: Los residuos del modelo ARIMA(1,0,0) fluctúan alrededor de cero y no presentan una tendencia sistemática evidente. Sin embargo, la función de autocorrelación muestra varios rezagos que superan las bandas de confianza, particularmente en los rezagos 12, 24 y 36, lo que evidencia autocorrelación remanente y sugiere que el modelo no captura completamente la dinámica estacional de la ocupación hotelera.

#Diagnostico de residuos SARIMA:

# Diagnóstico de residuos del modelo SARIMA automático

checkresiduals(
  auto_sarima_model
)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,0,0)(2,0,0)[12] with non-zero mean
## Q* = 25.71, df = 21, p-value = 0.2177
## 
## Model df: 3.   Total lags used: 24

#Interpretación: Los residuos fluctúan alrededor de cero y no presentan una tendencia sistemática evidente. Además, la mayoría de las autocorrelaciones se encuentran dentro de las bandas de confianza, lo que indica una reducción de la autocorrelación remanente frente al modelo ARIMA. Sin embargo, todavía se observan algunos valores atípicos y ciertos rezagos cercanos a las bandas.

#Validación predictiva en el conjunto de prueba:

# Pronóstico del conjunto de prueba con ARIMA automático

forecast_arima_auto <- forecast(
  auto_arima_model_no_seasonal,
  h = length(test_ts)
)

# Crear tabla de resultados
forecast_table_arima <- data.frame(
  Tiempo = time(test_ts),
  Observado = as.numeric(test_ts),
  Pronosticado = as.numeric(forecast_arima_auto$mean)
)

forecast_table_arima
Tiempo Observado Pronosticado
2025.000 45.36 54.98215
2025.083 49.92 54.48461
2025.167 47.45 54.06262
2025.250 48.01 53.70472
2025.333 51.82 53.40116
2025.417 55.48 53.14370
2025.500 61.00 52.92533
2025.583 60.63 52.74012
2025.667 54.25 52.58304
2025.750 65.94 52.44981
2025.833 60.33 52.33681
2025.917 53.33 52.24097
# Pronóstico del conjunto de prueba con SARIMA automático

forecast_sarima <- forecast(
  auto_sarima_model,
  h = length(test_ts)
)

# Crear tabla de resultados

forecast_table_sarima <- data.frame(
  Tiempo = time(test_ts),
  Observado = as.numeric(test_ts),
  Pronosticado = as.numeric(forecast_sarima$mean)
)

forecast_table_sarima
Tiempo Observado Pronosticado
2025.000 45.36 48.90827
2025.083 49.92 52.74584
2025.167 47.45 53.20077
2025.250 48.01 52.23703
2025.333 51.82 51.75284
2025.417 55.48 51.43674
2025.500 61.00 52.52566
2025.583 60.63 54.85555
2025.667 54.25 53.60887
2025.750 65.94 56.60018
2025.833 60.33 58.41112
2025.917 53.33 54.57540

#Interpretación: Al comparar los pronósticos de ambos modelos para el período de prueba, el SARIMA parece adaptarse mejor a las variaciones observadas en la ocupación hotelera que el ARIMA, ya que incorpora la componente estacional anual. El ARIMA presenta pronósticos más estables alrededor de su nivel medio y no captura completamente las fluctuaciones de la serie. Sin embargo, esta comparación visual debe complementarse con las métricas MAE, RMSE y MAPE para determinar formalmente cuál presenta mejor capacidad predictiva.

#Metricas Arima:

# Métricas de error del modelo ARIMA

mae_arima <- mean(
  abs(
    forecast_arima_auto$mean - test_ts
  ),
  na.rm = TRUE
)

rmse_arima <- sqrt(
  mean(
    (forecast_arima_auto$mean - test_ts)^2,
    na.rm = TRUE
  )
)

mape_arima <- mean(
  abs(
    (test_ts - forecast_arima_auto$mean) / test_ts
  ),
  na.rm = TRUE
) * 100

cat("MAE ARIMA:", mae_arima, "\n")
## MAE ARIMA: 5.884624
cat("RMSE ARIMA:", rmse_arima, "\n")
## RMSE ARIMA: 6.921151
cat("MAPE ARIMA:", mape_arima, "%\n")
## MAPE ARIMA: 10.70742 %

Metricas Sarima:

# Métricas de error del modelo SARIMA

mae_sarima <- mean(
  abs(
    forecast_sarima$mean - test_ts
  ),
  na.rm = TRUE
)

rmse_sarima <- sqrt(
  mean(
    (forecast_sarima$mean - test_ts)^2,
    na.rm = TRUE
  )
)

mape_sarima <- mean(
  abs(
    (test_ts - forecast_sarima$mean) / test_ts
  ),
  na.rm = TRUE
) * 100

cat("MAE SARIMA:", mae_sarima, "\n")
## MAE SARIMA: 3.988028
cat("RMSE SARIMA:", rmse_sarima, "\n")
## RMSE SARIMA: 4.881106
cat("MAPE SARIMA:", mape_sarima, "%\n")
## MAPE SARIMA: 7.175246 %

#Interpretación: El modelo SARIMA presenta un menor error de pronóstico en comparación con el modelo ARIMA en las tres métricas evaluadas. El MAE disminuye de 5,88 a 3,99, el RMSE de 6,92 a 4,88 y el MAPE de 10,71 % a 7,18 %. Estos resultados indican que, para el período de prueba correspondiente a 2025, el SARIMA logró aproximarse mejor a los valores observados de la ocupación hotelera.

#Pronostico sarima para el mismo periodo de prueba:

# Pronóstico del conjunto de prueba con SARIMA

forecast_sarima <- forecast(
  auto_sarima_model,
  h = length(test_ts)
)

# Crear tabla de resultados
forecast_table_sarima <- data.frame(
  Tiempo = time(test_ts),
  Observado = as.numeric(test_ts),
  Pronosticado = as.numeric(forecast_sarima$mean)
)

forecast_table_sarima
Tiempo Observado Pronosticado
2025.000 45.36 48.90827
2025.083 49.92 52.74584
2025.167 47.45 53.20077
2025.250 48.01 52.23703
2025.333 51.82 51.75284
2025.417 55.48 51.43674
2025.500 61.00 52.52566
2025.583 60.63 54.85555
2025.667 54.25 53.60887
2025.750 65.94 56.60018
2025.833 60.33 58.41112
2025.917 53.33 54.57540

#Tabla final de comparación:

# Comparación de desempeño predictivo

tabla_metricas <- data.frame(
  Modelo = c(
    "ARIMA automático",
    "SARIMA automático"
  ),
  
  MAE = c(
    mae_arima,
    mae_sarima
  ),
  
  RMSE = c(
    rmse_arima,
    rmse_sarima
  ),
  
  MAPE = c(
    mape_arima,
    mape_sarima
  )
)

tabla_metricas
Modelo MAE RMSE MAPE
ARIMA automático 5.884624 6.921151 10.707422
SARIMA automático 3.988028 4.881106 7.175246

#Interpretación: Al comparar las métricas de error para el período de prueba de 2025, el modelo SARIMA automático presenta menores valores de MAE, RMSE y MAPE que el modelo ARIMA automático. En particular, el MAPE del SARIMA es de 7,18 %, frente a 10,71 % del ARIMA. Esto indica que el SARIMA presentó un menor error de pronóstico durante el período evaluado y, por tanto, muestra una mejor capacidad predictiva para la ocupación hotelera de Cali.

#Gráfico comparativo:

# Crear dataframe para comparar los pronósticos

comparacion_pronosticos <- data.frame(
  Tiempo = time(test_ts),
  Observado = as.numeric(test_ts),
  ARIMA = as.numeric(forecast_arima_auto$mean),
  SARIMA = as.numeric(forecast_sarima$mean)
)

# Gráfico

grafico_comparacion <- ggplot(
  comparacion_pronosticos,
  aes(x = Tiempo)
) +
  geom_line(
    aes(y = Observado, color = "Observado")
  ) +
  geom_line(
    aes(y = ARIMA, color = "ARIMA")
  ) +
  geom_line(
    aes(y = SARIMA, color = "SARIMA")
  ) +
  ggtitle(
    "Ocupación hotelera de Cali: comparación de pronósticos"
  ) +
  xlab("Tiempo") +
  ylab("Ocupación hotelera (%)") +
  theme_minimal()

ggplotly(grafico_comparacion)

#Interpretación: El gráfico muestra que el modelo SARIMA sigue de manera más cercana las fluctuaciones observadas de la ocupación hotelera durante 2025, mientras que el ARIMA presenta pronósticos más estables alrededor del nivel medio de la serie. Este comportamiento es consistente con las métricas de error obtenidas, en las cuales el SARIMA presenta menores valores de MAE, RMSE y MAPE, mostrando un mejor desempeño predictivo durante el período de prueba.

#Validación Cruzada:

# Validación cruzada temporal para ARIMA

e_arima <- tsCV(
  train_ts,
  forecastfunction = function(y, h) {
    forecast(
      auto.arima(y, seasonal = FALSE),
      h = h
    )
  },
  h = 1
)

rmse_cv_arima <- sqrt(
  mean(
    e_arima^2,
    na.rm = TRUE
  )
)

mae_cv_arima <- mean(
  abs(e_arima),
  na.rm = TRUE
)

cat("RMSE validación cruzada ARIMA:", rmse_cv_arima, "\n")
## RMSE validación cruzada ARIMA: 7.5139
cat("MAE validación cruzada ARIMA:", mae_cv_arima, "\n")
## MAE validación cruzada ARIMA: 5.509005
# Validación cruzada temporal para SARIMA

e_sarima <- tsCV(
  train_ts,
  forecastfunction = function(y, h) {
    
    modelo_cv <- Arima(
      y,
      order = c(1, 0, 0),
      seasonal = list(
        order = c(2, 0, 0),
        period = 12
      ),
      include.mean = TRUE
    )
    
    forecast(
      modelo_cv,
      h = h
    )
  },
  h = 1
)

rmse_cv_sarima <- sqrt(
  mean(
    e_sarima^2,
    na.rm = TRUE
  )
)

mae_cv_sarima <- mean(
  abs(e_sarima),
  na.rm = TRUE
)

cat(
  "RMSE validacion cruzada SARIMA:",
  rmse_cv_sarima,
  "\n"
)
## RMSE validacion cruzada SARIMA: 6.843343
cat(
  "MAE validacion cruzada SARIMA:",
  mae_cv_sarima,
  "\n"
)
## MAE validacion cruzada SARIMA: 4.476364

#Interpretación: a validación cruzada muestra que el modelo SARIMA presenta menores errores que el ARIMA, con un RMSE de 6,99 frente a 7,51, y un MAE de 4,47 frente a 5,51. Esto indica que, bajo el procedimiento de validación cruzada aplicado, el SARIMA presenta un menor error promedio de pronóstico y mantiene un mejor desempeño predictivo que el ARIMA.

#Selección del modelo final: #A partir de la comparación de los modelos estimados, se selecciona el modelo SARIMA(1,0,0)(2,0,0)[12]. Este modelo presentó menores valores de AIC y BIC respecto al ARIMA automático. Asimismo, durante el período de prueba de 2025 obtuvo menores valores de MAE, RMSE y MAPE. La validación cruzada también mostró menores errores de pronóstico para el SARIMA. Adicionalmente, el diagnóstico de residuos mostró una reducción de la autocorrelación remanente. En conjunto, estos resultados sustentan la utilización del modelo SARIMA para realizar el pronóstico final.

#Reestimar el Sarima:

serie_pronostico
##            Jan       Feb       Mar       Apr       May       Jun       Jul
## 2012 40.984148 48.163945 52.751647 46.186024 51.656806 50.498865 50.687476
## 2013 38.086361 51.665945 46.410769 54.389457 56.751197 55.800285 63.027240
## 2014 44.333605 52.902421 51.557234 50.734539 53.464851 47.137093 52.576386
## 2015 44.724933 49.953606 49.744313 49.554234 54.826536 58.593627 65.146502
## 2016 49.154764 58.314705 52.380638 55.823001 54.776938 55.320560 52.846760
## 2017 45.069758 62.273459 59.861433 56.527333 52.612756 53.991888 54.144508
## 2018 46.893462 58.005900 53.450816 57.588292 52.494087 55.418636 56.674943
## 2019 48.658704 61.509657 56.973252 50.175596 57.697959 57.352878 58.098882
## 2020 49.179432 55.608367 29.654494  3.380544  4.055782  4.283978  8.207688
## 2021 20.068146 25.373495 32.348885 28.251748 18.982892 27.704024 35.673503
## 2022 40.481477 53.547676 59.027372 55.387065 59.723427 54.786626 71.830717
## 2023 52.373911 54.886085 57.563905 54.693217 55.658694 54.134706 57.715428
## 2024 42.610000 53.480000 52.550000 51.640000 49.010000 49.170000 49.680000
## 2025 45.360000 49.920000 47.450000 48.010000 51.820000 55.480000 61.000000
##            Aug       Sep       Oct       Nov       Dec
## 2012 52.192862 57.394377 60.205655 58.180522 48.398649
## 2013 59.284782 55.818442 60.448391 58.622399 54.725298
## 2014 56.396331 54.141024 59.202058 59.872495 52.288622
## 2015 59.362884 67.055408 66.936527 67.067612 58.769211
## 2016 59.828018 70.739118 59.643952 67.395772 53.674790
## 2017 60.167547 54.016639 62.693815 62.530258 55.059444
## 2018 55.827297 61.863534 58.866459 62.879937 56.430991
## 2019 61.179771 61.151650 61.702467 62.644918 56.036853
## 2020  6.784319 13.733728 22.558021 30.792839 28.038383
## 2021 45.312803 49.834545 51.910932 65.583885 60.928307
## 2022 69.124634 66.829581 65.504159 66.671055 60.354868
## 2023 58.952883 55.987835 55.804281 67.270734 58.711385
## 2024 56.550000 54.800000 65.222412 61.291183 55.568770
## 2025 60.630000 54.250000 65.940000 60.330000 53.330000
# Reestimación del modelo SARIMA seleccionado
# utilizando toda la información disponible hasta diciembre de 2025

modelo_final_sarima <- Arima(
  serie_pronostico,
  order = c(1, 0, 0),
  seasonal = list(
    order = c(2, 0, 0),
    period = 12
  ),
  include.mean = TRUE
)

# Mostrar los resultados del modelo final
summary(modelo_final_sarima)
## Series: serie_pronostico 
## ARIMA(1,0,0)(2,0,0)[12] with non-zero mean 
## 
## Coefficients:
##          ar1    sar1    sar2     mean
##       0.8873  0.3167  0.2422  51.8501
## s.e.  0.0339  0.0731  0.0779   7.9681
## 
## sigma^2 = 36.51:  log likelihood = -541.29
## AIC=1092.58   AICc=1092.95   BIC=1108.2
## 
## Training set error measures:
##                      ME     RMSE      MAE      MPE     MAPE      MASE
## Training set 0.08246178 5.969684 4.366633 -7.53726 15.81915 0.4409632
##                     ACF1
## Training set -0.04449139

#Para la parte estacional:

seasonal = list(
  order = c(2,0,0),
  period = 12
)
# Diagnóstico de residuos del modelo SARIMA final

checkresiduals(modelo_final_sarima)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,0,0)(2,0,0)[12] with non-zero mean
## Q* = 25.162, df = 21, p-value = 0.2402
## 
## Model df: 3.   Total lags used: 24

#Interpretación: El modelo SARIMA(1,0,0)(2,0,0)[12] fue reestimado utilizando toda la información disponible hasta diciembre de 2025. La prueba de Ljung-Box presenta un p-value de 0,2402, superior al nivel de significancia del 5 %, por lo que no se rechaza la hipótesis nula de ausencia de autocorrelación en los residuos. Además, la mayoría de las autocorrelaciones se encuentran dentro de las bandas de confianza. En consecuencia, los residuos presentan un comportamiento compatible con ruido blanco y el modelo resulta adecuado para realizar el pronóstico.

# Pronóstico final de enero a marzo de 2026

pronostico_final <- forecast(
  modelo_final_sarima,
  h = 3
)

# Mostrar el pronóstico
pronostico_final
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## Jan 2026       46.35081 38.60762 54.09400 34.50862 58.19300
## Feb 2026       50.56332 40.21124 60.91540 34.73118 66.39546
## Mar 2026       49.67653 37.66253 61.69053 31.30270 68.05035

#Interpretación: El modelo SARIMA(1,0,0)(2,0,0)[12], estimado con la información disponible hasta diciembre de 2025, proyecta una ocupación hotelera de 46,35 % para enero de 2026, 50,56 % para febrero y 49,68 % para marzo. Los resultados muestran un aumento de la ocupación entre enero y febrero, seguido de una leve disminución en marzo. Los intervalos de predicción muestran que existe incertidumbre alrededor de las estimaciones puntuales, siendo esta mayor para horizontes de pronóstico más alejados.

# Tabla del pronóstico final

tabla_pronostico_final <- data.frame(
  
  Mes = c(
    "Enero 2026",
    "Febrero 2026",
    "Marzo 2026"
  ),
  
  Pronostico = as.numeric(
    pronostico_final$mean
  ),
  
  LI_80 = as.numeric(
    pronostico_final$lower[, 1]
  ),
  
  LS_80 = as.numeric(
    pronostico_final$upper[, 1]
  ),
  
  LI_95 = as.numeric(
    pronostico_final$lower[, 2]
  ),
  
  LS_95 = as.numeric(
    pronostico_final$upper[, 2]
  )
)

tabla_pronostico_final
Mes Pronostico LI_80 LS_80 LI_95 LS_95
Enero 2026 46.35081 38.60762 54.09400 34.50862 58.19300
Febrero 2026 50.56332 40.21124 60.91540 34.73118 66.39546
Marzo 2026 49.67653 37.66253 61.69053 31.30270 68.05035
# Grafico del pronostico SARIMA frente a los valores observados de 2025

pronostico_sarima_2025 <- forecast(
  auto_sarima_model,
  h = length(test_ts)
)

datos_grafico_sarima <- data.frame(
  Tiempo = as.numeric(time(test_ts)),
  Pronostico = as.numeric(pronostico_sarima_2025$mean),
  Observado = as.numeric(test_ts)
)

grafico_sarima <- ggplot(
  datos_grafico_sarima,
  aes(x = Tiempo)
) +
  geom_line(
    aes(y = Pronostico, color = "Pronostico"),
    linewidth = 0.8
  ) +
  geom_line(
    aes(y = Observado, color = "Observado"),
    linewidth = 0.8
  ) +
  labs(
    title = "Pronostico vs observado de la ocupacion hotelera de Cali - 2025",
    x = "Tiempo",
    y = "Ocupacion hotelera (%)",
    color = ""
  ) +
  theme_minimal()

ggplotly(grafico_sarima)

#Interpretación: La gráfica compara los valores observados de la ocupación hotelera de Cali durante 2025 con los pronósticos generados por el modelo SARIMA. Se observa que el modelo reproduce parcialmente la dinámica de la serie y sigue su tendencia general, aunque presenta mayores diferencias durante algunos períodos de cambios pronunciados en la ocupación. Este comportamiento es consistente con las métricas de error obtenidas para el período de prueba.

#Recomendaciones: A partir del pronóstico, se recomienda que la junta directiva ajuste la planificación operativa y comercial del hotel a la demanda esperada. En particular, enero presenta una ocupación proyectada de 46,35 %, mientras que febrero alcanza 50,56 % y marzo 49,68 %, por lo que podrían implementarse estrategias comerciales para estimular la demanda en los meses de menor ocupación y aprovechar los períodos de mayor demanda. Asimismo, debido a la incertidumbre asociada a las proyecciones, se recomienda trabajar con diferentes escenarios de ocupación y realizar un seguimiento periódico de indicadores como ocupación, reservas, tarifa promedio e ingresos por habitación. Esto permitiría ajustar las decisiones conforme se disponga de nueva información.

#Conclusión: El análisis de la ocupación hotelera de Cali permitió identificar un comportamiento temporal con una componente estacional anual, por lo que se evaluaron modelos ARIMA y SARIMA. A partir de los criterios de información, el diagnóstico de residuos y la evaluación de la capacidad predictiva, se seleccionó el modelo SARIMA(1,0,0)(2,0,0)[12]. Este modelo presentó menores errores de pronóstico frente al ARIMA, con un MAE de 3,99, un RMSE de 4,88 y un MAPE de 7,18 % en el período de prueba de 2025. Asimismo, la validación cruzada mostró un mejor desempeño del SARIMA, y la prueba de Ljung-Box del modelo final no evidenció autocorrelación significativa en los residuos (p = 0,2402). Finalmente, utilizando toda la información disponible hasta diciembre de 2025, el modelo proyectó una ocupación hotelera de 46,35 % para enero, 50,56 % para febrero y 49,68 % para marzo de 2026. Estos resultados proporcionan una estimación de corto plazo de la dinámica esperada de la ocupación hotelera, teniendo en cuenta los intervalos de predicción asociados a cada pronóstico.