1 Ejercicio 19.27 - Inventory Sales (Suavización exponencial simple)

Se utiliza el método de suavización exponencial simple, con constante de suavización \(\alpha = 0,4\), para predecir el cociente entre existencias y ventas de los 4 años siguientes.

\[S_t = \alpha X_t + (1-\alpha)S_{t-1} \qquad \hat X_{n+h} = S_n \text{ (constante para too } h)\]

# ==========================================
# EJERCICIO 19.27
# Suavización exponencial simple
# ==========================================

# Datos
anio <- 1:12

ratio <- c(
  1.41, 1.45, 1.57, 1.48,
  1.46, 1.44, 1.43, 1.45,
  1.43, 1.52, 1.37, 1.33
)

# Constante de suavización
alpha <- 0.4

# Vector para almacenar los valores suavizados
suavizado <- numeric(length(ratio))

# Valor inicial
suavizado[1] <- ratio[1]

# Suavización exponencial simple
for (t in 2:length(ratio)) {
  suavizado[t] <- alpha * ratio[t] +
    (1 - alpha) * suavizado[t - 1]
}

# Último valor suavizado
ultimo_suavizado <- suavizado[length(suavizado)]

# Predicciones para los próximos 4 años
predicciones <- rep(ultimo_suavizado, 4)

# Mostrar resultados
resultados <- data.frame(
  Año = anio,
  Observado = ratio,
  Suavizado = suavizado
)

resultados
##    Año Observado Suavizado
## 1    1      1.41  1.410000
## 2    2      1.45  1.426000
## 3    3      1.57  1.483600
## 4    4      1.48  1.482160
## 5    5      1.46  1.473296
## 6    6      1.44  1.459978
## 7    7      1.43  1.447987
## 8    8      1.45  1.448792
## 9    9      1.43  1.441275
## 10  10      1.52  1.472765
## 11  11      1.37  1.431659
## 12  12      1.33  1.390995
# Años futuros
anio_futuro <- 13:16

# Tabla de predicciones
predicciones_df <- data.frame(
  Año = anio_futuro,
  Prediccion = predicciones
)

predicciones_df
##   Año Prediccion
## 1  13   1.390995
## 2  14   1.390995
## 3  15   1.390995
## 4  16   1.390995
# ==========================================
# GRÁFICA
# ==========================================

plot(
  anio,
  ratio,
  type = "o",
  xlim = c(1, 16),
  ylim = range(c(ratio, predicciones)),
  xlab = "Año",
  ylab = "Cociente existencias / ventas",
  main = "Suavización exponencial simple"
)

lines(anio, suavizado, type = "o")
lines(anio_futuro, predicciones, type = "o")

legend(
  "topright",
  legend = c("Serie observada", "Serie suavizada", "Predicciones"),
  lty = 1,
  pch = 1
)

1.1 Conclusión

Con \(\alpha = 0,4\) el último valor suavizado es \(S_{12} = 1,391\), y como el modelo de suavizaión exponencial simple asume que no hay tendencia, la predicción para los años 13, 14, 15 y 16 es la misma constante: 1,391. Esto ilustra justamente la limitación que se discute en el ejercicio 19.31: al no incrporar tendencia, el modelo “aplana” el pronótico en el último nivel estimado, sin imortar que el último dato observado (1,33) esté por debajo de ese nivel. Es un pronóstico razonable a my corto plazo si la serie realmente fluctúa alrededor de una media estable (~1,45), pero no capturaría una posible caída sostenda del cociente existencias/ventas

2 Ejercicio 19.28 - Gold Price (Suavización exponencial simple)

Se utiliza \(\alpha = 0,3\) para predecir el precio del oro de los 5 años siguientes.

# ============================================================
# EJERCICIO 19.28
# SUAVIZACIÓN EXPONENCIAL SIMPLE
# Precio del oro
# ============================================================

anio <- 1:14

precio_oro <- c(
  135, 166, 227, 533, 591, 399, 450,
  385, 308, 329, 405, 486, 410, 369
)

alpha <- 0.3

suavizado <- numeric(length(precio_oro))
suavizado[1] <- precio_oro[1]

for (t in 2:length(precio_oro)) {
  suavizado[t] <- alpha * precio_oro[t] +
    (1 - alpha) * suavizado[t - 1]
}

resultados <- data.frame(
  Año = anio,
  Precio_Observado = precio_oro,
  Precio_Suavizado = suavizado
)

print(resultados)
##    Año Precio_Observado Precio_Suavizado
## 1    1              135         135.0000
## 2    2              166         144.3000
## 3    3              227         169.1100
## 4    4              533         278.2770
## 5    5              591         372.0939
## 6    6              399         380.1657
## 7    7              450         401.1160
## 8    8              385         396.2812
## 9    9              308         369.7968
## 10  10              329         357.5578
## 11  11              405         371.7905
## 12  12              486         406.0533
## 13  13              410         407.2373
## 14  14              369         395.7661
ultimo_suavizado <- suavizado[length(suavizado)]

cat(
  "\nÚltimo valor suavizado:",
  round(ultimo_suavizado, 3),
  "\n"
)
## 
## Último valor suavizado: 395.766
anio_futuro <- 15:19

predicciones <- rep(ultimo_suavizado, 5)

predicciones_df <- data.frame(
  Año = anio_futuro,
  Prediccion = predicciones
)

cat("\nPredicciones:\n")
## 
## Predicciones:
print(predicciones_df)
##   Año Prediccion
## 1  15   395.7661
## 2  16   395.7661
## 3  17   395.7661
## 4  18   395.7661
## 5  19   395.7661
plot(
  anio,
  precio_oro,
  type = "o",
  xlim = c(1, 19),
  ylim = range(c(precio_oro, predicciones)),
  xlab = "Año",
  ylab = "Precio del oro ($)",
  main = "Suavización exponencial simple del precio del oro"
)

lines(anio, suavizado, type = "o")
lines(anio_futuro, predicciones, type = "o")
abline(v = 14, lty = 2)

