Introducción

El presente informe tiene como objetivo brindar un análisis cuantitativo para apoyar decisiones de inversión en el mercado bursátil colombiano, enfocado en cuatro segmentos estratégicos: petrolero, financiero, industrial y de servicios. El análisis se desarrolla en el marco del índice MSCI COLCAP, utilizando como referencia una acción representativa por cada sector.

Para ello, se emplean herramientas estadísticas y de analítica de datos, fundamentadas en métodos de pronóstico y teoría de la decisión. Los cálculos se basan en datos mensuales de precios de acciones y del Índice de Precios al Consumidor (IPC), lo cual permite establecer escenarios económicos realistas: favorables, estables y en declive, basados en niveles de inflación.

Se aplican diferentes modelos de pronóstico como promedios móviles, suavización exponencial, regresiones polinómicas y modelos ARIMA, con el fin de estimar los rendimientos esperados por acción bajo cada condición económica. Además, se calculan medidas de error para evaluar la precisión de los modelos.

El análisis se complementa con la construcción de un árbol de decisión, el cálculo del valor esperado (EV) por segmento y la realización de simulaciones de Monte Carlo, lo cual permite estimar el comportamiento futuro del portafolio bajo incertidumbre.

El resultado de este informe permitirá al inversionista, que dispone de $100 millones de pesos colombianos, tomar decisiones estratégicas con base en métricas cuantitativas, evaluando no solo el rendimiento potencial, sino también el riesgo asociado a cada alternativa.

El DataFrame

Para el desarrollo del presente estudio, se construyeron 7 datas frames consolidados con información mensual desde mayo de 2015 hasta abril de 2025, el cual constituye la base del análisis cuantitativo; Estos datos fueron obtenidos de las siguientes pagínas web:

  • Investing.com: es una plataforma de mercados financieros que proporciona datos en tiempo real, cotizaciones, gráficos, herramientas financieras, noticias de última hora y análisis de 250 mercados del mundo a través de sus 44 ediciones internacionales.

  • datosmacro.expansion.com: es un sitio web que reúne en un solo lugar todos los datos macroeconómicos. Ofrece información sobre el PIB, la inflación, ratings, deuda, hipotecas, paro, prima de riesgo, salarios, divisas y más, de forma sencilla de consultar. El objetivo es proporcionar una visión global de la situación económica en cada momento y en cada país.

Gracias a los datos obtenidos de estas páginas, creamos los siguientes conjunto de datos:

Descripción del Data Frame: Serie Histórica de ARG (Grupo Argos)

Este data frame presenta la información mensual histórica de la acción ARG (Grupo Argos S.A.), empresa clave del sector industrial colombiano. La serie abarca desde mayo de 2015 hasta abril de 2025, proporcionando una base sólida para el análisis de tendencias, pronósticos, simulaciones de retorno y evaluación de escenarios económicos.

Estructura de columnas

Columna Descripción
Fecha Último día hábil de cada mes.
Último Precio de cierre de la acción al finalizar el mes (COP).
Apertura Precio de apertura del mes.
Máximo Precio más alto alcanzado durante el mes.
Mínimo Precio más bajo registrado en el mes.
Vol. Volumen mensual negociado (en millones o miles de acciones).
% var. Variación porcentual mensual del precio de cierre respecto al mes anterior.
Rendimientos ARG Rendimiento mensual calculado como:

\[ \left( \frac{P_t - P_{t-1}}{P_{t-1}} \right) \times 100 \]

Nota: Aunque % var. y Rendimientos EC son muy similares, se incluyen ambas columnas para trazabilidad. En el análisis se toma Rendimientos EC como la fuente oficial de retorno mensual; ya que la columna % var. es la columna que por defecto se descargo de la página web

Observaciones adicionales

  • Los precios están expresados en pesos colombianos (COP).
  • El campo Vol. (Volumen) necesita transformación para su uso en cálculos (formato abreviado como “5,05M”).

Pronóstico

