1. Introducción

Para nadie es un secreto que Colombia debido a su ubicación geográfica en una zona ecuatorial, no experimenta estaciones como la gran mayoría de los otros países del mundo, por lo que esto convierte a Colombia en un país con clima heterogeneo. Según El portal web de ‘Ecoglobal Expeditions’ indica que, el régimen de estaciones en Colombia es bimodal y en casi todo el territorio se presentan dos estaciones, las cuales son de lluvia y dos períodos de verano, donde la irregularidad climática y los cambios en las condiciones atmosféricas adquieren cada vez mayor relevancia para la planificación urbana, la gestión ambiental y la toma de decisiones, resulta fundamental comprender el comportamiento de variables meteorológicas como la temperatura. Esta variable no solo influye en fenómenos ambientales y ecosistémicos, sino que también tiene implicaciones sobre actividades económicas, el consumo energético, la salud pública y la calidad de vida de la población. En santiago de Cali, distrito de colombia y capital del Valle del Cauca, es caracterizada por condiciones climáticas particulares derivadas de su ubicación geográfica y relieve, el estudio de la temperatura permite identificar patrones temporales que contribuyen a una mejor comprensión de su dinámica climática.

A partir de este contexto surge la siguiente pregunta de investigación: ¿es posible modelar y pronosticar el comportamiento de la temperatura en Cali a partir de los registros históricos disponibles del año 2018, identificando los patrones temporales que explican su evolución a lo largo del tiempo?

Con el objetivo de poder responder esta pregunta, se hace uso de un enfoque de análisis de series temporales mediante la metodología ARIMA (AutoRegressive Integrated Moving Average). Esta técnica permite estudiar la dependencia temporal presente en los datos, identificar componentes autorregresivos y de medias móviles, así como transformar la serie cuando es necesario para garantizar condiciones de estacionariedad. De esta manera, es posible construir modelos capaces de representar adecuadamente la dinámica observada y generar pronósticos sobre valores futuros de la variable.

El análisis se desarrolla a partir de registros horarios de temperatura obtenidos para la ciudad de Cali, los cuales constituyen una serie temporal de alta frecuencia que permite observar fluctuaciones, tendencias y posibles patrones recurrentes en el comportamiento de la variable. En primer lugar, se realiza un análisis descriptivo de los datos para caracterizar la serie y evaluar sus principales propiedades estadísticas. Una vez finalizado, se aplican herramientas gráficas y pruebas de diagnóstico que permiten determinar la necesidad de transformaciones y seleccionar la estructura más adecuada del modelo ARIMA.

Por medio de este informe se busca no solo obtener un modelo estadísticamente válido para el pronóstico de la temperatura, sino también comprender los patrones temporales que gobiernan su comportamiento. Los resultados permiten evidenciar la utilidad de los modelos de series de tiempo como herramientas para el análisis climático y la generación de información que puede servir como apoyo en procesos de planificación, monitoreo ambiental y toma de decisiones basadas en evidencia.

1.1 Contexto

El monitoreo y la predicción del clima, especialmente de la temperatura, juegan un papel muy importante en la planeación de las ciudades, el consumo de energía, la salud pública y el trabajo de las industrias. En una ciudad con los cambios de clima y la ubicación comun de Cali, las variaciones del calor no solo afectan la comodidad de las personas, sino que también impactan directamente la demanda de energía eléctrica (debido al uso de aires acondicionados y sistemas de refrigeración) y las actividades de los diferentes sectores productivos.

Para analizar estos cambios de manera estratégica, la ciencia de datos y la estadística ofrecen herramientas como el análisis de series de tiempo. Estas metodologías permiten tomar los registros históricos guardados en orden cronológico y transformarlos en modelos matemáticos capaces de encontrar patrones ocultos, tendencias y comportamientos que se repiten por temporadas en el clima de la región.

1.2 El Problema a Modelar

El comportamiento de la temperatura cambia a cada instante de forma drástica, pero guarda una relación sumamente estrecha con su propio pasado; lo que ocurre en las horas previas marca de manera directa la tendencia térmica de las horas siguientes, generando una inercia climática natural. El verdadero reto científico y operativo al trabajar con estos datos ambientales es que los análisis básicos tradicionales, como calcular promedios simples o modas mensuales, no son capaces de descubrir ni de explicar cómo se transmite ese “efecto memoria” a lo largo de las jornadas. Además, al recolectar mediciones de forma masiva hora por hora, las gráficas originales tienden a saturarse visualmente por completo debido a la enorme densidad de puntos, lo que termina ocultando patrones valiosos e incrementando el riesgo de que aparezcan ruidos extraños, fallas instrumentales en los sensores de climatización y vacíos de información. Todo esto hace indispensable realizar un proceso riguroso de depuración y auditoría antes de intentar trazar cualquier modelo matemático estable.

Por lo tanto, el problema central a resolver en este informe consiste en descifrar, estructurar y modelar el comportamiento real de la temperatura en la ciudad de Cali a partir de sus registros históricos acumulados. Siguiendo de forma estricta los pasos de la metodología Box-Jenkins (enfoque ARIMA), el estudio se enfocará en evaluar matemáticamente si el clima de la región se mantiene estable en el tiempo en cuanto a su promedio general, identificará cuántas horas hacia atrás impactan directamente en el presente analizando las gráficas de autocorrelación simple y parcial, y contrastará distintas configuraciones para elegir la arquitectura más eficiente según sus penalizaciones de error. Al final, tras auditar a fondo que las fallas del modelo seleccionado sean puramente aleatorias y libres de patrones ocultos, se generará una proyección dinámica para las próximas 24 horas, entregando una herramienta práctica y confiable que sirva para anticipar picos de calor extremos, optimizar la planeación energética urbana y facilitar la toma de decisiones en la región.

2. Metodología

2.1 Descripción de Variables

Para el desarrollo de este estudio se requiere únicamente un conjunto de datos históricos enfocado en el comportamiento térmico regional. La estructura de la información necesaria para el análisis está compuesta exclusivamente por las siguientes variables:

Fecha y Hora: Es la variable de indexación temporal. Corresponde a un registro cuantitativo de tipo cronológico que captura el momento exacto con año, mes, día, hora y minutos en el que se realizó cada medición climática. Esta variable funciona como el soporte fundamental para estructurar el objeto de serie de tiempo, asegurando que las observaciones mantengan una secuencia ordenada y equidistante.

Temperatura: Es la variable objeto de estudio que actúa como la variable de respuesta o dependiente. Es una variable cuantitativa continua que registra la temperatura ambiente medida en grados Celsius en la ciudad de Cali. Al ser una serie temporal, el análisis se centra en evaluar cómo esta variable se comporta en función de sus propios valores pasados.

La delimitación metodológica a estas dos variables se encuentra estrictamente justificada por los principios teóricos del enfoque Box Jenkins. Los modelos de tipo ARIMA poseen una naturaleza matemática univariada, lo que significa que el sistema se modela bajo el supuesto de que la variable es capaz de explicarse a sí misma mediante su propia historia. Por lo tanto, el diseño del algoritmo no requiere ni utiliza información exógena como la velocidad del viento, la radiación solar o la humedad relativa para estimar los escenarios futuros. Toda la inercia termodinámica, los patrones cíclicos horarios y las fluctuaciones de la temperatura en la región quedan absorbidos de manera eficiente dentro de la estructura de dependencia lineal, calculando las predicciones finales a partir de los rezagos históricos y la memoria de los errores pasados.

2.2 Descripción del Modelo Utilizado

El análisis predictivo de este estudio encuentra su sustento técnico en la metodología Box Jenkins mediante el uso de modelos autorregresivos integrados de media móvil, una herramienta ampliamente conocida en el ámbito estadístico como modelos ARIMA. Elegir este enfoque es ideal cuando se trabaja con series de tiempo univariadas, ya que tiene la enorme ventaja de entender y modelar el comportamiento de una variable basándose únicamente en su propia inercia histórica y en su estructura de dependencia lineal, lo que hace innecesario el uso de variables explicativas externas.La estructura interna de cualquier modelo ARIMA se define a partir de tres parámetros fundamentales que interactúan entre sí y que se identifican de forma universal con las letras \(p\), \(d\) y \(q\).

El componente autorregresivo, representado por la letra \(p\), analiza la relación directa que existe entre lo que ocurre en el momento actual y un número determinado de registros pasados a los que llamamos rezagos.Su lógica es muy intuitiva, ya que asume que el pasado inmediato tiene un peso real y condiciona el comportamiento del presente.