legend(
  "topleft",
  legend = c("Precio observado", "Serie suavizada", "Predicciones"),
  lty = 1,
  pch = 1
)

2.1 Conclusión

El precio del oro es una serie muy volátil (pasa de 135 a un pico de 591 y luego oscila entre 300 y 490) por lo que con \(\alpha = 0,3\) el suavizado reacciona con rezago a los cambios bruscos. El último nivel suavizado es \(S_{14} = 395,77\), y esa es la predicción constante para los 5 años siguientes (15 a 19). Al ser una serie sin una tendencia clara y con reversión a la media, un pronóstico plano cerca de 396 es aceptable, aunque el modelo no anticipa nuevos repuntes o caídas como los ya observados en la serie históric

3 Ejercicio 19.29 - Housing Starts (Suavización exponencial simple)

Se utiliza \(\alpha = 0,5\) para predecir la construcción de viviendas de los 3 años siguientes.

# ============================================================
# EJERCICIO 19.29
# SUAVIZACIÓN EXPONENCIAL SIMPLE
# Housing Starts
# ============================================================

anio <- 1:24

starts <- c(
  8.5, 6.9, 7.1, 7.8,
  8.5, 8.0, 7.6, 5.9,
  6.5, 7.5, 7.2, 7.0,
  9.9, 11.3, 9.7, 6.3,
  5.4, 7.1, 9.1, 9.1,
  7.8, 5.7, 4.7, 4.6
)

alpha <- 0.5

suavizado <- numeric(length(starts))
suavizado[1] <- starts[1]

for (t in 2:length(starts)) {
  suavizado[t] <- alpha * starts[t] +
    (1 - alpha) * suavizado[t - 1]
}

resultados <- data.frame(
  Año = anio,
  Observado = starts,
  Suavizado = suavizado
)

print(resultados)
##    Año Observado Suavizado
## 1    1       8.5  8.500000
## 2    2       6.9  7.700000
## 3    3       7.1  7.400000
## 4    4       7.8  7.600000
## 5    5       8.5  8.050000
## 6    6       8.0  8.025000
## 7    7       7.6  7.812500
## 8    8       5.9  6.856250
## 9    9       6.5  6.678125
## 10  10       7.5  7.089062
## 11  11       7.2  7.144531
## 12  12       7.0  7.072266
## 13  13       9.9  8.486133
## 14  14      11.3  9.893066
## 15  15       9.7  9.796533
## 16  16       6.3  8.048267
## 17  17       5.4  6.724133
## 18  18       7.1  6.912067
## 19  19       9.1  8.006033
## 20  20       9.1  8.553017
## 21  21       7.8  8.176508
## 22  22       5.7  6.938254
## 23  23       4.7  5.819127
## 24  24       4.6  5.209564
ultimo_suavizado <- suavizado[length(suavizado)]

cat(
  "\nÚltimo valor suavizado:",
  round(ultimo_suavizado, 3),
  "\n"
)
## 
## Último valor suavizado: 5.21
anio_futuro <- 25:27

predicciones <- rep(ultimo_suavizado, 3)

predicciones_df <- data.frame(
  Año = anio_futuro,
  Prediccion = predicciones
)

cat("\nPredicciones para los próximos 3 años:\n")
## 
## Predicciones para los próximos 3 años:
print(predicciones_df)
##   Año Prediccion
## 1  25   5.209564
## 2  26   5.209564
## 3  27   5.209564
plot(
  anio,
  starts,
  type = "o",
  xlim = c(1, 27),
  ylim = range(c(starts, predicciones)),
  xlab = "Año",
  ylab = "Viviendas iniciadas por mil habitantes",
  main = "Suavización exponencial simple - Housing Starts"
)

lines(anio, suavizado, type = "o")
lines(anio_futuro, predicciones, type = "o")
abline(v = 24, lty = 2)

legend(
  "topright",
  legend = c("Serie observada", "Serie suavizada", "Predicciones"),
  lty = 1,
  pch = 1
)

3.1 Conclusión

Con \(\alpha = 0,5\) el modelo pondera fuertemente las observaciones recientes. El nivel suavizado final es \(S_{24} = 5,21\), muy por debajo de promedio histórico de la serie (~7,4), porque los últimos años muestran una clara tenencia decreciente en la construcción de viviendas (de 9,1 a 4,6). Por tanto, la predicción para los años 25, 26 y 27 es 5,21 viviendas iniciadas por cada mil habitantes. Aunque la suavización exponencial simple no proyecta la tendencia bajista explícitamente, al usar un \(\alpha\) alto el nivel ya recoge buena parte de esa caída recient

4 Ejercicio 19.30 - Earnings per Share (comparación de constantes de suavización)

Se comparan las constantes \(\alpha = 0,2,\ 0,4,\ 0,6,\ 0,8\) mediante el error cuadrático medio (MSE) para elegir la mejor predicción.

# ============================================================
# EJERCICIO 19.30
# EARNINGS PER SHARE
# SUAVIZACIÓN EXPONENCIAL SIMPLE
# ============================================================

anio <- 1:28

earnings <- c(
  50.2, 33.9, 20.6, 25.4,
  32.9, 31.3, 18.8, 14.5,
  17.5, 23.6, 20.6, 21.6,
  27.6, 36.5, 49.3, 45.4,
  35.6, 30.1, 25.5, 22.4,
  12.3, 20.9, 42.8, 86.3,
  73.6, 47.7, 56.6, 53.1
)

alphas <- c(0.2, 0.4, 0.6, 0.8)

suavizacion <- function(x, alpha) {
  S <- numeric(length(x))
  S[1] <- x[1]
  for (t in 2:length(x)) {
    S[t] <- alpha * x[t] + (1 - alpha) * S[t - 1]
  }
  return(S)
}

S_02 <- suavizacion(earnings, 0.2)
S_04 <- suavizacion(earnings, 0.4)
S_06 <- suavizacion(earnings, 0.6)
S_08 <- suavizacion(earnings, 0.8)