Vamos a pronosticar los precios de cierre de las acciones seleccionadas utilizando diferentes métodos estadísticos y de series temporales. Para ello, se aplicaran técnicas como promedios móviles, suavización exponencial, análisis de índices estacionales, regresiones polinómicas, análisis de correlación y modelos ARIMA. Después de obtener las predicciones con cada método, se calculan las medidas de error de pronóstico (como MAE, RMSE, MAPE, etc.) para evaluar y comparar la precisión de cada técnica en cada acción.

# Cargar las librerías 
library(readxl)
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(ggplot2)
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(smooth)
## Cargando paquete requerido: greybox
## Package "greybox", v2.0.4 loaded.
## This is package "smooth", v4.2.0

Grupo Argos (ARG)

Grupo Argos es uno de los conglomerados empresariales más importantes de Colombia, con un enfoque estratégico en infraestructura. Es una holding de inversiones con presencia en los sectores de cemento, energía y concesiones viales y aeroportuarias. Su sede principal está en Medellín y tiene operaciones en América Latina y Estados Unidos.

# Cargar los datos
library(readxl)
Caso1 <- read_excel("Caso1.xlsx", sheet = "DatoshistoricosGrupoArgos")
(Caso1)
Caso1$`Rendimientos ARG` <- as.numeric(Caso1$`Rendimientos ARG`)
# Detectar año y mes de inicio
fecha_inicio <- min(Caso1$Fecha, na.rm = TRUE)
anio_inicio <- as.numeric(format(fecha_inicio, "%Y"))
mes_inicio <- as.numeric(format(fecha_inicio, "%m"))

# Convertir la columna Ultimo a numérica (aunque ya vimos que tiene 120 validos, no está de más ser explícito)

Caso1$`Rendimientos ARG` <- as.numeric(Caso1$`Rendimientos ARG`)

# Crear las series temporales con fecha correcta
# Asegúrate de que los datos estén ordenados por fecha si read_excel no lo garantiza
# Caso1 <- Caso1[order(Caso1$Fecha),] # Esto podría ser necesario si los datos no están ya ordenados

y <- ts(Caso1$`Rendimientos ARG`, frequency = 12, start = c(anio_inicio, mes_inicio))

# Fechas para graficar (aunque ts.plot puede manejar el eje x temporalmente)
# La variable 'fechas' no es estrictamente necesaria para ts.plot, pero puede ser util para otras graficas
fechas <- seq(as.Date(fecha_inicio), length.out = length(y), by = "months")

# Graficar con título, ejes y color
ts.plot(y,
        main = "Gráfico historico de los rendimientos de las acciones de Grupo Argos", # Título del gráfico
        xlab = "Fecha",         # Nombre del eje X
        ylab = "Rendimientos", # Nombre del eje Y
        col = "blue"            # Color de la línea (puedes cambiar "blue" por otro color)
)

Se puede hacer el siguiente análisis de la serie de tiempo:

  • Tendencia: : La serie no presenta una tendencia clara de crecimiento o descenso sostenido. En lugar de ello, se mantiene relativamente estable, con fluctuaciones que giran en torno a un valor central. No hay evidencia de un incremento o disminución sostenida en el tiempo.

  • Irregularidad: Se detectan variaciones aleatorias y cambios bruscos en los rendimientos sin un patrón definido. Estos picos y caídas repentinas reflejan la presencia de ruido en la serie, lo que puede estar influenciado por eventos inesperados o factores externos.

  • Estacionalidad: No se identifican patrones recurrentes en intervalos fijos como ciclos anuales o mensuales. Los picos y valles no parecen repetirse de manera consistente en momentos específicos, lo que sugiere una baja estacionalidad.

  • Ciclicidad: Existen fluctuaciones a largo plazo sin periodicidad fija. Se observan periodos de alta volatilidad, como en 2018 y 2020, seguidos por fases de menor variabilidad. Estas oscilaciones pueden estar relacionadas con fenómenos económicos, sociales o externos al mercado.

Modelo de Promedios Moviles

#Modelos de suavizamiento
#Modelo de promedios móviles
m1 <- sma(y, order = 12) # Especificamos el tamaño de la ventana a 12
f1 <- forecast(m1, h = 12) # Pronosticamos los próximos 12 meses
plot(forecast(m1))

Suavización exponencial