El componente integrado, asociado a la letra \(d\), representa el orden de diferenciación que necesita la serie original para corregir tendencias y transformarse en una serie estacionaria, asegurando así que tanto su media como su varianza se mantengan estables a lo largo del tiempo. En términos prácticos, esta transformación se logra restando el valor del registro actual menos el valor del periodo inmediatamente anterior.

El componente de media móvil, vinculado a la letra \(q\), se encarga de medir la dependencia entre la observación del presente y los errores o shocks aleatorios del pasado. Su papel es clave dentro del modelo porque ayuda a absorber y suavizar el impacto de variaciones imprevistas o ruidos extraños en el corto plazo. Para llevar esta teoría a la práctica dentro del código desarrollado, el proceso se divide en cuatro etapas analíticas que se ejecutan de manera secuencial: Durante la etapa de identificación, nos enfocamos en verificar si la serie limpia es estacionaria, recurriendo a la rigurosidad matemática de la prueba estadística de raíz unitaria de Dickey Fuller aumentado y al análisis visual de las funciones de autocorrelación simple y parcial.En la fase de estimación y comparación, planteamos de forma manual 5 combinaciones diferentes de modelos fijando un orden de integración igual a 1, y cruzamos estos resultados con el algoritmo de selección automática. Para elegir el modelo definitivo nos guiamos por el principio de parsimonia, buscando un equilibrio óptimo donde el modelo sea lo más simple posible pero con un excelente ajuste, guiándonos por los valores más bajos en los criterios de información de Akaike y Bayesiano.En la etapa de diagnóstico, realizamos una auditoría a fondo de los residuos del modelo que seleccionamos previamente para comprobar que se comporten como ruido blanco. Esto es indispensable para garantizar que los errores sean totalmente independientes entre sí, que no estén autocorrelacionados y que sigan una distribución normal.En la última etapa, dedicada por completo al pronóstico y con la seguridad de tener un modelo validado, generamos la proyección matemática de la variable para un horizonte futuro de 24 horas, incluyendo márgenes de confianza estadística al 80% y 95% para medir con precisión el nivel de incertidumbre en las predicciones.

3. Resultados Descriptivos

3.1 Carga e Inspección de la Estructura de Datos

En esta primera etapa se realiza la lectura del conjunto de datos para hacer una revisión básica de su tamaño y del tipo de información que contiene. Esto nos permite comprobar que los datos estén bien organizados y tengan el formato correcto antes de hacer cualquier cálculo o análisis a el modelo.

library(readxl)
library(knitr)


datos <- read_excel("Compartir2.xlsx")


kable(data.frame(Variables = names(datos)), 
      caption = "Variables identificadas en la base de datos")
Variables identificadas en la base de datos
Variables
Fecha & Hora
O3 (ug/m3)
Vel Viento (m/s)
Dir Viento (Grados)
Temperatura (C°)
Humedad (%)
Radiacion Solar (Watt/M2)
Lluvia (mm)

Aunque la base de datos contiene múltiples variables ambientales como el ozono, la velocidad y dirección del viento, la humedad, la radiación solar y la lluvia, para este análisis se seleccionan únicamente dos de ellas: la fecha junto con la hora y la temperatura.La razón principal es que el modelo ARIMA que vamos a construir es de naturaleza univariada. Esto significa que está diseñado matemáticamente para estudiar y predecir una sola variable tomando como base únicamente su propio comportamiento y su inercia a lo largo del tiempo.Se elige la temperatura como la variable central del estudio porque el objetivo principal es entender y proyectar el comportamiento térmico regional. Bajo este enfoque univariado, no hace falta incluir los demás factores climáticos externos, ya que toda la influencia del entorno queda absorbida y reflejada directamente en el histórico de la propia temperatura. El registro temporal de fecha y hora sirve entonces como el soporte indispensable para organizar estas mediciones en una secuencia ordenada y constante.

3.2 Comportamiento visual y evolución de la Serie histórica

Antes de hacer cualquier cálculo matemático o entrenar el modelo, es necesario armar la serie de tiempo y graficarla en una pantalla interactiva. Ver los datos de esta manera nos sirve para entender cómo cambia la temperatura en la vida real y analizar la calidad de la información de todo el año estudiado.

Temperatura <- xts(
  datos$`Temperatura (C°)`, 
  order.by = datos$`Fecha & Hora`
)

g <- ggplot(datos, aes(x = `Fecha & Hora`, y = `Temperatura (C°)`)) +
  geom_line(color = "darkcyan") +
  labs(title = "Temperatura a lo largo del tiempo", x = "Fecha & Hora", y = "Temperatura (C°)") +
  theme_minimal()

ggplotly(g)

Al observar detalladamente la gráfica de la serie original, se confirman visualmente las alertas del diagnóstico estadístico. En primer lugar, se hace evidente un vacío completo en las mediciones que ocurre entre los meses de febrero y abril aproximadamente. En segundo lugar, resalta una caída extrema y aislada a mitad de año, donde el registro térmico disminuye drásticamente hasta tocar los \(20\) grados, un comportamiento que no coincide con la tendencia regular de la región y que apunta a ser un valor atípico por posibles fallas en los sensores de medición.

3.3 Análisis descriptivo de los registros

Tabla de medidas de tendencia central y de dispersión.

Para entender a fondo el comportamiento de la temperatura antes de avanzar hacia el pronóstico, se extrajeron los indicadores numéricos clave de la serie limpia. Más allá de una simple lista de datos, estas métricas revelan la estructura interna del clima y aportan los fundamentos matemáticos necesarios para asegurar que el modelo sea confiable.

library(psych)
library(knitr)

Temperatura2 <- na.omit(Temperatura)
estadisticos <- describe(as.numeric(Temperatura2))

mean_val  <- round(estadisticos$mean, 2)
sd_val    <- round(estadisticos$sd, 2)
med_val   <- round(estadisticos$median, 2)
min_val   <- round(estadisticos$min, 2)
max_val   <- round(estadisticos$max, 2)
rango_val <- round(estadisticos$range, 2)
skew_val  <- round(estadisticos$skew, 2)
kurt_val  <- round(estadisticos$kurtosis, 2)

tabla_descriptiva <- data.frame(
  Estadístico = c("Media Aritmética", "Desviación Estándar", "Mediana", "Valor Mínimo", "Valor Máximo", "Rango Absoluto", "Asimetría", "Curtosis"),
  Valor = c(mean_val, sd_val, med_val, min_val, max_val, rango_val, skew_val, kurt_val)
)

kable(tabla_descriptiva, 
      caption = "Estadísticos Descriptivos de la Temperatura",
      align = c("l", "c"))
Estadísticos Descriptivos de la Temperatura
Estadístico Valor
Media Aritmética 28.28
Desviación Estándar 3.64
Mediana 27.30
Valor Mínimo 19.90
Valor Máximo 38.50
Rango Absoluto 18.60
Asimetría 0.45
Curtosis -0.96

Al examinar los resultados, se observa que la media aritmética se ubica en 28.28°C y la mediana en 27.30°C. Al ser valores tan cercanos entre sí, nos indican que los datos se distribuyen de forma bastante simétrica, representando el punto de equilibrio térmico de la región. En el ámbito del modelado ARIMA, esta estabilidad es una gran ventaja inicial porque fundamenta el principio de estacionariedad en media, lo que significa que el promedio no sufre variaciones drásticas a lo largo del tiempo.

Esta tendencia hacia la simetría se confirma al analizar el valor de asimetría de 0.45 y la curtosis de -0.96. Ambos indicadores muestran que el comportamiento probabilístico de la serie se aproxima de manera segura a una distribución normal. Esto es fundamental para el éxito del proyecto, ya que garantiza que los cálculos del modelo se realicen sobre la tendencia masiva regular de la temperatura, facilitando que los errores de las predicciones futuras se comporten como un ruido blanco limpio y sin patrones ocultos.

Por otro lado, la volatilidad y los límites del clima quedan definidos por la desviación estándar de 3.64°C y el rango absoluto de 18.60°C. Estos números nos muestran qué tanto puede variar el clima del día a día, registrando un valor mínimo histórico de 19.90°C y un máximo de 38.50°C. Conocer estos extremos ayuda a delimitar los escenarios más críticos de demanda energética o picos térmicos en la zona. Mantener esta dispersión histórica bajo control permite calibrar los márgenes de tolerancia en los sistemas y valida el supuesto de homocedasticidad, asegurando que las bandas de confianza de nuestro pronóstico futuro sean completamente estables y seguras.

Gráfico de Líneas