predicciones <- data.frame(
  Alpha = alphas,
  Prediccion_Año_29 = c(S_02[28], S_04[28], S_06[28], S_08[28])
)

print(predicciones)
##   Alpha Prediccion_Año_29
## 1   0.2          49.86438
## 2   0.4          54.85033
## 3   0.6          54.51778
## 4   0.8          53.65612
cat("\nÚltimos valores suavizados:\n")
## 
## Últimos valores suavizados:
cat("Alpha = 0.2:", round(S_02[28], 3), "\n")
## Alpha = 0.2: 49.864
cat("Alpha = 0.4:", round(S_04[28], 3), "\n")
## Alpha = 0.4: 54.85
cat("Alpha = 0.6:", round(S_06[28], 3), "\n")
## Alpha = 0.6: 54.518
cat("Alpha = 0.8:", round(S_08[28], 3), "\n")
## Alpha = 0.8: 53.656
# Comparación de errores (MSE)
calcular_mse <- function(x, S) {
  pronosticos <- S[-length(S)]
  observados <- x[-1]
  errores <- observados - pronosticos
  mean(errores^2)
}

mse_02 <- calcular_mse(earnings, S_02)
mse_04 <- calcular_mse(earnings, S_04)
mse_06 <- calcular_mse(earnings, S_06)
mse_08 <- calcular_mse(earnings, S_08)

comparacion <- data.frame(
  Alpha = alphas,
  MSE = c(mse_02, mse_04, mse_06, mse_08)
)

print(comparacion)
##   Alpha      MSE
## 1   0.2 305.8596
## 2   0.4 247.5689
## 3   0.6 215.3500
## 4   0.8 191.6491
mejor_modelo <- comparacion$Alpha[which.min(comparacion$MSE)]

cat("\nEl alpha con menor MSE es:", mejor_modelo, "\n")
## 
## El alpha con menor MSE es: 0.8
plot(
  anio,
  earnings,
  type = "o",
  xlab = "Año",
  ylab = "Earnings per Share",
  main = "Suavización exponencial simple"
)

lines(anio, S_02, type = "o")
lines(anio, S_04, type = "o")
lines(anio, S_06, type = "o")
lines(anio, S_08, type = "o")

legend(
  "topleft",
  legend = c("Observado", "Alpha = 0.2", "Alpha = 0.4", "Alpha = 0.6", "Alpha = 0.8"),
  lty = 1,
  pch = 1
)

4.1 Conclusión

a) Las predicciones para el año 29 con cada constante son:

\(\alpha\) Predicción año 29 MSE
0,2 49,86 305,86
0,4 54,85 247,57
0,6 54,52 215,35
0,8 53,66 191,65

b) El criterio para elegir entre las cuatro constantes es el error cuadrático medio (MSE) de cada modelo dentro de la muestra: mientras menor sea el MSE, mejor se ajusta el modelo a los datos históricos. Como se obsrva en la tabla, el MSE disminuye a medida que aumenta \(\alpha\), siendo \(\alpha = 0,8\) el que produce el menor error (MSE = 191,65). Esto tiene sentido porque las utilidades por acción de esta empresa son muy volátiles (saltan de 12,3 a 86,3 en pocos años), por lo que un \(\alpha\) alto —que da más peso a las observaciones recientes y recciona más rápido a los cambios— se ajusta mejor que un \(\alpha\) bajo, más apropiado para series estables. En consecuencia, elegiría la predicción de \(\alpha = 0,8\), es decir 53,66, como el pronóstico para el año 29

5 Ejercicio 19.34 - Industrial Production Canada (Método de Holt)

Se utiliza el método de Holt con \(\alpha = 0,3\) y \(\beta = 0,5\) para predecir el índice de producción industrial de los 5 años siguientes.

\[S_t = \alpha X_t + (1-\alpha)(S_{t-1}+T_{t-1}) \qquad T_t = \beta(S_t-S_{t-1})+(1-\beta)T_{t-1} \qquad \hat X_{n+h}=S_n+hT_n\]

# ============================================================
# EJERCICIO 19.34
# INDUSTRIAL PRODUCTION CANADA
# MÉTODO DE HOLT-WINTERS / HOLT
# ============================================================

year <- 1:15

index <- c(
  79, 74, 78, 80, 83,
  88, 85, 87, 79, 84,
  91, 10, 100, 106, 112
)

alpha <- 0.3
beta <- 0.5

nivel <- numeric(length(index))
tendencia <- numeric(length(index))

nivel[1] <- index[1]
tendencia[1] <- index[2] - index[1]

for (t in 2:length(index)) {
  nivel[t] <- alpha * index[t] +
    (1 - alpha) * (nivel[t - 1] + tendencia[t - 1])

  tendencia[t] <- beta * (nivel[t] - nivel[t - 1]) +
    (1 - beta) * tendencia[t - 1]
}

resultados <- data.frame(
  Año = year,
  Observado = index,
  Nivel = nivel,
  Tendencia = tendencia
)

print(resultados)
##    Año Observado    Nivel  Tendencia
## 1    1        79 79.00000  -5.000000
## 2    2        74 74.00000  -5.000000
## 3    3        78 71.70000  -3.650000
## 4    4        80 71.63500  -1.857500
## 5    5        83 73.74425   0.125875
## 6    6        88 78.10909   2.245356
## 7    7        85 81.74811   2.942190
## 8    8        87 85.38321   3.288645
## 9    9        79 85.77030   1.837866
## 10  10        84 86.52572   1.296642
## 11  11        91 88.77565   1.773288
## 12  12        10 66.38426 -10.309053
## 13  13       100 69.25264  -3.720333
## 14  14       106 77.67262   2.349820
## 15  15       112 89.61571   7.146455
nivel_final <- nivel[length(nivel)]
tendencia_final <- tendencia[length(tendencia)]