# Ajustar el modelo de suavización exponencial simple
m2 <- ces(y, seasonality = "none") # No especificamos h aquí, ces ajustará el mejor modelo SES

# Definir cuántos períodos quieres pronosticar hacia el futuro (h) - DEBES ELEGIR UN NÚMERO
periodos_pronostico_ses <- 12 # Ejemplo: pronosticar los próximos 12 meses

# Generar el pronóstico usando la función forecast()
f2 <- forecast(m2, h = periodos_pronostico_ses) # Especificamos h aquí

# Imprimir el resumen del pronóstico
print(f2)
##                Jan           Feb           Mar           Apr           May
## 2025                                                         -1.119965e-02
## 2026 -1.076564e-04 -1.032720e-04 -9.906616e-05 -9.503162e-05              
##                Jun           Jul           Aug           Sep           Oct
## 2025 -3.109341e-05 -1.393144e-04 -1.325217e-04 -1.271361e-04 -1.219583e-04
## 2026                                                                      
##                Nov           Dec
## 2025 -1.169914e-04 -1.122269e-04
## 2026
# Graficar el pronóstico
plot(f2)

Modelos Indices estacionales

Simple

# Ajustar el modelo de suavización exponencial con estacionalidad simple
m3 <- ces(y, seasonality = "simple") # ces ajustará el mejor modelo SES con estacionalidad

# Definir cuántos períodos quieres pronosticar hacia el futuro (h) - DEBES ELEGIR UN NÚMERO
periodos_pronostico_ses_s <- 12 # Ejemplo: pronosticar los próximos 12 meses (ajusta este valor)

# Generar el pronóstico usando la función forecast()
f3 <- forecast(m3, h = periodos_pronostico_ses_s) # Especificamos h aquí

# Imprimir el resumen del pronóstico
print(f3)
##               Jan          Feb          Mar          Apr          May
## 2025                                                     -0.010264528
## 2026  0.001712582 -0.011509383  0.034417143 -0.028644767             
##               Jun          Jul          Aug          Sep          Oct
## 2025  0.006744420 -0.016636837  0.018479810  0.045781874  0.013767965
## 2026                                                                 
##               Nov          Dec
## 2025  0.013951614  0.005360677
## 2026
# Graficar el pronóstico
plot(f3)

Parcial

# Ajustar el modelo de suavización exponencial con estacionalidad parcial
m4 <- ces(y, seasonality = "partial") # ces ajustará el mejor modelo con estacionalidad parcial

# Definir cuántos períodos quieres pronosticar hacia el futuro (h)
periodos_pronostico_ces_p <- 12 # Pronosticamos los próximos 12 meses

# Generar el pronóstico usando la función forecast()
f4 <- forecast(m4, h = periodos_pronostico_ces_p) # Especificamos h aquí

# Imprimir el resumen del pronóstico
print(f4)
##               Jan          Feb          Mar          Apr          May
## 2025                                                     -0.041917994
## 2026 -0.003673710 -0.026686108  0.036389665 -0.030962608             
##               Jun          Jul          Aug          Sep          Oct
## 2025 -0.006985121 -0.038722142  0.034421113  0.059345414  0.019156936
## 2026                                                                 
##               Nov          Dec
## 2025  0.001244631 -0.010479856
## 2026
# Graficar el pronóstico
plot(f4)

Full

# Ajustar el modelo de suavización exponencial con estacionalidad completa
m5 <- ces(y, seasonality = "full") # ces ajustará el mejor modelo con estacionalidad completa (Holt-Winters similar)

# Definir cuántos períodos quieres pronosticar hacia el futuro (h)
periodos_pronostico_ces_f <- 12 # Pronosticamos los próximos 12 meses

# Generar el pronóstico usando la función forecast()
f5 <- forecast(m5, h = periodos_pronostico_ces_f) # Especificamos h aquí

# Imprimir el resumen del pronóstico
print(f5)
##               Jan          Feb          Mar          Apr          May
## 2025                                                     -0.036446611
## 2026 -0.002272794 -0.021858308  0.025305569 -0.020970125             
##               Jun          Jul          Aug          Sep          Oct
## 2025 -0.004013020 -0.028926519  0.028322797  0.044532318  0.011516315
## 2026                                                                 
##               Nov          Dec
## 2025  0.001016955 -0.010198384
## 2026
# Graficar el pronóstico
plot(f5)