plot_ly(
  x = datos$`Fecha & Hora`,
  y = datos$`Temperatura (C°)`,
  type = "scatter",
  mode = "lines",
  line = list(color = "darkcyan")
) |>
  layout(
    title = "Temperatura en Cali",
    xaxis = list(title = "Fecha"),
    yaxis = list(title = "Temperatura (°C)")
  )

Al rastrear secuencialmente cada medición cronológica, la representación gráfica permite constatar que la serie oscila con una regularidad constante y de forma homogénea alrededor de una franja central muy cercana a los 28.28°C. El hecho de que los valores no muestren una inclinación sostenida al alza o a la baja a lo largo de los meses confirma la ausencia de tendencias determinísticas a largo plazo, lo que funciona como un fuerte indicio visual de estacionariedad en media. Asimismo, la alta densidad y el comportamiento de vaivén constante en la gráfica reflejan la existencia de patrones cíclicos y horarios repetitivos vinculados a las variaciones térmicas entre el día y la noche, manteniendo límites estables que facilitarán la captura de la memoria lineal por parte del modelo predictivo.

Histograma de Frecuencias:

# Histograma
plot_ly(
  x = datos$`Temperatura (C°)`,
  type = "histogram",
  nbinsx = 20,
  opacity = 0.8,
  marker = list(
    color = "darkcyan",
    line = list(color = "black", width = 1)
  )
)

Al observar la forma del histograma, se confirma visualmente la alta acumulación de registros en torno a la mediana de 27.30°C, concentrando la mayor parte de los datos en el rango que va desde los 24°C hasta los 27°C. Esta distribución permite verificar de manera directa el grado de simetría de la serie, mostrando un ligero sesgo hacia la derecha que coincide perfectamente con el valor de asimetría positivo calculado previamente. Asimismo, la estructura del gráfico revela un comportamiento bimodal sutil, con un segundo pico de menor intensidad cerca de los 32°C, lo cual refleja las transiciones naturales entre los periodos más frescos y las horas del día con mayor radiación solar. Esta disposición de los datos es clave para el proceso de modelado, ya que valida visualmente que la variable no presenta dispersiones caóticas o descontroladas, sino que se agrupa de forma estable y predecible, facilitando que el modelo predictivo asimile la tendencia masiva del clima de la región.

Diagrama de Caja (Boxplot):

# Boxplot
plot_ly(
  y = datos$`Temperatura (C°)`,
  type = "box",
  fillcolor = "darkcyan",
  line = list(color = "black")
) |>
  layout(
    title = "Boxplot de la temperatura",
    yaxis = list(title = "Temperatura (°C)")
  )

Al observar el cuerpo principal de la caja, se evidencia que el 50% central de las mediciones se encuentra concentrado de manera muy estable y agrupada entre los 25.30°C y los 31.40°C aproximadamente. La línea interna, que marca la mediana, divide el rectóngulo mostrando visualmente cómo se distribuye el grueso de los registros sin inclinaciones drásticas, soportando la consistencia interna detectada en los análisis estadísticos previos.

Por otra parte, la extensión de los bigotes del gráfico resulta fundamental para validar la calidad de la información meteorológica. Los límites superior e inferior se extienden limpiamente hasta alcanzar los valores de 38.50°C y 19.90°C sin dejar puntos aislados flotando por fuera de las líneas transversales. Esta estructura permite confirmar de forma visual que, a pesar de las fuertes oscilaciones térmicas del conjunto de datos, no existen valores atípicos severos o errores de digitación remanentes que actúen como anomalías aisladas. De este modo, se descarta la presencia de ruidos externos capaces de sesgar las estimaciones, garantizando que el modelo predictivo procesará un comportamiento climático natural y altamente confiable.

4. Resultados del Modelo

4.1 Depuración de la Serie y Análisis de Estacionariedad

El punto de partida para garantizar la viabilidad del modelado predictivo consistió en auditar la calidad de la información meteorológica disponible. Al realizar un rastreo inicial, el sistema detectó la presencia de 634 registros faltantes, una situación completamente normal cuando se opera con sensores automáticos expuestos a fallas eléctricas o pérdidas de señal en las estaciones de monitoreo. Para resolver esta interrupción de la secuencia, se aplicó un filtro de omisión que eliminó estas celdas vacías y consolidó un conjunto de datos depurado y libre de ruidos informáticos.

Gráfico de la Serie Temporal

library(forecast)
library(ggplot2)
library(plotly)
library(knitr)

tabla_na <- data.frame(
  Etapa = c("Serie Original", "Serie Filtrada (Sin NA)"),
  `Datos Faltantes (NA)` = c(sum(is.na(Temperatura)), sum(is.na(na.omit(Temperatura))))
)

kable(tabla_na, 
      caption = "Control de Datos Faltantes", 
      align = c("l", "c"))
Control de Datos Faltantes
Etapa Datos.Faltantes..NA.
Serie Original 634
Serie Filtrada (Sin NA) 0
Temperatura2 <- na.omit(Temperatura)

p_linea <- autoplot(Temperatura2) +
  labs(title = "Comportamiento Histórico de la Temperatura", x = "Tiempo", y = "Temperatura (°C)") +
  theme_minimal()

ggplotly(p_linea)

Al observar de manera directa el gráfico de la serie temporal generado tras la limpieza, se revelan dos dinámicas cruciales sobre el clima de la región. En primer lugar, la gráfica expone de forma transparente un vacío de información prolongado durante el primer trimestre del año, representado visualmente por una línea recta diagonal continua que cruza de un extremo a otro debido a la falta de mediciones reales en ese lapso. En segundo lugar, a pesar de este bache, la temperatura exhibe una oscilación densa, compacta y sumamente homogénea que se mantiene confinada de manera estable entre los 22°C y los 37°C. Al no percibirse ninguna inclinación sostenida al alza o a la baja a nivel macro, la inspección visual sugiere que la serie carece de tendencias determinísticas a largo plazo, manteniendo un comportamiento global en equilibrio.

Prueba de Raíz Unitaria Dickey-Fuller Aumentado

library(tseries)
library(knitr)


prueba_adf <- adf.test(Temperatura2)

tabla_adf <- data.frame(
  `Estadístico Dickey-Fuller` = round(prueba_adf$statistic, 4),
  `Lag Order` = prueba_adf$parameter,
  `p-valor` = round(prueba_adf$p.value, 4),
  Resultado = ifelse(prueba_adf$p.value < 0.05, "Estacionaria (Rechaza H0)", "No Estacionaria")
)

kable(tabla_adf, 
      caption = "Resultado de la Prueba de Raíz Unitaria (ADF)", 
      align = "c")
Resultado de la Prueba de Raíz Unitaria (ADF)
Estadístico.Dickey.Fuller Lag.Order p.valor Resultado
Dickey-Fuller -8.1442 20 0.01 Estacionaria (Rechaza H0)

Para dar soporte científico a la percepción visual previa y asegurar que las predicciones futuras no resulten erráticas o sesgadas, se ejecutó formalmente la prueba matemática de raíz unitaria de Dickey-Fuller Aumentada. Los resultados obtenidos directamente en la consola de R arrojan un estadístico de -8.1442 con un orden de rezago de 20, derivando en un p-valor de 0.01. Al ubicarse este indicador estrictamente por debajo del límite de significancia estándar del 5% (\(\alpha = 0.05\)), se cuenta con evidencia estadística contundente para rechazar de manera definitiva la premisa de no estacionariedad.Por lo tanto, se confirma formalmente que la serie de temperatura es estacionaria en media y varianza. Este hallazgo representa un pilar fundamental para el proyecto, ya que demuestra matemáticamente que el orden de integración para los modelos predictivos base debe ser \(d=0\). Al validar que la serie retorna constantemente a su promedio, se evita aplicar una diferenciación ordinaria innecesaria, eliminando el riesgo de sobreprocesar los datos o alterar de manera artificial la verdadera naturaleza estocástica del clima local.

Análisis de Correlogramas (ACF y PACF)

library(forecast)
library(ggplot2)
library(plotly)

p_acf <- ggAcf(Temperatura2) + labs(title = "Función de Autocorrelación (ACF)") + theme_minimal()
p_pacf <- ggPacf(Temperatura2) + labs(title = "Función de Autocorrelación Parcial (PACF)") + theme_minimal()

subplot(ggplotly(p_acf), ggplotly(p_pacf), nrows = 1, titleX = TRUE, titleY = TRUE)

