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.
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/user/Downloads/Base Caso1 (1).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)
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
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 identificó 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.
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 pronóstico: 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)
# 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)
# 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 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.
# 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.
# 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.
# 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.
# 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 |
# 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.
# 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 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.
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.
A partir de los resultados obtenidos, se proponen las siguientes recomendaciones para la junta directiva del hotel:
1. Ajustar la planificación operativa:
Adaptar la asignación de personal, inventarios y recursos a la demanda
esperada, considerando que la ocupación proyectada es de 46,35 %
en enero, 50,56 % en febrero y 49,68 % en marzo de 2026.
2. Fortalecer las estrategias comerciales:
Implementar promociones, paquetes y estrategias de captación de demanda
durante los períodos de menor ocupación, especialmente en enero.
3. Aprovechar los períodos de mayor demanda:
Utilizar la mayor ocupación proyectada para febrero como referencia para
fortalecer la gestión de tarifas y la venta de servicios
complementarios.
4. Trabajar con escenarios de demanda:
Considerar escenarios de ocupación baja, esperada y alta debido a la
incertidumbre asociada a los intervalos de predicción. El pronóstico
debe utilizarse como una herramienta de apoyo y no como un valor
cierto.
5. Realizar seguimiento periódico:
Monitorear la ocupación real frente a la proyectada, las reservas, la
tarifa promedio, los ingresos por habitación y las cancelaciones, con el
fin de ajustar las decisiones conforme se disponga de nueva
informació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]. En el período de prueba de 2025, este modelo presentó un MAE de 3,99, un RMSE de 4,88 y un MAPE de 7,18 %, además de un mejor desempeño en la validación cruzada frente al modelo ARIMA.
Asimismo, la prueba de Ljung-Box del modelo final presentó un p-value de 0,2402, por lo que no se evidenció autocorrelación significativa en los residuos.
Finalmente, utilizando la información disponible hasta diciembre de 2025, el modelo proyectó una ocupación de 46,35 % para enero, 50,56 % para febrero y 49,68 % para marzo de 2026. Estas proyecciones permiten apoyar decisiones de planificación operativa y comercial, considerando siempre la incertidumbre asociada a los intervalos de predicción.
Departamento Administrativo Nacional de Estadística (DANE). (2026). Cuenta Satélite de Turismo (CST): Información 2024 provisional y 2025 preliminar. DANE – Cuenta Satélite de Turismo Departamento Administrativo Nacional de Estadística (DANE). (2026). Servicios: Turismo. DANE – Estadísticas de turismo Alcaldía de Santiago de Cali. Secretaría de Turismo. (2025, 10 de enero). Más de 3 millones de visitantes llegaron a Cali durante el 2024. Alcaldía de Cali – Más de 3 millones de visitantes llegaron a Cali durante el 2024 InterContinental Hotels Group (IHG). (2026). InterContinental Cali: Hotel de lujo en Cali. InterContinental Cali – sitio oficial