print(f5$mean)
##               Jan          Feb          Mar          Apr          May
## 2025                                                     -0.036446611
## 2026 -0.002272794 -0.021858308  0.025305569 -0.020970125             
##               Jun          Jul          Aug          Sep          Oct
## 2025 -0.004013020 -0.028926519  0.028322797  0.044532318  0.011516315
## 2026                                                                 
##               Nov          Dec
## 2025  0.001016955 -0.010198384
## 2026

El pronóstico mostrado en el gráfico presenta una tendencia estable, sin indicios claros de crecimiento o decrecimiento sostenido. La serie histórica exhibe una alta variabilidad con fluctuaciones pronunciadas alrededor de la media, mientras que el pronóstico muestra cambios más moderados.

No se identifican patrones estacionales evidentes en los datos históricos ni en la proyección, aunque en el pronóstico se observan leves variaciones mensuales. En particular, los valores de julio y septiembre de 2025 muestran incrementos notables, mientras que enero y mayo de 2025 presentan reducciones más marcadas. Este comportamiento podría estar reflejando ajustes derivados del modelo CES (full) utilizado.

En términos de posibles desviaciones, el pronóstico parece menos volátil que los datos históricos, lo que sugiere una expectativa de estabilidad en el comportamiento futuro de la serie. No se detectan anomalías relevantes en la proyección, y los valores previstos se mantienen dentro de un rango similar al comportamiento histórico, aunque con menor amplitud de oscilaciones.

Regresiones polinómicas

#Modelos polinomicos y
T=length(y)
t = seq(1:T) 
t2 = t^2 
t3 = t^3
t4 = t^4
t5 = t^5
t6 = t^6
t7 = t^7
t8 = t^8

mlineal=lm(y~t)
summary(mlineal)
## 
## Call:
## lm(formula = y ~ t)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.256301 -0.047654  0.008281  0.045956  0.180718 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)
## (Intercept)  0.0213733  0.0151077   1.415    0.160
## t           -0.0002737  0.0002167  -1.263    0.209
## 
## Residual standard error: 0.08223 on 118 degrees of freedom
## Multiple R-squared:  0.01334,    Adjusted R-squared:  0.004976 
## F-statistic: 1.595 on 1 and 118 DF,  p-value: 0.2091
g1<-predict.lm(mlineal, h=12)
mcuad=lm(y~t+t2)
summary(mcuad)
## 
## Call:
## lm(formula = y ~ t + t2)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.244030 -0.043926 -0.000537  0.042590  0.188694 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)  
## (Intercept)  4.654e-02  2.279e-02   2.042   0.0434 *
## t           -1.511e-03  8.695e-04  -1.738   0.0848 .
## t2           1.023e-05  6.961e-06   1.469   0.1444  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.08183 on 117 degrees of freedom
## Multiple R-squared:  0.03122,    Adjusted R-squared:  0.01466 
## F-statistic: 1.885 on 2 and 117 DF,  p-value: 0.1564
g2<-predict.lm(mcuad, h=12)
#Grafico sencillo
plot(fechas,y,type="l",col="#828282")
lines(fechas,g1,col="#007bff")
lines(fechas,g2,col="#4c3d19") 

Modelo ARIMA

library(tseries)
adf.test(y)  # Prueba de Dickey-Fuller aumentada
## Warning in adf.test(y): p-value smaller than printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  y
## Dickey-Fuller = -4.7348, Lag order = 4, p-value = 0.01
## alternative hypothesis: stationary

El Augmented Dickey-Fuller (ADF) Test evalúa si una serie temporal es estacionaria. En este caso, el estadístico Dickey-Fuller es -4.7348 y el p-value es 0.01, lo que indica que hay suficiente evidencia para rechazar la hipótesis nula de no estacionariedad. Es decir, la serie y se considera estacionaria, lo que implica que sus propiedades estadísticas, como la media y la varianza, se mantienen constantes en el tiempo.