Con la estabilidad global de la serie demostrada numéricamente, la inspección en paralelo de las funciones de autocorrelación simple (ACF) y parcial (PACF) entrega la información clave para descubrir la estructura de memoria oculta del clima antes de calibrar las ecuaciones. El correograma comparativo del ACF exhibe un patrón fuertemente sinusoidal y cíclico, con coeficientes que sobresalen significativamente de las bandas de confianza de color azul y que alcanzan un pico de repetición exacto e imponente cada 24 rezagos. Este comportamiento confirma visualmente la existencia de una marcada estacionalidad diaria, típica de variables climatológicas donde las condiciones de calor y frío repiten un ciclo exacto cada 24 horas entre el día y la noche.

Por su parte, la gráfica de autocorrelación parcial (PACF) complementa este diagnóstico al presentar un corte abrupto y severo exactamente en el rezago 2, registrando un coeficiente negativo pronunciado que es seguido por picos estacionales significativos en torno al rezago 24. Esta huella digital revela que el fenómeno posee un componente autorregresivo de memoria corta muy definido en sus primeras horas de arrastre, pero advierte con total claridad que las variaciones cíclicas del rezago 24 harán que un modelo ARIMA simple se quede corto. Esto establece la necesidad de guiar la configuración de los órdenes hacia un enfoque estacional avanzado (SARIMA), único método capaz de procesar en simultáneo la inercia inmediata y el ciclo completo de la jornada natural de la región.

4.2 Estimación y Selección del Modelo ARIMA

Una vez definida la inercia temporal de la serie, el proceso avanza hacia la fase de modelamiento competitivo mediante la metodología Box-Jenkins. Con base en la memoria matemática observada en los correlogramas analizados anteriormente, donde los rezagos iniciales marcan un patrón de arrastre claro, se diseñaron cinco configuraciones manuales alternativas. Estas estructuras se construyeron fijando un operador de diferencias para garantizar el control local de la varianza y un límite máximo de cuatro retardos autorregresivos para representar el impacto de las horas más recientes sobre el clima actual.

Para identificar la arquitectura más eficiente, estos modelos diseñados a medida se contrastaron en paralelo contra la selección automatizada provista por el algoritmo de optimización. La comparación se fundamenta en la evaluación crítica de los criterios de información de Akaike y Bayesiano, indicadores que penalizan el exceso de variables para prevenir el sobreajuste. Este análisis matricial permite hallar un punto de equilibrio óptimo, seleccionando el modelo que minimice la pérdida de información y garantice la mayor capacidad predictiva utilizando la estructura matemática más compacta y robusta posible.

library(forecast)
library(knitr)

modelo1 <- Arima(Temperatura2, order = c(4,1,0))
modelo2 <- Arima(Temperatura2, order = c(4,1,1))
modelo3 <- Arima(Temperatura2, order = c(4,1,2))
modelo4 <- Arima(Temperatura2, order = c(4,1,3))
modelo5 <- Arima(Temperatura2, order = c(4,1,4))
modelo_auto <- auto.arima(Temperatura2)


aic_valores <- c(modelo1$aic, modelo2$aic, modelo3$aic, modelo4$aic, modelo5$aic, modelo_auto$aic)
bic_valores <- c(modelo1$bic, modelo2$bic, modelo3$bic, modelo4$bic, modelo5$bic, modelo_auto$bic)

tabla_criterios <- data.frame(
  Modelo = c("ARIMA(4,1,0)", "ARIMA(4,1,1)", "ARIMA(4,1,2)", "ARIMA(4,1,3)", "ARIMA(4,1,4)", "Auto ARIMA"),
  AIC = round(as.numeric(aic_valores), 2),
  BIC = round(as.numeric(bic_valores), 2)
)

kable(tabla_criterios, 
      caption = "Criterios de Información para Selección de Modelos", 
      align = "c")
Criterios de Información para Selección de Modelos
Modelo AIC BIC
ARIMA(4,1,0) 21565.50 21600.51
ARIMA(4,1,1) 19956.78 19998.80
ARIMA(4,1,2) 19513.76 19562.78
ARIMA(4,1,3) 19504.92 19560.94
ARIMA(4,1,4) 19560.32 19623.34
Auto ARIMA 19504.92 19560.94

La selección de la estructura óptima para la temperatura en Cali durante el año 2018 se fundamenta en el principio de parsimonia a través de las métricas de Akaike (AIC) y Bayesiano (BIC). Al evaluar los modelos candidatos, se observa una reducción drástica en ambos criterios al pasar de un modelo autorregresivo puro \(\text{ARIMA}(4,1,0)\) (\(\text{AIC} = 21565.50\)) hacia estructuras mixtas, evidenciando que los puros cambios lineales pasados no bastan para describir el comportamiento de la variable.El valor mínimo global se alcanza simultáneamente en el modelo \(\text{ARIMA}(4,1,3)\) y en la sugerencia del algoritmo automatizado (\(\text{AUTO.ARIMA}\)), consolidando un \(\text{AIC} = 19504.92\) y un \(\text{BIC} = 19560.94\). Debido a que la adición de un parámetro rezagado más en el modelo \(\text{ARIMA}(4,1,4)\) incrementa penalizaciones por complejidad sin ofrecer una mejora sustancial en el ajuste (\(\text{AIC} = 19560.32\)), la estructura \((4,1,3)\) queda validada matemáticamente como el modelo clásico más equilibrado para describir la dinámica térmica de la ciudad.

library(forecast)
library(tidyverse)
library(knitr)
library(lmtest)

modelo_auto <- auto.arima(Temperatura2)

tabla_coeficientes <- as.data.frame(t(coeftest(modelo_auto)[, 1:2]))

kable(tabla_coeficientes, 
      caption = "Parámetros y Errores Estándar del Modelo Seleccionado", 
      align = "c")
Parámetros y Errores Estándar del Modelo Seleccionado
ar1 ar2 ar3 ar4 ma1 ma2 ma3
Estimate 1.5493792 -0.1737867 -0.5839582 0.1259323 -1.2307363 -0.2892762 0.5476799
Std. Error 0.1009032 0.2220181 0.1572997 0.0327936 0.0995606 0.1856504 0.0880259

La estimación matemática del modelo matemático devela cómo se transfiere la energía térmica a lo largo de las horas en la atmósfera de Cali. El fuerte acoplamiento del primer coeficiente autorregresivo denota que la temperatura ambiente posee una inercia térmica sumamente alta; es decir, el aire conserva el calor o el frío de la hora inmediatamente anterior de forma dominante, requiriendo de los desfases posteriores para estabilizar y contrapearse de manera oscilatoria.

Por otro lado, la naturaleza de las medias móviles actúa directamente como un amortiguador de choques exógenos en el microclima de la ciudad. El impacto negativo y pronunciado del primer término de media móvil sugiere que las perturbaciones meteorológicas súbitas de corto plazo —tales como un aumento imprevisto en la nubosidad, ráfagas de viento provenientes de los Farallones de Cali o caídas de presión por lluvias repentinas— provocan una corrección correctiva rápida en el sistema. Al evaluar la proporción de estos estimadores frente a sus respectivos márgenes de dispersión, se ratifica que esta memoria atmosférica de corto plazo es estadísticamente sólida y describe de forma confiable las transiciones del clima local.

modelo1 <- Arima(Temperatura2, order = c(4,1,0))
modelo2 <- Arima(Temperatura2, order = c(4,1,1))
modelo3 <- Arima(Temperatura2, order = c(4,1,2))
modelo4 <- Arima(Temperatura2, order = c(4,1,3))
modelo5 <- Arima(Temperatura2, order = c(4,1,4))

comparacion <- data.frame(
  Modelo = c("ARIMA(4,1,0)", "ARIMA(4,1,1)", "ARIMA(4,1,2)",
             "ARIMA(4,1,3)", "ARIMA(4,1,4)", "AUTO.ARIMA"),
  
  AIC = c(AIC(modelo1), AIC(modelo2), AIC(modelo3),
          AIC(modelo4), AIC(modelo5), AIC(modelo_auto)),
  
  BIC = c(BIC(modelo1), BIC(modelo2), BIC(modelo3),
          BIC(modelo4), BIC(modelo5), BIC(modelo_auto))
)

kable(comparacion, 
      caption = "Segunda Validación de Criterios de Información", 
      align = "c")
Segunda Validación de Criterios de Información
Modelo AIC BIC
ARIMA(4,1,0) 21565.50 21600.51
ARIMA(4,1,1) 19956.78 19998.80
ARIMA(4,1,2) 19513.76 19562.78
ARIMA(4,1,3) 19504.92 19560.94
ARIMA(4,1,4) 19560.32 19623.34
AUTO.ARIMA 19504.92 19560.94
library(forecast)
library(knitr)

invisible(capture.output(checkresiduals(modelo1, plot = TRUE)))