cat("\nNivel final:", round(nivel_final, 3), "\n")
## 
## Nivel final: 89.616
cat("Tendencia final:", round(tendencia_final, 3), "\n")
## Tendencia final: 7.146
h <- 1:5
year_futuro <- 16:20

predicciones <- nivel_final + h * tendencia_final

pronosticos <- data.frame(
  Año = year_futuro,
  Prediccion = predicciones
)

cat("\nPredicciones para los próximos 5 años:\n")
## 
## Predicciones para los próximos 5 años:
print(pronosticos)
##   Año Prediccion
## 1  16   96.76216
## 2  17  103.90862
## 3  18  111.05507
## 4  19  118.20153
## 5  20  125.34798
plot(
  year,
  index,
  type = "o",
  xlim = c(1, 20),
  ylim = range(c(index, predicciones)),
  xlab = "Año",
  ylab = "Índice de producción industrial",
  main = "Método de Holt - Industrial Production Canada"
)

lines(year, nivel, type = "o")
lines(year_futuro, predicciones, type = "o")
abline(v = 15, lty = 2)

legend(
  "topleft",
  legend = c("Serie observada", "Nivel suavizado", "Predicciones"),
  lty = 1,
  pch = 1
)

5.1 Conclusión

Con el método de Holt (\(\alpha = 0,3\), \(\beta = 0,5\)) se obtiene un nivel final \(S_{15} = 89,62\) y una tendencia final \(T_{15} = 7,15\), lo que arroja las siguientes predicciones para los años 16 a 20: 96,76 – 103,91 – 111,06 – 118,20 – 125,35, es decir, un crecimiento lineal sostenido de aproximadamente 7,15 puntos del índice por año.

Es importante señalar una observación sobre los datos: el valor del año 12 (10) rompe abruptamente la tendencia creciente que traía la serie (…, 84, 91, 10, 100, 106, 112), lo cual genera una tendencia estimada muy inestable en ese punto (\(T_{12} = -10,31\)) que luego se corrige en los años siguientes. Este comportamiento sugiere que ese dato podría ser un error de digitación (posiblemente debía ser un valor cercano a 100), por lo que sería recomendable verificar la fuente original antes de reportar la predicción final, ya que un solo dato atípico puede distorsionar considerablemente la estimación de la tendencia y, con ello, los pronósticos a 5 años.

6 Ejercicio 19.35 - Hourly Earnings (Método de Holt)

\(\alpha = 0,3\), \(\beta = 0,4\). Predicción de los 3 meses siguientes.

# ==========================================
# EJERCICIO 19.35
# Método de Holt (Holt-Winters sin estacionalidad)
# ==========================================

mes <- 1:24

earnings <- c(
  10.58, 10.67, 10.48, 10.59, 10.67, 10.74,
  10.74, 10.80, 10.84, 10.87, 10.81, 10.93,
  10.94, 10.96, 11.05, 10.83, 11.05, 11.02,
  11.06, 11.11, 11.15, 11.19, 11.22, 11.17
)

alpha <- 0.3
beta  <- 0.4

n <- length(earnings)

S <- numeric(n)
T <- numeric(n)

S[1] <- earnings[1]
T[1] <- earnings[2] - earnings[1]

for (t in 2:n) {
  S[t] <- alpha * earnings[t] + (1 - alpha) * (S[t - 1] + T[t - 1])
  T[t] <- beta * (S[t] - S[t - 1]) + (1 - beta) * T[t - 1]
}

resultados <- data.frame(
  Mes = mes,
  Observado = earnings,
  Nivel_S = S,
  Tendencia_T = T
)

print(resultados, digits = 6)
##    Mes Observado Nivel_S Tendencia_T
## 1    1     10.58 10.5800  0.09000000
## 2    2     10.67 10.6700  0.09000000
## 3    3     10.48 10.6760  0.05640000
## 4    4     10.59 10.6897  0.03931200
## 5    5     10.67 10.7113  0.03223296
## 6    6     10.74 10.7425  0.03180968
## 7    7     10.74 10.7640  0.02769622
## 8    8     10.80 10.7942  0.02869325
## 9    9     10.84 10.8280  0.03074798
## 10  10     10.87 10.8621  0.03209654
## 11  11     10.81 10.8690  0.02198894
## 12  12     10.93 10.9027  0.02667495
## 13  13     10.94 10.9325  0.02795416
## 14  14     10.96 10.9603  0.02789511
## 15  15     11.05 11.0068  0.03530636
## 16  16     10.83 10.9785  0.00985748
## 17  17     11.05 11.0068  0.01726036
## 18  18     11.02 11.0229  0.01677113
## 19  19     11.06 11.0457  0.01921614
## 20  20     11.11 11.0785  0.02462171
## 21  21     11.15 11.1172  0.03025100
## 22  22     11.19 11.1602  0.03536138
## 23  23     11.22 11.2029  0.03829529
## 24  24     11.17 11.2198  0.02975358
h <- 1:3
predicciones <- S[n] + h * T[n]

predicciones_df <- data.frame(
  Mes = (n + 1):(n + 3),
  Prediccion = predicciones
)

print(predicciones_df, digits = 6)
##   Mes Prediccion
## 1  25    11.2496
## 2  26    11.2793
## 3  27    11.3091
mes_futuro <- (n + 1):(n + 3)

plot(
  mes, earnings,
  type = "o",
  xlim = c(1, n + 3),
  ylim = range(c(earnings, predicciones)),
  xlab = "Mes",
  ylab = "Ingresos por hora",
  main = "Metodo de Holt: nivel, tendencia y predicciones"
)

lines(mes, S, type = "o", col = "blue")
lines(mes_futuro, predicciones, type = "o", col = "red")

legend(
  "topleft",
  legend = c("Serie observada", "Serie suavizada (nivel)", "Predicciones"),
  col = c("black", "blue", "red"),
  lty = 1,
  pch = 1
)

# ==========================================
# VERIFICACION CON LA FUNCION HoltWinters DE R
# ==========================================