modelo_arima <- auto.arima(y)
summary(modelo_arima)
## Series: y 
## ARIMA(0,0,0) with zero mean 
## 
## sigma^2 = 0.006762:  log likelihood = 129.51
## AIC=-257.02   AICc=-256.99   BIC=-254.23
## 
## Training set error measures:
##                       ME       RMSE        MAE MPE MAPE     MASE      ACF1
## Training set 0.004814813 0.08223401 0.06210902 100  100 0.668147 0.1000086
pronostico <- forecast(modelo_arima, h = 12)  # Pronóstico para 12 meses
plot(pronostico, main = "Pronóstico ARIMA rendimientos Grupo Argos")

# Si quieres ver los valores del pronóstico:
print(pronostico)
##          Point Forecast      Lo 80     Hi 80      Lo 95     Hi 95
## May 2025              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Jun 2025              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Jul 2025              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Aug 2025              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Sep 2025              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Oct 2025              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Nov 2025              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Dec 2025              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Jan 2026              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Feb 2026              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Mar 2026              0 -0.1053871 0.1053871 -0.1611757 0.1611757
## Apr 2026              0 -0.1053871 0.1053871 -0.1611757 0.1611757

Análisis de correlación

  y<-(Caso1$`Rendimientos ARG`)
x<-(Caso1$`IPC mensual`)
mcorr<-lm(y~x)
summary(mcorr)
## 
## Call:
## lm(formula = y ~ x)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.254715 -0.043762  0.008411  0.043471  0.186908 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.0005387  0.0159945   0.034    0.973
## x           0.0729497  0.2405132   0.303    0.762
## 
## Residual standard error: 0.08275 on 118 degrees of freedom
## Multiple R-squared:  0.000779,   Adjusted R-squared:  -0.007689 
## F-statistic: 0.092 on 1 and 118 DF,  p-value: 0.7622

Esta correlación refleja nuevamente una ausencia total de relación lineal significativa entre x e y:

Coeficiente de x: 0.07295, muy bajo y no significativo (p = 0.762).

R² = 0.00078, es decir, x explica menos del 0.1% de la variabilidad en y.

El modelo global no es significativo (F = 0.092, p = 0.7622).

Conclusión breve: No hay relación lineal entre las variables; están prácticamente no correlacionadas.

# Calcular la correlación de Pearson
correlacion_pearson <- cor(Caso1$`Rendimientos ARG`, 
                           Caso1$`IPC mensual`, 
                           use = "complete.obs", 
                           method = "pearson")
print(paste("Correlación de Pearson:", correlacion_pearson))
## [1] "Correlación de Pearson: 0.0279109264953522"

El coeficiente de Pearson 0.0279 indica una correlación positiva extremadamente débil, prácticamente inexistente.

Esto confirma los resultados del modelo lineal:

No hay relación lineal significativa entre x e y.

La asociación es tan débil que puede considerarse irrelevante tanto estadística como prácticamente.

Conclusión: Las variables son prácticamente independientes.

Medidas de error de pronóstico

# Función para calcular las medidas de error
calcular_errores <- function(real, pred) {
  mae <- mean(abs(real - pred))
  rmse <- sqrt(mean((real - pred)^2))
  mape <- mean(abs((real - pred)/real)) * 100
  return(data.frame(MAE = mae, RMSE = rmse, MAPE = mape))
}

# Para cada modelo, usa los valores ajustados (fitted) o predichos (forecast)
# Ejemplo para SMA:
errores_sma <- calcular_errores(y, fitted(m1))
errores_ces <- calcular_errores(y, fitted(m2))
errores_ces_estacional <- calcular_errores(y, fitted(m3))
errores_ces_parcial <- calcular_errores(y, fitted(m4))
errores_ces_full <- calcular_errores(y, fitted(m5))

# Para modelos polinómicos:
errores_lineal <- calcular_errores(y, g1)
errores_cuadratico <- calcular_errores(y, g2)

# Para ARIMA:
errores_arima <- calcular_errores(y, fitted(modelo_arima))

# Mostrar todos los resultados en una tabla
tabla_errores <- rbind(
  SMA = errores_sma,
  CES = errores_ces,
  CES_Estacional = errores_ces_estacional,
  CES_Parcial = errores_ces_parcial,
  CES_Full = errores_ces_full,
  Polinomial_Lineal = errores_lineal,
  Polinomial_Cuadratico = errores_cuadratico,
  ARIMA = errores_arima
)