test_m1 <- Box.test(residuals(modelo1), lag = 10, type = "Ljung-Box")
tabla_m1 <- data.frame(
  Modelo = "ARIMA(4,1,0)",
  `Estadístico X-squared` = round(test_m1$statistic, 2),
  `Grados de Libertad` = test_m1$parameter,
  `Valor p` = round(test_m1$p.value, 4),
  check.names = FALSE
)
kable(tabla_m1, caption = "Prueba Ljung-Box para ARIMA(4,1,0)", align = "c")
Prueba Ljung-Box para ARIMA(4,1,0)
Modelo Estadístico X-squared Grados de Libertad Valor p
X-squared ARIMA(4,1,0) 376.94 10 0
invisible(capture.output(checkresiduals(modelo2, plot = TRUE)))

test_m2 <- Box.test(residuals(modelo2), lag = 10, type = "Ljung-Box")
tabla_m2 <- data.frame(
  Modelo = "ARIMA(4,1,1)",
  `Estadístico X-squared` = round(test_m2$statistic, 2),
  `Grados de Libertad` = test_m2$parameter,
  `Valor p` = round(test_m2$p.value, 4),
  check.names = FALSE
)
kable(tabla_m2, caption = "Prueba Ljung-Box para ARIMA(4,1,1)", align = "c")
Prueba Ljung-Box para ARIMA(4,1,1)
Modelo Estadístico X-squared Grados de Libertad Valor p
X-squared ARIMA(4,1,1) 108.03 10 0
invisible(capture.output(checkresiduals(modelo3, plot = TRUE)))

test_m3 <- Box.test(residuals(modelo3), lag = 10, type = "Ljung-Box")
tabla_m3 <- data.frame(
  Modelo = "ARIMA(4,1,2)",
  `Estadístico X-squared` = round(test_m3$statistic, 2),
  `Grados de Libertad` = test_m3$parameter,
  `Valor p` = round(test_m3$p.value, 4),
  check.names = FALSE
)
kable(tabla_m3, caption = "Prueba Ljung-Box para ARIMA(4,1,2)", align = "c")
Prueba Ljung-Box para ARIMA(4,1,2)
Modelo Estadístico X-squared Grados de Libertad Valor p
X-squared ARIMA(4,1,2) 209.25 10 0
invisible(capture.output(checkresiduals(modelo4, plot = TRUE)))

test_m4 <- Box.test(residuals(modelo4), lag = 10, type = "Ljung-Box")
tabla_m4 <- data.frame(
  Modelo = "ARIMA(4,1,3)",
  `Estadístico X-squared` = round(test_m4$statistic, 2),
  `Grados de Libertad` = test_m4$parameter,
  `Valor p` = round(test_m4$p.value, 4),
  check.names = FALSE
)
kable(tabla_m4, caption = "Prueba Ljung-Box para ARIMA(4,1,3)", align = "c")
Prueba Ljung-Box para ARIMA(4,1,3)
Modelo Estadístico X-squared Grados de Libertad Valor p
X-squared ARIMA(4,1,3) 195.49 10 0
invisible(capture.output(checkresiduals(modelo5, plot = TRUE)))

test_m5 <- Box.test(residuals(modelo5), lag = 10, type = "Ljung-Box")
tabla_m5 <- data.frame(
  Modelo = "ARIMA(4,1,4)",
  `Estadístico X-squared` = round(test_m5$statistic, 2),
  `Grados de Libertad` = test_m5$parameter,
  `Valor p` = round(test_m5$p.value, 4),
  check.names = FALSE
)
kable(tabla_m5, caption = "Prueba Ljung-Box para ARIMA(4,1,4)", align = "c")
Prueba Ljung-Box para ARIMA(4,1,4)
Modelo Estadístico X-squared Grados de Libertad Valor p
X-squared ARIMA(4,1,4) 192.84 10 0
invisible(capture.output(checkresiduals(modelo_auto, plot = TRUE)))

test_ma <- Box.test(residuals(modelo_auto), lag = 10, type = "Ljung-Box")
tabla_ma <- data.frame(
  Modelo = "AUTO.ARIMA",
  `Estadístico X-squared` = round(test_ma$statistic, 2),
  `Grados de Libertad` = test_ma$parameter,
  `Valor p` = round(test_ma$p.value, 4),
  check.names = FALSE
)
kable(tabla_ma, caption = "Prueba Ljung-Box para AUTO.ARIMA", align = "c")
Prueba Ljung-Box para AUTO.ARIMA
Modelo Estadístico X-squared Grados de Libertad Valor p
X-squared AUTO.ARIMA 195.49 10 0

Para ver si alguno de los modelos de verdad estaba haciendo bien el trabajo de limpiar la información de la serie, se utilizo la función checkresiduals(). Esta función arroja tres gráficos: la línea de tiempo de los errores arriba, el correograma (ACF) abajo a la izquierda y el histograma con la curva normal abajo a la derecha. Además, esto arroja los datos matemáticos del test de Ljung-Box para comprobar si los errores son realmente aleatorios (ruido blanco).Al comparar los resultados de todos los modelos que se probaron (desde el ARIMA(4,1,0) hasta el ARIMA(4,1,4)), se pudo determinar que todos fallan en un mismo punto. Si se mira la gráfica de arriba, todos muestran una nube de puntos bien distribuida alrededor de cero, con un par de picos locos que pasan de 5 unidades seguramente por algún día de clima rarísimo en Cali. Esta segunda matriz actúa como un control metodológico para verificar la consistencia numérica de los algoritmos de estimación ejecutados sobre la serie de temperatura de Cali. La perfecta convergencia e identidad entre los valores de ambos bloques ratifica que las funciones de optimización en R (Arima y auto.arima) alcanzaron el mismo mínimo local de la función de verosimilitud para el histórico de 2018. Esta replicabilidad matemática confirma que la ventaja predictiva del modelo \(\text{ARIMA}(4,1,3)\) no es un artefacto aleatorio derivado de la inicialización de los algoritmos, sino una propiedad estructural del comportamiento climático local; sin embargo, para determinar si de verdad alguna de estas estructuras logra capturar y limpiar la información de la serie por completo, es imperativo someterlas a una evaluación rigurosa de sus residuos.Con este propósito se utilizó la función checkresiduals(), la cual despliega un diagnóstico visual compuesto por tres gráficos esenciales: la evolución temporal de los errores en la parte superior, el correograma de la función de autocorrelación simple (ACF) abajo a la izquierda y el histograma acoplado con la curva de densidad normal abajo a la derecha. Complementariamente, esta herramienta calcula las métricas formales de la prueba de Box-Pierce-Ljung para verificar matemáticamente si los residuales se comportan como un proceso de ruido blanco puramente aleatorio.Al contrastar los resultados de todo el espectro de modelos evaluados (desde el \(\text{ARIMA}(4,1,0)\) hasta el \(\text{ARIMA}(4,1,4)\)), se pudo determinar que todas las estructuras analizadas fallan exactamente en el mismo supuesto correlacional. Al observar la gráfica temporal superior, todos los modelos exhiben una dispersión de errores que parece bien distribuida de forma homogénea alrededor del cero, registrando únicamente un par de picos anómalos aislados que superan las 5 unidades, asociados con eventos climáticos atípicos o transiciones térmicas extremas en la ciudad de Cali durante ese año. El problema aparece cuando se observa los correogramas (ACF) y los p-valores. En todas las imágenes sin excepción, el correograma muestra unas barras negras gigantes que se salen por completo de las líneas azules de control. Lo interesante de esto es que estas barras no se salen en cualquier lado, todas se disparan de forma masiva entre los rezagos 20 y 26, teniendo el pico más alto justo en el rezago 24. Esto nos demuestra gráficamente que todos los modelos dejaron escapar el mismo detalle, la temperatura de hoy está amarrada a la temperatura que hizo exactamente a la misma hora el día anterior. Ningún ARIMA tradicional fue capaz de corregir eso.

Para terminar, la prueba estadística de abajo da la razón con números. El valor \(Q^*\) se eleva en todos los casos: 376.94 en el ARIMA(4,1,0), 108.03 en el ARIMA(4,1,1), 209.25 en el ARIMA(4,1,2), 195.49 en el ARIMA(4,1,3) y 318.46 en el ARIMA(4,1,4). Como todos tienen un p-valor menor a 2.2e-16 (o sea, cero), la estadística obliga a rechazar la idea de que los errores son independientes. Al final, esto confirma que los residuos de ninguno son ruido blanco y que nuestro modelo ganador, el ARIMA(4,1,3), sigue estando incompleto porque se le pasa toda la estacionalidad del día y la noche.

Interpretación de los Resultados Técnicos

