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.
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:
Este data frame contiene la evolución mensual de la acción GEB (Grupo Energía Bogotá S.A. ESP), una de las principales empresas del sector de servicios públicos en Colombia. La serie histórica va desde mayo de 2015 hasta abril de 2025, proporcionando información confiable y continua para análisis de tendencias, pronósticos de precios y simulaciones financieras.
Columna | Descripción |
---|---|
Fecha |
Último día hábil de cada mes. |
Último |
Precio de cierre mensual de la acción (COP). |
Apertura |
Precio de apertura del mes. |
Máximo |
Precio más alto registrado durante el mes. |
Mínimo |
Precio más bajo del mes. |
Vol. |
Volumen negociado en el mes (en millones o miles de acciones). |
% var. |
Porcentaje de variación del precio de cierre respecto al mes anterior. |
Rendimientos GEB |
Rendimiento mensual efectivo, calculado como: |
\[ \left( \frac{P_t - P_{t-1}}{P_{t-1}} \right) \times 100 \]
Nota: Aunque
% var.
yRendimientos EC
son muy similares, se incluyen ambas columnas para trazabilidad. En el análisis se tomaRendimientos 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
Último
, Apertura
,
etc.) están en pesos colombianos (COP).Vol.
puede estar abreviado (“15,95M”),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.
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
##
## 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
## Cargando paquete requerido: greybox
## Package "greybox", v2.0.4 loaded.
## This is package "smooth", v4.2.0
Grupo Energía Bogotá (GEB) es una empresa multilatina con más de 128 años de historia, especializada en la transmisión y distribución de energía eléctrica, así como en el transporte y distribución de gas natural. Con operaciones en Colombia, Perú, Brasil y Guatemala, GEB se ha consolidado como un actor clave en el sector energético de América Latina.
# Cargar los datos
library(readxl)
Caso1 <- read_excel("Caso1.xlsx", sheet = "DatoshistoricosGrupoEnergia ")
(Caso1)
# 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 GEB` <- as.numeric(Caso1$`Rendimientos GEB`)
# 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 GEB`, 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 Energia Bogota", # 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 muestra una tendencia clara de aumento o disminución a lo largo del tiempo. Los rendimientos oscilan alrededor de un valor cercano a cero, sin evidencia de un crecimiento sostenido ni un descenso prolongado. Esto sugiere que los valores se mantienen relativamente estables en términos de tendencia a largo plazo.
Irregularidad: La serie presenta variaciones impredecibles, con picos y caídas repentinas que no parecen explicarse por los otros componentes. Este comportamiento es común en series de tiempo financieras, donde el mercado responde a eventos inesperados, cambios en la percepción de los inversionistas o factores externos.
Estacionalidad: No se observan patrones recurrentes que indiquen estacionalidad clara en la serie. Los picos y valles parecen aparecer en momentos variados, sin repetirse en intervalos específicos como anual, mensual o diario. Esto sugiere que no hay una componente estacional definida que influya en los rendimientos de estas acciones.
Ciclicidad: Se pueden notar fluctuaciones a largo plazo, pero no ocurren en intervalos fijos. Estas variaciones pueden estar relacionadas con factores económicos, sociales o del mercado que afectan los rendimientos de Grupo Energía Bogotá. Hay períodos de alta volatilidad seguidos de otros más estables, lo que puede asociarse con dinámicas cíclicas del sector energético o del mercado financiero.
#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))
# 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 Jun
## 2025 0.004928441 0.005059199
## 2026 0.004896102 0.004873135 0.004850276 0.004827523
## Jul Aug Sep Oct Nov Dec
## 2025 0.005036192 0.005012571 0.004989058 0.004965655 0.004942361 0.004919177
## 2026
# 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.0123341303
## 2026 0.0090465264 -0.0003695001 -0.0095514168 -0.0023662357
## Jun Jul Aug Sep Oct
## 2025 0.0151613689 0.0121670257 0.0227213900 -0.0064271089 -0.0011163803
## 2026
## Nov Dec
## 2025 0.0003588845 0.0082673157
## 2026
# 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.029494643
## 2026 0.012046788 -0.014868247 -0.003258130 -0.012552047
## Jun Jul Aug Sep Oct
## 2025 0.027441759 -0.006020594 0.032081531 -0.007016966 0.016658838
## 2026
## Nov Dec
## 2025 -0.028232248 0.015210184
## 2026
# 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.002757159
## 2026 0.004225663 0.002869495 -0.017034362 -0.009385820
## Jun Jul Aug Sep Oct
## 2025 0.017897399 0.010639456 0.005927950 -0.002605119 -0.018959724
## 2026
## Nov Dec
## 2025 0.002287816 0.009019153
## 2026
## Jan Feb Mar Apr May
## 2025 0.002757159
## 2026 0.004225663 0.002869495 -0.017034362 -0.009385820
## Jun Jul Aug Sep Oct
## 2025 0.017897399 0.010639456 0.005927950 -0.002605119 -0.018959724
## 2026
## Nov Dec
## 2025 0.002287816 0.009019153
## 2026
l pronóstico mostrado en el gráfico refleja una serie temporal con fluctuaciones moderadas en el período proyectado (2025-2026) en comparación con los datos históricos, los cuales presentan una variabilidad más marcada. La proyección parece mantener una tendencia estable sin cambios abruptos, aunque se identifican ciertos movimientos estacionales.
En el año 2025, los valores comienzan con un crecimiento en junio (0.00276) y julio (0.01064), seguido de una ligera disminución en agosto (0.00593) y una caída en septiembre (-0.00261), alcanzando su punto más bajo en octubre (-0.01896). Sin embargo, en los meses de noviembre y diciembre, la serie recupera valores positivos (0.00229 y 0.00902, respectivamente), lo que podría indicar un efecto estacional.
Para el 2026, los primeros meses presentan valores positivos (enero y febrero), pero en marzo y abril la serie muestra un descenso (-0.01703 y -0.00939), lo que sugiere una posible repetición de patrones observados en el año anterior.
En general, el pronóstico no evidencia una tendencia claramente creciente ni decreciente, sino más bien un comportamiento estable con fluctuaciones que podrían corresponder a patrones estacionales.
#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.183357 -0.028657 -0.000081 0.028872 0.186672
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.214e-02 1.024e-02 1.186 0.238
## t -9.046e-05 1.469e-04 -0.616 0.539
##
## Residual standard error: 0.05575 on 118 degrees of freedom
## Multiple R-squared: 0.003203, Adjusted R-squared: -0.005244
## F-statistic: 0.3792 on 1 and 118 DF, p-value: 0.5392
##
## Call:
## lm(formula = y ~ t + t2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.180744 -0.031513 -0.001003 0.029153 0.182962
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.384e-02 1.552e-02 1.536 0.127
## t -6.658e-04 5.923e-04 -1.124 0.263
## t2 4.754e-06 4.742e-06 1.003 0.318
##
## Residual standard error: 0.05574 on 117 degrees of freedom
## Multiple R-squared: 0.01169, Adjusted R-squared: -0.005199
## F-statistic: 0.6922 on 2 and 117 DF, p-value: 0.5025
#Grafico sencillo
plot(fechas,y,type="l",col="#828282")
lines(fechas,g1,col="#007bff")
lines(fechas,g2,col="#4c3d19")
## Warning in adf.test(y): p-value smaller than printed p-value
##
## Augmented Dickey-Fuller Test
##
## data: y
## Dickey-Fuller = -4.746, 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.746 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.
## Series: y
## ARIMA(0,0,0) with zero mean
##
## sigma^2 = 0.00311: log likelihood = 176.11
## AIC=-350.23 AICc=-350.19 BIC=-347.44
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 0.006670428 0.0557681 0.04047104 100 100 0.7224016 -0.1050653
pronostico <- forecast(modelo_arima, h = 12) # Pronóstico para 12 meses
plot(pronostico, main = "Pronóstico ARIMA rendimientos Grupo Energia Bogota")
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## May 2025 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Jun 2025 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Jul 2025 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Aug 2025 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Sep 2025 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Oct 2025 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Nov 2025 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Dec 2025 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Jan 2026 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Feb 2026 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Mar 2026 0 -0.0714697 0.0714697 -0.1093035 0.1093035
## Apr 2026 0 -0.0714697 0.0714697 -0.1093035 0.1093035
##
## Call:
## lm(formula = y ~ x)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.177368 -0.029980 -0.002915 0.025645 0.193133
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.01229 0.01078 1.141 0.256
## x -0.09594 0.16204 -0.592 0.555
##
## Residual standard error: 0.05575 on 118 degrees of freedom
## Multiple R-squared: 0.002962, Adjusted R-squared: -0.005487
## F-statistic: 0.3506 on 1 and 118 DF, p-value: 0.5549
Este análisis muestra, nuevamente, ausencia de relación lineal significativa entre x e y:
Coeficiente de x: -0.09594, muy cercano a cero, no significativo (p = 0.555).
R² = 0.00296, es decir, x explica solo el 0.3% de la variabilidad en y.
El modelo completo no es significativo (F = 0.3506, p = 0.5549).
Conclusión breve: La relación entre x e y es estadísticamente insignificante y la correlación es prácticamente nula.
# Calcular la correlación de Pearson
correlacion_pearson <- cor(Caso1$`Rendimientos GEB`,
Caso1$`IPC mensual`,
use = "complete.obs",
method = "pearson")
print(paste("Correlación de Pearson:", correlacion_pearson))
## [1] "Correlación de Pearson: -0.054426189596503"
El coeficiente de Pearson -0.0544 indica una correlación negativa muy débil, casi nula.
Esto coincide con el resultado del modelo lineal:
No hay evidencia de una relación lineal significativa entre x e y, ni estadística ni prácticamente.
Conclusión: Las variables están prácticamente no correlacionadas.
# 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
)
# EJECUTA ESTO AL FINAL
knitr::kable(tabla_errores, caption = "Medidas de error de pronóstico para cada modelo Grupo Energia Bogota")
MAE | RMSE | MAPE | |
---|---|---|---|
SMA | 0.0415486 | 0.0571531 | Inf |
CES | 0.0401800 | 0.0552426 | Inf |
CES_Estacional | 0.0396519 | 0.0536191 | Inf |
CES_Parcial | 0.0392039 | 0.0524863 | Inf |
CES_Full | 0.0405749 | 0.0539362 | Inf |
Polinomial_Lineal | 0.0404181 | 0.0552790 | Inf |
Polinomial_Cuadratico | 0.0398100 | 0.0550430 | Inf |
ARIMA | 0.0404710 | 0.0557681 | NaN |
# PASO 1: Define la NUEVA función para calcular errores (con sMAPE)
# Asegúrate de que esta sea la función ACTIVA en tu sesión de R
calcular_errores <- function(real, pred) {
# Aseguramos que no haya NAs en los datos antes de calcular
valid_indices <- complete.cases(real, pred)
real_clean <- real[valid_indices]
pred_clean <- pred[valid_indices]
# Si después de limpiar no quedan datos válidos, retornamos NA
if(length(real_clean) == 0) {
return(data.frame(MAE = NA, RMSE = NA, sMAPE = NA)) # Retorna sMAPE
}
mae <- mean(abs(real_clean - pred_clean))
rmse <- sqrt(mean((real_clean - pred_clean)^2))
# Calcular sMAPE
abs_diff <- abs(real_clean - pred_clean)
sum_abs <- abs(real_clean) + abs(pred_clean)
# Calculamos el componente de sMAPE, manejando el caso donde sum_abs es 0
# Si sum_abs es 0 (lo que implica real_clean=0 y pred_clean=0), el componente es 0
smape_components <- ifelse(sum_abs == 0, 0, 2 * abs_diff / sum_abs)
# Calculamos la media de los componentes y multiplicamos por 100
smape <- mean(smape_components) * 100
return(data.frame(MAE = mae, RMSE = rmse, sMAPE = smape)) # Devuelve sMAPE
}
# PASO 2: Calcula los errores para cada modelo USANDO la función recién definida
# EJECUTA ESTO DESPUÉS de haber definido la función 'calcular_errores' arriba
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 que m4 es CES_Parcial
errores_ces_full <- calcular_errores(y, fitted(m5)) # Asegúrate de que m5 es CES_Full
# Para modelos polinómicos:
errores_lineal <- calcular_errores(y, g1) # Asumo que g1 es el modelo lineal
errores_cuadratico <- calcular_errores(y, g2) # Asumo que g2 es el modelo cuadrático
# Para ARIMA:
errores_arima <- calcular_errores(y, fitted(modelo_arima))
# PASO 3: 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
)
# PASO 4: Muestra la tabla
# EJECUTA ESTO AL FINAL
knitr::kable(tabla_errores, caption = "Medidas de error de pronóstico para cada modelo Grupo Energia Bogota")
MAE | RMSE | sMAPE | |
---|---|---|---|
SMA | 0.0415486 | 0.0571531 | 144.7035 |
CES | 0.0401800 | 0.0552426 | 154.3711 |
CES_Estacional | 0.0396519 | 0.0536191 | 143.2194 |
CES_Parcial | 0.0392039 | 0.0524863 | 135.3245 |
CES_Full | 0.0405749 | 0.0539362 | 142.9731 |
Polinomial_Lineal | 0.0404181 | 0.0552790 | 157.9905 |
Polinomial_Cuadratico | 0.0398100 | 0.0550430 | 160.9661 |
ARIMA | 0.0404710 | 0.0557681 | 196.6667 |
# 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) ---"
## [1] "El modelo con el menor RMSE de ajuste es: CES_Parcial"
## [1] "Sus medidas de error de ajuste son:"
## MAE RMSE sMAPE
## CES_Parcial 0.03920393 0.05248632 135.3245
# --- 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_Parcial"
## [1] "Su valor de MAE es: 0.0392"
## [1] "--------------------"
## [1] "El modelo con el menor RMSE es: CES_Parcial"
## [1] "Su valor de RMSE es: 0.0525"
## [1] "--------------------"
## [1] "El modelo con el menor sMAPE es: CES_Parcial"
## [1] "Su valor de sMAPE es: 135.3245"
## [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.
En el análisis de las medidas de error de pronóstico para el Grupo Energía de Bogotá, se observa que el modelo CES_Parcial presenta el mejor desempeño general, con el menor MAE (0.0392), el menor RMSE (0.0525) y el más bajo sMAPE (135.32%), lo que indica una mayor precisión tanto en términos absolutos como relativos. Le siguen de cerca los modelos CES_Estacional y CES_Full, aunque con errores ligeramente superiores. En contraste, el modelo ARIMA muestra el peor resultado en sMAPE (196.67%), lo que sugiere una baja precisión proporcional, a pesar de que sus errores absolutos (MAE y RMSE) son similares a los demás. El modelo SMA también tiene un desempeño inferior, con sMAPE de 144.70%. Por tanto, el modelo CES_Parcial se destaca como la mejor opción para pronosticar esta serie, gracias a su equilibrio entre exactitud y capacidad de capturar patrones relevantes.