serie_ts <- ts(earnings, start = 1, frequency = 1)

modelo_hw <- HoltWinters(
  serie_ts,
  alpha = alpha,
  beta = beta,
  gamma = FALSE
)

modelo_hw
## Holt-Winters exponential smoothing with trend and without seasonal component.
## 
## Call:
## HoltWinters(x = serie_ts, alpha = alpha, beta = beta, gamma = FALSE)
## 
## Smoothing parameters:
##  alpha: 0.3
##  beta : 0.4
##  gamma: FALSE
## 
## Coefficients:
##          [,1]
## a 11.21982659
## b  0.02975358
predict(modelo_hw, n.ahead = 3)
## Time Series:
## Start = 25 
## End = 27 
## Frequency = 1 
##           fit
## [1,] 11.24958
## [2,] 11.27933
## [3,] 11.30909

6.1 Conclusión

El método de Holt con \(\alpha = 0,3\) y \(\beta = 0,4\) captura adecuadamente la tendencia suave y sostenida de crecimiento en los ingresos por hora de la industria manufacturera. El nivel final es \(S_{24} = 11,22\) y la tendencia final es \(T_{24} = 0,030\) dólares por mes, por lo que las predicciones para los meses 25, 26 y 27 son 11,25, 11,28 y 11,31 dólares, respectivamente. La verificación con la función HoltWinters() de R confirma los mismos resultados obtenidos manualmente, lo que valida el procedimiento iterativo implementado. El pronóstico es coherente con el comportamiento histórico: un incremento gradual y estable, sin sobresaltos ni cambios de tendencia.

7 Ejercicio 19.36 - Food Prices (Método de Holt)

\(\alpha = 0,5\), \(\beta = 0,5\). Predicción de los 3 meses siguientes.

# ==========================================
# EJERCICIO 19.36
# Metodo de Holt (Holt-Winters sin estacionalidad)
# ==========================================

mes <- 1:14

precio <- c(
  116.6, 117.1, 117.8, 118.9, 119.5, 120.3, 120.6,
  120.8, 121.2, 122.1, 122.6, 123.6, 124.2, 125.0
)

alpha <- 0.5
beta  <- 0.5

n <- length(precio)
S <- numeric(n)
T <- numeric(n)

S[1] <- precio[1]
T[1] <- precio[2] - precio[1]

for (t in 2:n) {
  S[t] <- alpha * precio[t] + (1 - alpha) * (S[t - 1] + T[t - 1])
  T[t] <- beta * (S[t] - S[t - 1]) + (1 - beta) * T[t - 1]
}

resultados <- data.frame(Mes = mes, Observado = precio, Nivel_S = S, Tendencia_T = T)
print(resultados, digits = 6)
##    Mes Observado Nivel_S Tendencia_T
## 1    1     116.6 116.600    0.500000
## 2    2     117.1 117.100    0.500000
## 3    3     117.8 117.700    0.550000
## 4    4     118.9 118.575    0.712500
## 5    5     119.5 119.394    0.765625
## 6    6     120.3 120.230    0.800781
## 7    7     120.6 120.815    0.693164
## 8    8     120.8 121.154    0.516064
## 9    9     121.2 121.435    0.398499
## 10  10     122.1 121.967    0.465091
## 11  11     122.6 122.516    0.507114
## 12  12     123.6 123.312    0.651348
## 13  13     124.2 124.081    0.710627
## 14  14     125.0 124.896    0.762610
h <- 1:3
predicciones <- S[n] + h * T[n]

predicciones_df <- data.frame(Mes = (n + 1):(n + 3), Prediccion = predicciones)
print(predicciones_df, digits = 6)
##   Mes Prediccion
## 1  15    125.659
## 2  16    126.421
## 3  17    127.184
mes_futuro <- (n + 1):(n + 3)

plot(
  mes, precio, type = "o",
  xlim = c(1, n + 3),
  ylim = range(c(precio, predicciones)),
  xlab = "Mes", ylab = "Indice de precios de alimentos",
  main = "Metodo de Holt: nivel, tendencia y predicciones"
)
lines(mes, S, type = "o", col = "blue")
lines(mes_futuro, predicciones, type = "o", col = "red")
legend("topleft",
       legend = c("Serie observada", "Serie suavizada (nivel)", "Predicciones"),
       col = c("black", "blue", "red"), lty = 1, pch = 1)

serie_ts <- ts(precio, start = 1, frequency = 1)
modelo_hw <- HoltWinters(serie_ts, alpha = alpha, beta = beta, gamma = FALSE)
modelo_hw
## Holt-Winters exponential smoothing with trend and without seasonal component.
## 
## Call:
## HoltWinters(x = serie_ts, alpha = alpha, beta = beta, gamma = FALSE)
## 
## Smoothing parameters:
##  alpha: 0.5
##  beta : 0.5
##  gamma: FALSE
## 
## Coefficients:
##          [,1]
## a 124.8960339
## b   0.7626103
predict(modelo_hw, n.ahead = 3)
## Time Series:
## Start = 15 
## End = 17 
## Frequency = 1 
##           fit
## [1,] 125.6586
## [2,] 126.4213
## [3,] 127.1839

7.1 Conclusión

Con \(\alpha = 0,5\) y \(\beta = 0,5\) el índice de precios de alimentos muestra una tendencia claramente creciente y estable (nivel final \(S_{14} = 124,90\), tendencia final \(T_{14} = 0,763\) por mes). Esto lleva a predicciones de 125,66, 126,42 y 127,18 para los meses 15, 16 y 17, reflejando un ritmo inflacionario constante de aproximadamente 0,76 puntos mensuales. Al usar \(\alpha\) y \(\beta\) relativamente altos, el modelo se ajusta rápido a los cambios recientes, lo cual es apropiado aquí porque la serie no presenta reversiones ni estacionalidad, solo una tendencia monotónica al alza. La verificación con HoltWinters() reproduce los mismos valores.