Una vez estimadas las diferentes estructuras candidatas para modelar la temperatura, el proceso avanza hacia la elección de la mejor arquitectura basándose en el principio de parsimonia. Esta regla busca un equilibrio perfecto: que el modelo explique con la mayor precisión posible los cambios del clima, pero utilizando la menor cantidad de parámetros para evitar que se sature o se vuelva ineficiente. Para medir este balance de forma cuantitativa, se contrastan en paralelo los criterios de información de Akaike y Bayesiano, dos indicadores que penalizan de forma estricta la inclusión de variables innecesarias.Al examinar los resultados numéricos de la tabla comparativa, resalta de inmediato que el modelo ARIMA(4,1,3) supera a todas las demás opciones alternativas evaluadas. Esta configuración logra alcanzar de manera simultánea los valores más bajos tanto en el indicador AIC como en el BIC. Que ambos criterios coincidan en señalar al mismo ganador es un hallazgo de gran peso estadístico; mientras que el AIC se enfoca en maximizar la capacidad de predicción del sistema, el BIC aplica un castigo mucho más severo según el volumen de datos para asegurar que no se estén forzando coeficientes redundantes. Esta reducción simultánea demuestra que la combinación de cuatro rezagos autorregresivos donde \(p=4\), una diferencia lineal donde \(d=1\), y tres términos de medias móviles donde \(q=3\), representa la estructura más eficiente para capturar la memoria de corto plazo y las variaciones climáticas de la serie sin saturar el algoritmo numérico. Por lo tanto, el ARIMA(4,1,3) queda seleccionado formalmente como la estructura definitiva para el análisis. No obstante, para validar su idoneidad matemática antes de proceder con el pronóstico final, este modelo deberá someterse en la siguiente sección a una revisión estricta de sus residuos para garantizar de manera formal que se comporten como ruido blanco.

4.3 Modelo mediante Entrenamiento y Prueba

library(forecast)
library(knitr)

ventana <- window(Temperatura2, end = index(Temperatura2)[length(Temperatura2)-24])
ventana2 <- window(Temperatura2, start = index(Temperatura2)[length(Temperatura2)-23])
modelo_train <- Arima(ventana, order = c(4,1,3))

pronostico <- forecast(modelo_train, h = 24)

tabla_pronostico <- data.frame(
  Índice = rownames(as.data.frame(pronostico)),
  `Pronóstico (Point Forecast)` = round(pronostico$mean, 4),
  `Límite Inferior 95% (Lo 95)` = round(pronostico$lower[, 2], 4),
  `Límite Superior 95% (Hi 95)` = round(pronostico$upper[, 2], 4),
  check.names = FALSE
)

kable(tabla_pronostico, 
      caption = "Valores Pronosticados e Intervalos de Confianza (95%) para las Próximas 24 Horas", 
      align = "c")
Valores Pronosticados e Intervalos de Confianza (95%) para las Próximas 24 Horas
Índice Pronóstico (Point Forecast) Límite Inferior 95% (Lo 95) Límite Superior 95% (Hi 95)
29167201 26.4044 24.8297 27.9791
29170801 26.1311 23.5263 28.7359
29174401 26.0825 22.7222 29.4427
29178001 26.2810 22.3432 30.2189
29181601 26.6940 22.3466 31.0414
29185201 27.2934 22.6737 31.9130
29188801 28.0280 23.2518 32.8041
29192401 28.8457 23.9974 33.6941
29196001 29.6871 24.8186 34.5557
29199601 30.4951 25.6260 35.3643
29203201 31.2158 26.3402 36.0914
29206801 31.8037 26.9010 36.7064
29210401 32.2235 27.2715 37.1755
29214001 32.4528 27.4381 37.4676
29217601 32.4827 27.4057 37.5597
29221201 32.3182 27.1925 37.4438
29224801 31.9771 26.8234 37.1309
29228401 31.4889 26.3262 36.6515
29232001 30.8915 25.7288 36.0542
29235601 30.2293 25.0587 35.3999
29239201 29.5494 24.3439 34.7548
29242801 28.8983 23.6159 34.1807
29246401 28.3191 22.9107 33.7275
29250001 27.8485 22.2692 33.4279
library(forecast)
library(knitr)

pronostico_objeto <- forecast(modelo_train, h = 24, level = 0.95)

tabla_pronostico <- data.frame(
  Índice = rownames(as.data.frame(pronostico_objeto)),
  `Pronóstico (Point Forecast)` = round(pronostico_objeto$mean, 4),
  `Límite Inferior 95% (Lo 95)` = round(pronostico_objeto$lower, 4),
  `Límite Superior 95% (Hi 95)` = round(pronostico_objeto$upper, 4),
  check.names = FALSE
)

kable(tabla_pronostico, 
      caption = "Pronóstico de las Próximas 24 Horas", 
      align = "c")
Pronóstico de las Próximas 24 Horas
Índice Pronóstico (Point Forecast) 95% 95%
29167201 26.4044 24.8297 27.9791
29170801 26.1311 23.5263 28.7359
29174401 26.0825 22.7222 29.4427
29178001 26.2810 22.3432 30.2189
29181601 26.6940 22.3466 31.0414
29185201 27.2934 22.6737 31.9130
29188801 28.0280 23.2518 32.8041
29192401 28.8457 23.9974 33.6941
29196001 29.6871 24.8186 34.5557
29199601 30.4951 25.6260 35.3643
29203201 31.2158 26.3402 36.0914
29206801 31.8037 26.9010 36.7064
29210401 32.2235 27.2715 37.1755
29214001 32.4528 27.4381 37.4676
29217601 32.4827 27.4057 37.5597
29221201 32.3182 27.1925 37.4438
29224801 31.9771 26.8234 37.1309
29228401 31.4889 26.3262 36.6515
29232001 30.8915 25.7288 36.0542
29235601 30.2293 25.0587 35.3999
29239201 29.5494 24.3439 34.7548
29242801 28.8983 23.6159 34.1807
29246401 28.3191 22.9107 33.7275
29250001 27.8485 22.2692 33.4279
tabla_reales <- data.frame(
  Índice = index(ventana2),
  `Valores Reales (Ventana 2)` = as.numeric(ventana2),
  check.names = FALSE
)

kable(tabla_reales, 
      caption = "Valores Reales de Validación (Ventana 2)", 
      align = "c")
Valores Reales de Validación (Ventana 2)
Índice Valores Reales (Ventana 2)
2018-12-31 01:00:00 26.3
2018-12-31 02:00:00 26.1
2018-12-31 03:00:00 25.8
2018-12-31 04:00:00 25.4
2018-12-31 05:00:00 24.7
2018-12-31 06:00:00 24.5
2018-12-31 07:00:00 24.5
2018-12-31 08:00:00 25.8
2018-12-31 09:00:00 28.4
2018-12-31 10:00:00 30.8
2018-12-31 11:00:00 32.7
2018-12-31 12:00:00 33.6
2018-12-31 13:00:00 34.8
2018-12-31 14:00:00 35.7
2018-12-31 15:00:00 35.8
2018-12-31 16:00:00 36.1
2018-12-31 17:00:00 36.0
2018-12-31 18:00:00 33.5
2018-12-31 19:00:00 31.8
2018-12-31 20:00:00 30.4
2018-12-31 21:00:00 28.3
2018-12-31 22:00:00 27.5
2018-12-31 23:00:00 27.1
2019-01-01 00:00:00 26.5
metricas_precision <- accuracy(forecast(modelo_train, h = 24), ventana2)

tabla_precision <- as.data.frame(metricas_precision)

kable(tabla_precision, 
      caption = "Métricas de Precisión del Pronóstico (Datos de Entrenamiento vs. Validación)", 
      align = "c")
Métricas de Precisión del Pronóstico (Datos de Entrenamiento vs. Validación)
ME RMSE MAE MPE MAPE MASE ACF1
Training set 0.0018147 0.8030419 0.581598 -0.0652486 2.073696 0.0205657 -0.0014328
Test set 0.1857881 2.1596865 1.782660 -0.2777034 5.920446 0.0630360 NA
library(forecast)
library(ggplot2)

modelo_train %>%
  forecast(h = 24) %>%
  autoplot(include = 80)