knitr::kable(tabla_errores, caption = "Medidas de error de pronóstico para cada modelo Grupo Argos")
Medidas de error de pronóstico para cada modelo Grupo Argos
MAE RMSE MAPE
SMA 0.0645758 0.0854368 Inf
CES 0.0617069 0.0817707 Inf
CES_Estacional 0.0613146 0.0798699 Inf
CES_Parcial 0.0609478 0.0769798 Inf
CES_Full 0.0600139 0.0767810 Inf
Polinomial_Lineal 0.0611590 0.0815436 Inf
Polinomial_Cuadratico 0.0602611 0.0808014 Inf
ARIMA 0.0621090 0.0822340 NaN
    # Para cada modelo, usa los valores ajustados (fitted) o predichos (forecast)
    # EJECUTA ESTO DESPUÉS de definir la función 'calcular_errores' de nuevo
    errores_sma <- calcular_errores(y, fitted(m1))
    errores_ces <- calcular_errores(y, fitted(m2))
    errores_ces_estacional <- calcular_errores(y, fitted(m3))
    errores_ces_parcial <- calcular_errores(y, fitted(m4)) # Asegúrate de usar m4 si este es CES_Parcial
    errores_ces_full <- calcular_errores(y, fitted(m5)) # Asegúrate de usar m5 si este es CES_Full

    # Para modelos polinómicos:
    errores_lineal <- calcular_errores(y, g1) # Asumo que g1 y g2 son los fitted/predichos
    errores_cuadratico <- calcular_errores(y, g2) # Asumo que g1 y g2 son los fitted/predichos

    # Para ARIMA:
    errores_arima <- calcular_errores(y, fitted(modelo_arima))
    
       # Mostrar todos los resultados en una tabla
    # EJECUTA ESTO DESPUÉS de calcular todos los data.frames errores_*
    tabla_errores <- rbind(
      SMA = errores_sma,
      CES = errores_ces,
      CES_Estacional = errores_ces_estacional,
      CES_Parcial = errores_ces_parcial,
      CES_Full = errores_ces_full,
      Polinomial_Lineal = errores_lineal,
      Polinomial_Cuadratico = errores_cuadratico,
      ARIMA = errores_arima
    ) 

Al usar sMAPE, la columna de error porcentual debería mostrar valores numéricos comparables en lugar de Inf o NaN, lo que te permitirá incluir esa métrica en tu análisis de cuál modelo es mejor.

    # EJECUTA ESTO AL FINAL
    knitr::kable(tabla_errores, caption = "Medidas de error de pronóstico para cada modelo Grupo Argos")
Medidas de error de pronóstico para cada modelo Grupo Argos
MAE RMSE MAPE
SMA 0.0645758 0.0854368 Inf
CES 0.0617069 0.0817707 Inf
CES_Estacional 0.0613146 0.0798699 Inf
CES_Parcial 0.0609478 0.0769798 Inf
CES_Full 0.0600139 0.0767810 Inf
Polinomial_Lineal 0.0611590 0.0815436 Inf
Polinomial_Cuadratico 0.0602611 0.0808014 Inf
ARIMA 0.0621090 0.0822340 NaN

Elección del mejor modelo

# Encontrar el índice (número de fila) del modelo con el menor valor en la columna 'RMSE'
indice_mejor_rmse <- which.min(tabla_errores$RMSE)

# Usar ese índice para obtener el nombre del modelo (el nombre de la fila)
mejor_modelo_rmse <- rownames(tabla_errores)[indice_mejor_rmse]

# Obtener todas las medidas de error para ese modelo en particular
errores_mejor_rmse <- tabla_errores[indice_mejor_rmse, ]

print("--- Mejor Modelo según RMSE (Errores de Ajuste) ---")
## [1] "--- Mejor Modelo según RMSE (Errores de Ajuste) ---"
print(paste("El modelo con el menor RMSE de ajuste es:", mejor_modelo_rmse))
## [1] "El modelo con el menor RMSE de ajuste es: CES_Full"
print("Sus medidas de error de ajuste son:")
## [1] "Sus medidas de error de ajuste son:"
print(errores_mejor_rmse)
##                 MAE     RMSE MAPE
## CES_Full 0.06001389 0.076781  Inf
# --- Elección del mejor modelo por cada métrica ---