8 Ejercicio 19.37 - Profit Margins (Método de Holt)

\(\alpha = 0,6\), \(\beta = 0,6\). Predicción de los 2 años siguientes.

# ==========================================
# EJERCICIO 19.37
# Metodo de Holt (Holt-Winters sin estacionalidad)
# ==========================================

anio <- 1:11

margen <- c(8.4, 7.4, 7.4, 7.2, 6.3, 7.9, 7.7, 7.1, 8.5, 7.0, 5.7)

alpha <- 0.6
beta  <- 0.6

n <- length(margen)
S <- numeric(n)
T <- numeric(n)

S[1] <- margen[1]
T[1] <- margen[2] - margen[1]

for (t in 2:n) {
  S[t] <- alpha * margen[t] + (1 - alpha) * (S[t - 1] + T[t - 1])
  T[t] <- beta * (S[t] - S[t - 1]) + (1 - beta) * T[t - 1]
}

resultados <- data.frame(Año = anio, Observado = margen, Nivel_S = S, Tendencia_T = T)
print(resultados, digits = 6)
##    Año Observado Nivel_S Tendencia_T
## 1    1       8.4 8.40000  -1.0000000
## 2    2       7.4 7.40000  -1.0000000
## 3    3       7.4 7.00000  -0.6400000
## 4    4       7.2 6.86400  -0.3376000
## 5    5       6.3 6.39056  -0.4191040
## 6    6       7.9 7.12858   0.2751718
## 7    7       7.7 7.58150   0.3818203
## 8    8       7.1 7.44533   0.0710244
## 9    9       8.5 8.10654   0.4251372
## 10  10       7.0 7.61267  -0.1262670
## 11  11       5.7 6.41456  -0.7693726
h <- 1:2
predicciones <- S[n] + h * T[n]

predicciones_df <- data.frame(Año = (n + 1):(n + 2), Prediccion = predicciones)
print(predicciones_df, digits = 6)
##   Año Prediccion
## 1  12    5.64519
## 2  13    4.87582
anio_futuro <- (n + 1):(n + 2)

plot(
  anio, margen, type = "o",
  xlim = c(1, n + 2),
  ylim = range(c(margen, predicciones)),
  xlab = "Año", ylab = "Margen de beneficio (%)",
  main = "Metodo de Holt: nivel, tendencia y predicciones"
)
lines(anio, S, type = "o", col = "blue")
lines(anio_futuro, predicciones, type = "o", col = "red")
legend("topright",
       legend = c("Serie observada", "Serie suavizada (nivel)", "Predicciones"),
       col = c("black", "blue", "red"), lty = 1, pch = 1)

serie_ts <- ts(margen, start = 1, frequency = 1)
modelo_hw <- HoltWinters(serie_ts, alpha = alpha, beta = beta, gamma = FALSE)
modelo_hw
## Holt-Winters exponential smoothing with trend and without seasonal component.
## 
## Call:
## HoltWinters(x = serie_ts, alpha = alpha, beta = beta, gamma = FALSE)
## 
## Smoothing parameters:
##  alpha: 0.6
##  beta : 0.6
##  gamma: FALSE
## 
## Coefficients:
##         [,1]
## a  6.4145618
## b -0.7693726
predict(modelo_hw, n.ahead = 2)
## Time Series:
## Start = 12 
## End = 13 
## Frequency = 1 
##           fit
## [1,] 5.645189
## [2,] 4.875817

8.1 Conclusión

A diferencia de los ejercicios anteriores, el margen de beneficio de esta empresa muestra una tendencia decreciente en los últimos años de la serie (de 8,5 en el año 9 a 5,7 en el año 11). Con \(\alpha = 0,6\) y \(\beta = 0,6\) se obtiene un nivel final \(S_{11} = 6,41\) y una tendencia final \(T_{11} = -0,769\), lo que produce predicciones de 5,65% para el año 12 y 4,88% para el año 13. Dado que el método de Holt extrapola la tendencia de forma lineal e indefinida, conviene interpretar este pronóstico con cautela: si la caída observada en los últimos periodos es puntual (por ejemplo, producto de un choque específico) y no estructural, el modelo podría subestimar el margen futuro; si en cambio la tendencia bajista se mantiene, los márgenes seguirían deteriorándose. En cualquier caso, es un buen ejemplo de por qué no conviene proyectar una tendencia lineal a muchos periodos hacia adelante sin contrastarla con el conocimiento del negocio.

9 Ejercicio 19.38 - Quarterly Earnings (Holt-Winters estacional)

\(\alpha = 0,6\), \(\beta = 0,5\), \(\gamma = 0,4\), \(L = 4\). Predicción de los 8 trimestres siguientes.

\[S_t = \alpha\left(\frac{X_t}{I_{t-L}}\right)+(1-\alpha)(S_{t-1}+T_{t-1}) \qquad T_t=\beta(S_t-S_{t-1})+(1-\beta)T_{t-1}\] \[I_t=\gamma\left(\frac{X_t}{S_t}\right)+(1-\gamma)I_{t-L} \qquad \hat X_{n+h}=(S_n+hT_n)\,I_{n+h-L}\]

# ==========================================
# EJERCICIO 19.38
# Metodo estacional de Holt-Winters (multiplicativo)
# ==========================================

anio <- rep(1:7, each = 4)
trimestre <- rep(1:4, times = 7)

ventas <- c(
  0.786, 0.668, 0.863, 0.807,
  0.802, 0.670, 0.885, 0.805,
  0.579, 0.423, 0.904, 0.851,
  0.430, 0.409, 1.120, 0.958,
  0.680, 0.460, 1.190, 0.830,
  0.766, 0.440, 1.020, 0.630,
  0.690, 0.600, 1.130, 0.680
)

alpha <- 0.6
beta  <- 0.5
gamma <- 0.4
L <- 4

n <- length(ventas)

S <- numeric(n)
T <- numeric(n)
I <- numeric(n)