Para evaluar con rigurosidad metodológica la capacidad predictiva de la estructura seleccionada, se procedió a aislar las últimas 24 horas de la serie histórica bajo un esquema de validación cruzada temporal. De este modo, la serie de temperatura de Cali se dividió en un conjunto de entrenamiento (Training Set) destinado a la estimación paramétrica y un conjunto de prueba (Test Set) que simula un horizonte futuro de validación exógena que el algoritmo no ha visto previamente.Al contrastar de forma analítica las métricas de precisión obtenidas en ambas fases, se evidencia un fenómeno clásico de pérdida de generalización. Durante la etapa de ajuste sobre el Training Set, las métricas simulan un desempeño sumamente robusto: el error cuadrático medio (RMSE) se posiciona en apenas 0.80 °C y el error porcentual absoluto medio (MAPE) registra un óptimo 2.07%. No obstante, al someter el modelo a la prueba de fuego frente a los datos reales de validación del Test Set, el escenario cambia por completo. El RMSE se triplica drásticamente hasta alcanzar los 2.15 °C, mientras que el MAPE se eleva al 5.92%, incrementando de manera notable la incertidumbre de la proyección.Esta marcada divergencia entre los errores de entrenamiento y evaluación es el reflejo matemático de una limitación estructural en la especificación del modelo ARIMA tradicional. El análisis complementario de la función de autocorrelación (ACF) residual devela la presencia de correlaciones altamente significativas y periódicas que persisten sin corregir. Al carecer de un componente estacional explícito, el modelo es completamente ciego a los ciclos circadianos naturales (el patrón repetitivo de día y noche de 24 horas); en consecuencia, asume que la dinámica térmica responde únicamente a una inercia lineal de cortísimo plazo y no logra capturar los picos máximos de radiación solar en la tarde caleña ni los enfriamientos nocturnos habituales influenciados por los vientos de los Farallones.Esta insuficiencia queda finalmente ratificada por los resultados de la prueba formal de Ljung-Box sobre el modelo base, donde el estadístico X{-squared} de 376.94 y un valor p que converge estrictamente a cero rechazan categóricamente la hipótesis de aleatoriedad en los residuos. Los errores no constituyen ruido blanco, sino que retienen información climática sistemática que el modelo fue incapaz de asimilar. En conclusión, aunque la estructura lineal extrae de forma eficiente la memoria inmediata del proceso, se queda teóricamente corta para proyecciones meteorológicas de mediano plazo, validando la necesidad imperativa de migrar hacia un enfoque estacional univariado (SARIMA) o modelos de espacio de estados que incorporen explícitamente el período estacional de 24 horas.

4.4 Diagnóstico y Validación de los Residuales

Con el propósito de determinar si el proceso estocástico estimado mediante la estructura ARIMA(4,1,3) es estadísticamente adecuado y consistente para la generación de pronósticos, se ejecuta un análisis integral sobre sus perturbaciones aleatorias en combinación con la prueba formal de Box-Pierce-Ljung. Este procedimiento evalúa rigurosamente si los residuos satisfacen las condiciones asintóticas de ruido blanco; es decir, la confirmación de una media ergódica estacionaria en cero, un comportamiento homocedástico en la varianza a lo largo del soporte temporal y la ausencia absoluta de autocorrelación serial.

library(forecast)
library(ggplot2)
library(plotly)

residuos <- residuals(modelo4)

p_res_linea <- autoplot(residuos) + 
  labs(title = "Residuos del Modelo en el Tiempo", y = "Error", x = "Tiempo") +
  theme_minimal()

ggplotly(p_res_linea)

Al examinar la evolución temporal de las perturbaciones en primera instancia, se aprecia que la nube densa de errores oscila de manera homogénea y simétrica alrededor de la línea horizontal del cero, lo que valida conceptualmente que el modelo no presenta sesgos de subestimación o sobreestimación sistemática. No obstante, el gráfico expone visualmente la persistencia de anomalías en ciertos tramos, destacando la distorsión vinculada al vacío de información ocurrido durante el primer trimestre de 2018. Aunque la varianza aparenta una relativa estabilidad (homocedasticidad) en la mayor parte del soporte, esta inspección puramente lineal es insuficiente para garantizar que el modelo sea estadísticamente óptimo, requiriendo un examen en el dominio de las frecuencias y las autocorrelaciones.

library(forecast)
library(ggplot2)
library(plotly)

residuos <- residuals(modelo4)

p_res_acf <- ggAcf(residuos) + 
  labs(title = "Función de Autocorrelación (ACF) de Residuos") +
  theme_minimal()

ggplotly(p_res_acf)

La verdadera quiebra de los supuestos teóricos de ruido blanco se evidencia de manera contundente al analizar el correograma de los residuos. En la función de autocorrelación simple (ACF) se observa que una cantidad significativa de retardos sobresale de forma severa y sistemática por encima de las bandas de confianza estadística de color azul. Este comportamiento no es aleatorio; al contrario, dibuja un patrón oscilatorio remanente que expone con claridad que la estructura ARIMA ordinaria fue incapaz de extraer la totalidad de la dependencia temporal intrínseca de la serie, dejando libre un flujo de información no absorbido que contamina los errores y sesga la eficiencia de los pronósticos.

library(forecast)
library(ggplot2)
library(plotly)
library(knitr)

residuos <- residuals(modelo4)

p_res_hist <- ggplot(data.frame(res = as.numeric(residuos)), aes(x = res)) +
  geom_histogram(bins = 20, fill = "darkcyan", color = "black", alpha = 0.8) +
  labs(title = "Distribución y Simetría de los Residuos", x = "Residuos", y = "Frecuencia") +
  theme_minimal()

ggplotly(p_res_hist)
prueba_lb <- Box.test(residuos, lag = 10, type = "Ljung-Box")

tabla_lb <- data.frame(
  `Estadístico X-squared` = round(prueba_lb$statistic, 4),
  `Grados de Libertad (df)` = prueba_lb$parameter,
  `p-valor` = round(prueba_lb$p.value, 4),
  Resultado = ifelse(prueba_lb$p.value > 0.05, "Ruido Blanco (No Autocorrelacionados)", "Autocorrelacionados")
)

kable(tabla_lb, 
      caption = "Resultado de la Prueba de Ljung-Box sobre los Residuales", 
      align = "c")
Resultado de la Prueba de Ljung-Box sobre los Residuales
Estadístico.X.squared Grados.de.Libertad..df. p.valor Resultado
X-squared 195.485 10 0 Autocorrelacionados

Finalmente, el análisis gráfico se complementa con el histograma de frecuencias, el cual exhibe un perfil marcadamente apuntalado y centrado en cero que simula una distribución normal. Sin embargo, la presencia previa de dependencias seriales en el ACF invalida de inmediato cualquier presunción de independencia e idoneidad.Para otorgar el veredicto matemático definitivo y evitar ambigüedades visuales, los resultados de la prueba de Ljung-Box procesada para un orden de 10 rezagos arrojan un estadístico \(X^2 = 195.485\) y un \(p\text{-valor} = 0\). Al ser este indicador estrictamente inferior al nivel de significancia convencional del 5% (\(\alpha = 0.05\)), se rechaza categóricamente la premisa de independencia.La conclusión del diagnóstico es clara: los residuos están significativamente autocorrelacionados. Desde la perspectiva metodológica de Box-Jenkins, el ARIMA(4,1,3) se revela como un modelo estadísticamente insuficiente para esta serie. Esta falla estructural ocurre porque las ecuaciones tradicionales carecen de los operadores matemáticos necesarios para digerir la fortísima inercia cíclica de 24 horas que caracteriza al clima de Cali. Este hallazgo justifica técnicamente por qué se vuelve estrictamente obligatorio abandonar el enfoque ARIMA simple y migrar hacia una modelación estacional avanzada (SARIMA), la cual cuenta con la capacidad de incorporar coeficientes estacionales específicos para limpiar los desfases en el rezago 24 y devolver perturbaciones puramente aleatorias.

4.5 Análisis y Evaluación del Pronóstico

A partir del modelo ARIMA(4,1,3) seleccionado, se ejecuta la predicción de la temperatura para un horizonte de corto plazo correspondiente a las próximas 24 observaciones donde \(h=24\), incorporando bandas de confianza del 80% y 95%. A pesar de las limitaciones de validación identificadas en los residuos debido a la ausencia de componentes estacionales, el examen cuantitativo y la trayectoria de la curva proyectada abren paso a una evaluación detallada de la capacidad predictiva del sistema. De este modo, el análisis visual y operativo del gráfico de pronóstico permite extraer las siguientes conclusiones técnicas y operativas:

pronostico_24h <- forecast(modelo4, h = 24, level = c(80, 95))

p_pronostico <- autoplot(pronostico_24h) +
  labs(
    title = "Pronóstico Interactivo de Temperatura para las Próximas 24 Horas",
    x = "Tiempo / Período",
    y = "Temperatura (°C)"
  ) +
  theme_minimal()

ggplotly(p_pronostico)