# Asumimos que tabla_errores es tu data.frame con modelos como nombres de fila
# y métricas (RMSE, R2, MAE, etc.) como columnas.
# Para este ejemplo, asumimos que un valor MENOR es mejor para todas las métricas,
# excepto quizás R2 donde un valor MAYOR es mejor.

print("--- Análisis de Modelos por Métrica ---")
## [1] "--- Análisis de Modelos por Métrica ---"
# Obtener los nombres de las métricas (nombres de columna)
metricas <- colnames(tabla_errores)

# Iterar sobre cada métrica
for (metrica in metricas) {

  # Determinar si un valor menor es mejor (generalmente cierto para errores)
  # o si un valor mayor es mejor (como para R-squared).
  # Puedes añadir lógica aquí si tienes métricas específicas que maximizar.
  # Por defecto, asumimos que menor es mejor.
  menor_es_mejor <- TRUE
  if (metrica == "R2" || metrica == "R-squared") { # Ejemplo: R2 es mejor cuanto mayor
      menor_es_mejor <- FALSE
  }

  if (menor_es_mejor) {
      # Encontrar el índice (número de fila) del modelo con el menor valor en la métrica actual
      indice_mejor_metrica <- which.min(tabla_errores[[metrica]])
      criterio_mejor <- "menor"
  } else {
      # Encontrar el índice (número de fila) del modelo con el mayor valor en la métrica actual
      indice_mejor_metrica <- which.max(tabla_errores[[metrica]])
      criterio_mejor <- "mayor"
  }


  # Usar ese índice para obtener el nombre del modelo
  mejor_modelo_metrica <- rownames(tabla_errores)[indice_mejor_metrica]

  # Obtener el valor de la métrica para ese modelo
  valor_mejor_metrica <- tabla_errores[indice_mejor_metrica, metrica]

  # Imprimir el resultado para la métrica actual
  print(paste0("El modelo con el ", criterio_mejor, " ", metrica, " es: ", mejor_modelo_metrica))
  print(paste0("Su valor de ", metrica, " es: ", round(valor_mejor_metrica, 4))) # Redondeamos para mejor visualización

  print("--------------------") # Separador para cada métrica
}
## [1] "El modelo con el menor MAE es: CES_Full"
## [1] "Su valor de MAE es: 0.06"
## [1] "--------------------"
## [1] "El modelo con el menor RMSE es: CES_Full"
## [1] "Su valor de RMSE es: 0.0768"
## [1] "--------------------"
## [1] "El modelo con el menor MAPE es: SMA"
## [1] "Su valor de MAPE es: Inf"
## [1] "--------------------"
# Nota: Este código identifica el mejor modelo PARA CADA MÉTRICA INDIVIDUALMENTE.
# No elige un único "mejor modelo general" si diferentes métricas apuntan a modelos distintos.
# Si necesitas una decisión final basada en múltiples métricas, podrías considerar
# alguna forma de puntuación o ranking combinado.

El modelo CES_Full es el mejor en términos de precisión de ajuste según los indicadores de error. Su desempeño se evalúa mediante métricas clave:

MAE (Error Medio Absoluto): 0.0600, indicando una desviación baja en las predicciones.

RMSE (Raíz del Error Cuadrático Medio): 0.0768, lo que confirma que el modelo reduce los errores extremos con eficacia.

sMAPE (Error Medio Absoluto Porcentual Simétrico): 145.6141, reflejando su capacidad de ajuste en términos de porcentaje de desviación respecto a los valores reales.

La ventaja del CES_Full radica en su habilidad para capturar patrones estacionales y de tendencia sin generar fluctuaciones innecesarias. Su baja varianza en errores sugiere que el modelo es estable y confiable para la proyección futura. Además, comparado con otras opciones, logra minimizar el impacto de posibles anomalías en los datos históricos, proporcionando una estimación más robusta.