media_anio1 <- mean(ventas[1:4])
media_anio2 <- mean(ventas[5:8])

S[4] <- media_anio1
T[4] <- (media_anio2 - media_anio1) / L

I[1:4] <- ventas[1:4] / media_anio1

for (t in 5:n) {
  S[t] <- alpha * (ventas[t] / I[t - L]) + (1 - alpha) * (S[t - 1] + T[t - 1])
  T[t] <- beta  * (S[t] - S[t - 1]) + (1 - beta) * T[t - 1]
  I[t] <- gamma * (ventas[t] / S[t]) + (1 - gamma) * I[t - L]
}

resultados <- data.frame(
  Anio = anio, Trimestre = trimestre, Observado = ventas,
  Nivel_S = S, Tendencia_T = T, Indice_I = I
)
print(resultados, digits = 6)
##    Anio Trimestre Observado  Nivel_S Tendencia_T Indice_I
## 1     1         1     0.786 0.000000  0.00000000 1.006402
## 2     1         2     0.668 0.000000  0.00000000 0.855314
## 3     1         3     0.863 0.000000  0.00000000 1.104994
## 4     1         4     0.807 0.781000  0.00237500 1.033291
## 5     2         1     0.802 0.791489  0.00643197 1.009153
## 6     2         2     0.670 0.789171  0.00205719 0.852785
## 7     2         3     0.885 0.797037  0.00496151 1.107141
## 8     2         4     0.805 0.788238 -0.00191877 1.028480
## 9     3         1     0.579 0.658777 -0.06569008 0.957053
## 10    3         2     0.423 0.534848 -0.09480951 0.828023
## 11    3         3     0.904 0.665926  0.01813424 1.207288
## 12    3         4     0.851 0.770085  0.06114654 1.059118
## 13    4         1     0.430 0.602070 -0.05343399 0.859913
## 14    4         2     0.409 0.515823 -0.06984047 0.813977
## 15    4         3     1.120 0.735013  0.07467444 1.333886
## 16    4         4     0.958 0.866591  0.10312633 1.077663
## 17    5         1     0.680 0.862354  0.04944463 0.831363
## 18    5         2     0.460 0.703795 -0.05455680 0.749826
## 19    5         3     1.190 0.794973  0.01831062 1.399094
## 20    5         4     0.830 0.787425  0.00538090 1.068226
## 21    6         1     0.766 0.869949  0.04395266 0.851023
## 22    6         2     0.440 0.717643 -0.05417691 0.695143
## 23    6         3     1.020 0.702812 -0.03450363 1.419981
## 24    6         4     0.630 0.621181 -0.05806728 1.046614
## 25    7         1     0.690 0.711719  0.01623530 0.898407
## 26    7         2     0.600 0.809061  0.05678857 0.713726
## 27    7         3     1.130 0.823811  0.03576924 1.400658
## 28    7         4     0.680 0.733661 -0.02719054 0.998712
h <- 1:8
indices_futuros <- I[(n - L + 1):n]
indices_repetidos <- rep(indices_futuros, 2)

predicciones <- (S[n] + h * T[n]) * indices_repetidos

predicciones_df <- data.frame(
  Anio = rep(8:9, each = 4),
  Trimestre = rep(1:4, times = 2),
  Prediccion = predicciones
)
print(predicciones_df, digits = 6)
##   Anio Trimestre Prediccion
## 1    8         1   0.634698
## 2    8         2   0.484819
## 3    8         3   0.913354
## 4    8         4   0.624094
## 5    9         1   0.536985
## 6    9         2   0.407193
## 7    9         3   0.761015
## 8    9         4   0.515471
t_futuro <- (n + 1):(n + 8)

plot(
  1:n, ventas, type = "o",
  xlim = c(1, n + 8),
  ylim = range(c(ventas, predicciones)),
  xlab = "Trimestre", ylab = "Beneficios trimestrales",
  main = "Holt-Winters estacional: nivel y predicciones"
)
lines(1:n, S, type = "o", col = "blue")
lines(t_futuro, predicciones, type = "o", col = "red")
legend("topleft",
       legend = c("Serie observada", "Nivel suavizado", "Predicciones"),
       col = c("black", "blue", "red"), lty = 1, pch = 1)

serie_ts <- ts(ventas, start = c(1, 1), frequency = 4)
modelo_hw <- HoltWinters(
  serie_ts,
  alpha = alpha, beta = beta, gamma = gamma,
  seasonal = "multiplicative"
)
modelo_hw
## Holt-Winters exponential smoothing with trend and multiplicative seasonal component.
## 
## Call:
## HoltWinters(x = serie_ts, alpha = alpha, beta = beta, gamma = gamma,     seasonal = "multiplicative")
## 
## Smoothing parameters:
##  alpha: 0.6
##  beta : 0.5
##  gamma: 0.4
## 
## Coefficients:
##           [,1]
## a   0.73483146
## b  -0.02664942
## s1  0.90015624
## s2  0.71350814
## s3  1.39987445
## s4  0.99650943
predict(modelo_hw, n.ahead = 8)
##        Qtr1      Qtr2      Qtr3      Qtr4
## 8 0.6374745 0.4862791 0.9167543 0.6260409
## 9 0.5415199 0.4102208 0.7675309 0.5198153

10 Ejercicio 19.39 - Ventas trimestrales (Holt-Winters estacional)

\(\alpha = 0,5\), \(\beta = 0,4\), \(\gamma = 0,3\), \(L = 4\). Predicción de los 8 trimestres siguientes.

# ==========================================
# EJERCICIO 19.39
# Metodo estacional de Holt-Winters (multiplicativo)
# ==========================================

anio <- rep(1:6, each = 4)
trimestre <- rep(1:4, times = 6)

ventas <- c(
  271, 199, 240, 255,
  341, 246, 245, 275,
  351, 283, 353, 292,
  401, 282, 306, 291,
  370, 242, 281, 274,
  356, 245, 304, 279
)