-Comportamiento de la Estimación Puntual: La trayectoria proyectada por el modelo se ubica al extremo final del denso registro histórico. Debido a que se está operando con una estructura ARIMA(4,1,3) que implementa un orden de diferenciación \(d=1\), la predicción no es arrastrada mecánicamente hacia el promedio histórico global.

-Estabilización de la Curva: Una vez que se disipan los efectos dinámicos de los componentes autorregresivos y de medias móviles en las primeras horas del horizonte, la curva se estabiliza de forma suavizada en un nivel horizontal. Este comportamiento plano queda determinado exclusivamente por la inercia y el valor de las últimas observaciones reales disponibles.

-Incapacidad de Réplica Cíclica: Al no incorporar operadores estacionales explícitos, el modelo se muestra incapaz de replicar el ciclo diario de calentamiento y enfriamiento propio de la ciudad de Cali. Debido a esto, la estructura se limita a proyectar el nivel promedio de cierre de la serie sin reflejar las oscilaciones naturales entre el día y la noche.

-Análisis de las Bandas de Incertidumbre: Las áreas sombreadas de dispersión reflejan visualmente el incremento de la incertidumbre a medida que la predicción se aleja en el tiempo del último dato real registrado. Este ensanchamiento progresivo en el extremo derecho es teóricamente consistente con los procesos integrados de orden uno.

-Relevancia Operativa: En el ámbito del control operativo y de procesos, delimitar estos rangos máximos y mínimos esperados con rigor matemático permite cuantificar riesgos térmicos extremos. Esta información resulta clave para la toma de decisiones preventivas en la región.

library(forecast)
library(knitr)

pronostico_final <- forecast(modelo4, h = 24, level = c(80, 95))

tabla_pronostico_m4 <- data.frame(
  Índice = rownames(as.data.frame(pronostico_final)),
  `Pronóstico (Point Forecast)` = round(pronostico_final$mean, 4),
  `Lo 80` = round(pronostico_final$lower[, 1], 4),
  `Hi 80` = round(pronostico_final$upper[, 1], 4),
  `Lo 95` = round(pronostico_final$lower[, 2], 4),
  `Hi 95` = round(pronostico_final$upper[, 2], 4),
  check.names = FALSE
)

kable(tabla_pronostico_m4, 
      caption = "Pronóstico para las Próximas 24 Horas con Intervalos de Confianza (80% y 95%)", 
      align = "c")
Pronóstico para las Próximas 24 Horas con Intervalos de Confianza (80% y 95%)
Índice Pronóstico (Point Forecast) Lo 80 Hi 80 Lo 95 Hi 95
29253601 25.9882 24.9591 27.0173 24.4144 27.5620
29257201 25.7191 24.0160 27.4221 23.1145 28.3236
29260801 25.7392 23.5419 27.9366 22.3787 29.0998
29264401 26.0406 23.4653 28.6159 22.1021 29.9791
29268001 26.5967 23.7534 29.4401 22.2483 30.9452
29271601 27.3603 24.3388 30.3819 22.7393 31.9814
29275201 28.2734 25.1493 31.3975 23.4955 33.0513
29278801 29.2685 26.0971 32.4399 24.4182 34.1188
29282401 30.2758 27.0910 33.4605 25.4051 35.1464
29286001 31.2264 28.0413 34.4116 26.3552 36.0977
29289601 32.0582 28.8689 35.2476 27.1805 36.9360
29293201 32.7189 29.5120 35.9258 27.8144 37.6234
29296801 33.1697 29.9307 36.4086 28.2161 38.1232
29300401 33.3872 30.1074 36.6670 28.3712 38.4032
29304001 33.3649 30.0447 36.6852 28.2870 38.4428
29307601 33.1125 29.7607 36.4644 27.9863 38.2388
29311201 32.6551 29.2851 36.0251 27.5011 37.8091
29314801 32.0306 28.6549 35.4063 26.8679 37.1933
29318401 31.2872 27.9114 34.6629 26.1244 36.4499
29322001 30.4791 27.0980 33.8602 25.3081 35.6501
29325601 29.6634 26.2591 33.0677 24.4570 34.8698
29329201 28.8955 25.4401 32.3509 23.6109 34.1800
29332801 28.2257 24.6869 31.7645 22.8136 33.6378
29336401 27.6960 24.0442 31.3478 22.1111 33.2809
library(forecast)
library(ggplot2)

modelo4 %>%
  forecast(h = 24) %>%
  autoplot(include = 168)

Al generar la proyección definitiva con la serie completa (Temperatura2), los valores cambiaron debido a que el modelo cuenta con más información histórica: ahora arranca en un mínimo de 25.98°C y alcanza un pico máximo de 33.38°C (un grado más alto que en la simulación). Sin embargo, el comportamiento de fondo confirma la misma deficiencia del enfoque tradicional; el ARIMA(4,1,3) logra simular la primera onda de calor diurna gracias a su memoria de corto plazo, pero al avanzar las horas la predicción se rinde, convirtiéndose en una línea totalmente recta y plana que se estanca en 27.69°C e ignora el descenso térmico natural de la madrugada. Esto, sumado a unas bandas de confianza que se abren de forma exagerada, demuestra que el modelo es muy preciso para estimar las próximas 3 a 5 horas, pero pierde toda validez técnica para planeaciones a mediano o largo plazo.

5. Conclusiones

El desarrollo de este taller permitió aplicar la metodología Box-Jenkins para el modelado y pronóstico de la temperatura de Cali, extrayendo las siguientes conclusiones fundamentales desde una perspectiva estadística y de ingeniería:

1. Insuficiencia de los Modelos ARIMA Tradicionales para Variables Climatológica

A pesar de que el modelo ARIMA(4,1,3) fue seleccionado de manera rigurosa por minimizar simultáneamente los criterios de información de Akaike (AIC) y Bayesiano (BIC) bajo el principio de parsimonia, el diagnóstico posterior demostró que la estructura clásica es insuficiente. El modelo logró absorber con éxito la memoria lineal de corto plazo, pero fue completamente incapaz de capturar la fuerte estacionalidad diaria con ciclo de 24 horas intrínseca al clima local.

2. Falla en el Supuesto de Ruido Blanco

La prueba formal de Box-Pierce-Ljung arrojó un p-valor de 0, lo que llevó al rechazo categórico de la hipótesis nula de independencia. Visualmente, la función de autocorrelación simple (ACF) de los residuos confirmó este hallazgo al presentar múltiples picos estacionales que sobresalen severamente de las bandas de confianza de color azul. Esto implica que los errores aún contienen información estructurada no explicada, por lo que el modelo ARIMA(4,1,3) no es estadísticamente adecuado para la inferencia definitiva.

3. Impacto de las Limitaciones en el Pronóstico

La consecuencia directa de omitir el componente estacional se evidenció al proyectar el horizonte de corto plazo para las próximas 24 observaciones. La estimación puntual se tradujo en una línea recta horizontal estancada por la inercia del nivel de las últimas mediciones reales. Al carecer de las oscilaciones cíclicas naturales (picos de calor en el día y descensos en la noche), el modelo pierde precisión y utilidad práctica para proyecciones detalladas hora a hora.

4. Calidad de los Datos y Vulnerabilidad del Historial

La fase de control inicial identificó la presencia de registros faltantes y un vacío de información considerable durante el primer trimestre del año. Aunque el tratamiento aplicado permitió limpiar la serie y viabilizar los algoritmos de estimación en R, estos baches temporales prolongados representan una vulnerabilidad en la continuidad meteorológica que puede alterar la varianza global del proceso estocástico y sesgar las estimaciones estructurales.

Al separar los datos y generar la proyección definitiva permitió evaluar el alcance real del modelo mediante el análisis de registros fuera de la muestra. Por una parte,se tiene que durante la fase de validación (backtesting), se logro observar que el (RMSE) se triplicó al pasar de 0.80°C en el conjunto de entrenamiento a 2.15°C en el de prueba, lo que se evidenció que el buen ajuste inicial con los datos históricos no garantizaba la misma precisión de cara al futuro. Por otra parte, al ejecutar el pronóstico final con la serie completa, el algoritmo ajustó sus cálculos y proyectó una primera curva con una temperatura mínima de 25.98°C y un pico máximo de 33.38°C para las horas del mediodía. Sin embargo, debido a la falta de un componente estacional, la capacidad de predicción de la estructura ARIMA(4,1,3) se agotó rápidamente, tras simular la primera onda de calor, la trayectoria se convirtió en una línea plana estancada en los 27.69°C, siendo incapaz de replicar el descenso natural de la temperatura durante la madrugada en Cali.

6. Bibliografia