alpha <- 0.5
beta  <- 0.4
gamma <- 0.3
L <- 4

n <- length(ventas)

S <- numeric(n)
T <- numeric(n)
I <- numeric(n)

media_anio1 <- mean(ventas[1:4])
media_anio2 <- mean(ventas[5:8])

S[4] <- media_anio1
T[4] <- (media_anio2 - media_anio1) / L

I[1:4] <- ventas[1:4] / media_anio1

for (t in 5:n) {
  S[t] <- alpha * (ventas[t] / I[t - L]) + (1 - alpha) * (S[t - 1] + T[t - 1])
  T[t] <- beta  * (S[t] - S[t - 1]) + (1 - beta) * T[t - 1]
  I[t] <- gamma * (ventas[t] / S[t]) + (1 - gamma) * I[t - L]
}

resultados <- data.frame(
  Anio = anio, Trimestre = trimestre, Observado = ventas,
  Nivel_S = S, Tendencia_T = T, Indice_I = I
)
print(resultados, digits = 6)
##    Anio Trimestre Observado Nivel_S Tendencia_T Indice_I
## 1     1         1       271   0.000    0.000000 1.123316
## 2     1         2       199   0.000    0.000000 0.824870
## 3     1         3       240   0.000    0.000000 0.994819
## 4     1         4       255 241.250    8.875000 1.056995
## 5     2         1       341 276.845   19.563100 1.155842
## 6     2         2       246 297.318   19.927159 0.825628
## 7     2         3       245 281.761    5.733236 0.957233
## 8     2         4       275 273.833    0.268733 1.041175
## 9     3         1       351 288.888    6.183378 1.173590
## 10    3         2       283 318.920   15.722945 0.844150
## 11    3         3       353 351.707   22.548543 0.971165
## 12    3         4       292 327.354    3.787823 0.996423
## 13    4         1       401 336.414    5.896744 1.179108
## 14    4         2       282 338.187    4.247297 0.841062
## 15    4         3       306 328.760   -1.222569 0.959047
## 16    4         4       291 309.791   -8.321113 0.979299
## 17    5         1       370 307.633   -5.855801 1.186195
## 18    5         2       242 294.754   -8.665022 0.835050
## 19    5         3       281 289.544   -7.283049 0.962480
## 20    5         4       274 281.027   -7.776891 0.978008
## 21    6         1       356 286.685   -2.402978 1.202871
## 22    6         2       245 288.839   -0.580199 0.839003
## 23    6         3       304 302.055    4.938286 0.975668
## 24    6         4       279 296.133    0.594468 0.967249
h <- 1:8
indices_futuros <- I[(n - L + 1):n]
indices_repetidos <- rep(indices_futuros, 2)

predicciones <- (S[n] + h * T[n]) * indices_repetidos

predicciones_df <- data.frame(
  Anio = rep(7:8, each = 4),
  Trimestre = rep(1:4, times = 2),
  Prediccion = predicciones
)
print(predicciones_df, digits = 6)
##   Anio Trimestre Prediccion
## 1    7         1    356.925
## 2    7         2    249.454
## 3    7         3    290.668
## 4    7         4    288.734
## 5    8         1    359.786
## 6    8         2    251.449
## 7    8         3    292.988
## 8    8         4    291.034
t_futuro <- (n + 1):(n + 8)

plot(
  1:n, ventas, type = "o",
  xlim = c(1, n + 8),
  ylim = range(c(ventas, predicciones)),
  xlab = "Trimestre", ylab = "Ventas",
  main = "Holt-Winters estacional: nivel y predicciones"
)
lines(1:n, S, type = "o", col = "blue")
lines(t_futuro, predicciones, type = "o", col = "red")
legend("topleft",
       legend = c("Serie observada", "Nivel suavizado", "Predicciones"),
       col = c("black", "blue", "red"), lty = 1, pch = 1)

serie_ts <- ts(ventas, start = c(1, 1), frequency = 4)
modelo_hw <- HoltWinters(
  serie_ts,
  alpha = alpha, beta = beta, gamma = gamma,
  seasonal = "multiplicative"
)
modelo_hw
## Holt-Winters exponential smoothing with trend and multiplicative seasonal component.
## 
## Call:
## HoltWinters(x = serie_ts, alpha = alpha, beta = beta, gamma = gamma,     seasonal = "multiplicative")
## 
## Smoothing parameters:
##  alpha: 0.5
##  beta : 0.4
##  gamma: 0.3
## 
## Coefficients:
##           [,1]
## a  302.0360497
## b    3.5942050
## s1   1.2216471
## s2   0.8669597
## s3   0.9749290
## s4   0.9264404
predict(modelo_hw, n.ahead = 8)
##       Qtr1     Qtr2     Qtr3     Qtr4
## 7 373.3723 268.0852 304.9760 293.1377
## 8 390.9357 280.5493 318.9924 306.4569

10.1 Conclusión

Para las ventas trimestrales, el modelo estacional de Holt-Winters (\(\alpha = 0,5\), \(\beta = 0,4\), \(\gamma = 0,3\)) estima índices estacionales del último ciclo de aproximadamente 1,203 (T1), 0,839 (T2), 0,976 (T3) y 0,967 (T4), es decir, el primer trimestre de cada año es sistemáticamente el más fuerte (20% por encima del nivel promedio) y el segundo el más débil (16% por debajo). Con un nivel final \(S_{24} = 296,13\) y una tendencia final \(T_{24} = 0,594\) (prácticamente estable, con un leve crecimiento), las predicciones para los 8 trimestres siguientes (años 7 y 8) son: 356,93 – 249,45 – 290,67 – 288,73 – 359,79 – 251,45 – 292,99 – 291,03. El patrón estacional se repite claramente en ambos años, con un nivel base que crece muy levemente, lo cual es consistente con una serie que, tras un período de crecimiento fuerte en los primeros años, se ha estabilizado en los últimos ciclos. La verificación con HoltWinters() corrobora estos resultados.