##Carga de librerías
library(forecast)
library(tseries)
library(ggplot2)
library(knitr)
data(nottem)
temperatura <- nottem # Renombre de la serie
temperatura
## Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
## 1920 40.6 40.8 44.4 46.7 54.1 58.5 57.7 56.4 54.3 50.5 42.9 39.8
## 1921 44.2 39.8 45.1 47.0 54.1 58.7 66.3 59.9 57.0 54.2 39.7 42.8
## 1922 37.5 38.7 39.5 42.1 55.7 57.8 56.8 54.3 54.3 47.1 41.8 41.7
## 1923 41.8 40.1 42.9 45.8 49.2 52.7 64.2 59.6 54.4 49.2 36.3 37.6
## 1924 39.3 37.5 38.3 45.5 53.2 57.7 60.8 58.2 56.4 49.8 44.4 43.6
## 1925 40.0 40.5 40.8 45.1 53.8 59.4 63.5 61.0 53.0 50.0 38.1 36.3
## 1926 39.2 43.4 43.4 48.9 50.6 56.8 62.5 62.0 57.5 46.7 41.6 39.8
## 1927 39.4 38.5 45.3 47.1 51.7 55.0 60.4 60.5 54.7 50.3 42.3 35.2
## 1928 40.8 41.1 42.8 47.3 50.9 56.4 62.2 60.5 55.4 50.2 43.0 37.3
## 1929 34.8 31.3 41.0 43.9 53.1 56.9 62.5 60.3 59.8 49.2 42.9 41.9
## 1930 41.6 37.1 41.2 46.9 51.2 60.4 60.1 61.6 57.0 50.9 43.0 38.8
## 1931 37.1 38.4 38.4 46.5 53.5 58.4 60.6 58.2 53.8 46.6 45.5 40.6
## 1932 42.4 38.4 40.3 44.6 50.9 57.0 62.1 63.5 56.3 47.3 43.6 41.8
## 1933 36.2 39.3 44.5 48.7 54.2 60.8 65.5 64.9 60.1 50.2 42.1 35.8
## 1934 39.4 38.2 40.4 46.9 53.4 59.6 66.5 60.4 59.2 51.2 42.8 45.8
## 1935 40.0 42.6 43.5 47.1 50.0 60.5 64.6 64.0 56.8 48.6 44.2 36.4
## 1936 37.3 35.0 44.0 43.9 52.7 58.6 60.0 61.1 58.1 49.6 41.6 41.3
## 1937 40.8 41.0 38.4 47.4 54.1 58.6 61.4 61.8 56.3 50.9 41.4 37.1
## 1938 42.1 41.2 47.3 46.6 52.4 59.0 59.6 60.4 57.0 50.7 47.8 39.2
## 1939 39.4 40.9 42.4 47.8 52.4 58.0 60.7 61.8 58.2 46.7 46.6 37.8
class(temperatura)
## [1] "ts"
# Resultado esperado: "ts" → Es una serie temporal, no necesita conversión.
any(is.na(temperatura)) # TRUE si hay NA
## [1] FALSE
sum(is.na(temperatura)) # Cuántos NA
## [1] 0
which(is.na(temperatura)) # En qué posiciones
## integer(0)
# ── Limpieza: eliminar NA si los hay ──────────────────────────
if (any(is.na(temperatura))) {
# na.approx interpola los NA usando los valores vecinos
# (mantiene el objeto como serie temporal ts)
temperatura <- na.approx(temperatura)
cat("NA eliminados por interpolación lineal.\n")
cat("NA restantes:", sum(is.na(temperatura)), "\n")
} else {
cat("No hay valores faltantes. No se requiere limpieza.\n")
}
## No hay valores faltantes. No se requiere limpieza.
Interpretación: La serie
nottemno presenta valores faltantes (NA). La visualización confirma un comportamiento estacional claro con ciclos anuales.
tabla_caracteristicas <- data.frame(
Caracteristica = c("Inicio", "Fin", "Frecuencia",
"Mínimo", "Q1", "Mediana",
"Media", "Q3", "Máximo"),
Valor = c(
paste(start(temperatura), collapse = "-"),
paste(end(temperatura), collapse = "-"),
frequency(temperatura),
min(temperatura),
quantile(temperatura, 0.25),
median(temperatura),
round(mean(temperatura), 2),
quantile(temperatura, 0.75),
max(temperatura)
)
)
kable(tabla_caracteristicas,
caption = "Características de la serie nottem",
align = c("l", "r"))
| Caracteristica | Valor |
|---|---|
| Inicio | 1920-1 |
| Fin | 1939-12 |
| Frecuencia | 12 |
| Mínimo | 31.3 |
| Q1 | 41.55 |
| Mediana | 47.35 |
| Media | 49.04 |
| Q3 | 57 |
| Máximo | 66.5 |
Interpretación: La serie abarca 20 años completos (1920–1939) con 240 observaciones mensuales. La temperatura media es de 49.05°F, con mínimo de 31.3°F (invierno) y máximo de 66.5°F (verano), lo que confirma una marcada estacionalidad anual.
autoplot(temperatura) +
ggtitle("Temperaturas mensuales – Nottingham (1920–1939)") +
ylab("Temperatura (°F)") + xlab("Año") +
theme_minimal()
Interpretación: Presenta una estacionalidad anual muy marcada y regular, con picos de verano alrededor de 62–66°F (julio–agosto) y valles de invierno entre 35–42°F (enero–febrero), generando una amplitud de aproximadamente 25–30°F que se mantiene constante a lo largo de los 20 años, lo que sugiere un comportamiento estacionario.
# Descomposición multiplicativa
temperatura.decom <- decompose(temperatura, type ="multiplicative")
plot(temperatura.decom)
Interpretación: La descomposición revela:
# ACF
acf(temperatura,
lag.max = 48,
main = "Correlograma ACF – Temperaturas Nottingham")
# PACF
pacf(temperatura,
lag.max = 48,
main = "Correlograma PACF – Temperaturas Nottingham")
Interpretación (en función de tendencia y estacionalidad): - El ACF muestra un patrón sinusoidal con picos significativos cada 12 rezagos (lag 12, 24, 36), confirmando la estacionalidad anual fuerte. - Los valores del ACF decaen lentamente, lo que indica cierta persistencia en la serie, aunque la tendencia visual es plana. - El PACF muestra un corte abrupto después del lag 1–2 y picos en los rezagos estacionales (12, 24), consistente con una estructura AR estacional. - Conclusión: la serie tiene estacionalidad determinística fuerte y no requiere diferenciación para Holt-Winters.
# Modelo
temperatura.hw.mult <- HoltWinters(temperatura, seasonal = "mult")
# 1. Parámetros de suavización
tabla_parametros <- data.frame(
Parametro = c("Alpha (nivel)", "Beta (tendencia)", "Gamma (estacional)"),
Valor = c(
temperatura.hw.mult$alpha,
temperatura.hw.mult$beta,
temperatura.hw.mult$gamma
)
)
# 2. Coeficientes (nivel, tendencia y estacionales)
coeficientes <- as.data.frame(temperatura.hw.mult$coef)
tabla_coef <- data.frame(
Coeficiente = rownames(coeficientes),
Valor = coeficientes[,1]
)
# 3. Métrica del modelo
tabla_metricas <- data.frame(
Metrica = "SSE (Error cuadrático)",
Valor = temperatura.hw.mult$SSE
)
# Mostrar tablas
kable(tabla_parametros, caption = "Parámetros de suavización")
| Parametro | Valor | |
|---|---|---|
| alpha | Alpha (nivel) | 0.1245727 |
| beta | Beta (tendencia) | 0.0189613 |
| gamma | Gamma (estacional) | 0.2255464 |
kable(tabla_coef, caption = "Coeficientes del modelo")
| Coeficiente | Valor |
|---|---|
| a | 50.4976725 |
| b | 0.0034626 |
| s1 | 0.7895952 |
| s2 | 0.7863645 |
| s3 | 0.8444163 |
| s4 | 0.9240776 |
| s5 | 1.0404888 |
| s6 | 1.1624451 |
| s7 | 1.2219231 |
| s8 | 1.2208696 |
| s9 | 1.1379220 |
| s10 | 0.9771861 |
| s11 | 0.8765871 |
| s12 | 0.7724631 |
kable(tabla_metricas, caption = "Métrica del modelo")
| Metrica | Valor |
|---|---|
| SSE (Error cuadrático) | 1541.807 |
Interpretación: - Alpha cercano a 0 indica que el nivel se suaviza mucho, dando más peso a observaciones pasadas. - Beta muy bajo (o ~0) confirma que la tendencia es casi inexistente en la serie. - Gamma elevado indica que el patrón estacional se actualiza con mayor rapidez ante cambios recientes. - Los coeficientes estacionales
s1–s12representan los factores multiplicativos por mes: valores > 1 indican meses más cálidos que el promedio, < 1 meses más fríos.
plot(temperatura.hw.mult,
main = "Ajuste Holt-Winters Multiplicativo – Nottingham",
ylab = "Temperatura (°F)",
col = c("black", "red"))
legend("topright", legend = c("Observado", "Ajustado HW"),
col = c("black", "red"), lty = 1)
Interpretación: La línea ajustada sigue de cerca la serie original, capturando bien los picos y valles estacionales.
# Pronóstico
temperatura.pred.mult <- predict(
temperatura.hw.mult,
n.ahead = 5 * 12,
prediction.interval = TRUE
)
# Convertir a data frame
tabla_pred <- data.frame(
Tiempo = time(temperatura.pred.mult),
Pronostico = temperatura.pred.mult[,1],
Limite_Inferior = temperatura.pred.mult[,2],
Limite_Superior = temperatura.pred.mult[,3]
)
# Mostrar tabla
kable(tabla_pred, caption = "Pronóstico Holt-Winters (Modelo Multiplicativo)")
| Tiempo | Pronostico | Limite_Inferior | Limite_Superior |
|---|---|---|---|
| 1940.000 | 39.87546 | 41.51180 | 38.23911 |
| 1940.083 | 39.71502 | 41.47294 | 37.95711 |
| 1940.167 | 42.64983 | 44.56060 | 40.73906 |
| 1940.250 | 46.67656 | 48.77060 | 44.58253 |
| 1940.333 | 52.56028 | 54.89469 | 50.22586 |
| 1940.417 | 58.72492 | 61.32928 | 56.12057 |
| 1940.500 | 61.73389 | 64.53327 | 58.93451 |
| 1940.583 | 61.68489 | 64.58767 | 58.78211 |
| 1940.667 | 57.49787 | 60.36291 | 54.63284 |
| 1940.750 | 49.37946 | 52.06362 | 46.69530 |
| 1940.833 | 44.29899 | 46.90295 | 41.69504 |
| 1940.917 | 39.03969 | 404.09008 | -326.01071 |
| 1941.000 | 39.90826 | 187.02439 | -107.20787 |
| 1941.083 | 39.74770 | 188.98910 | -109.49371 |
| 1941.167 | 42.68492 | 205.86973 | -120.49990 |
| 1941.250 | 46.71496 | 228.49613 | -135.06621 |
| 1941.333 | 52.60351 | 260.88935 | -155.68233 |
| 1941.417 | 58.77322 | 295.50037 | -177.95392 |
| 1941.500 | 61.78466 | 314.85998 | -191.29066 |
| 1941.583 | 61.73562 | 318.82586 | -195.35462 |
| 1941.667 | 57.54515 | 301.11524 | -186.02493 |
| 1941.750 | 49.42006 | 261.97645 | -163.13632 |
| 1941.833 | 44.33542 | 238.05191 | -149.38108 |
| 1941.917 | 39.07178 | 578.53140 | -500.38783 |
| 1942.000 | 39.94107 | 272.37641 | -192.49426 |
| 1942.083 | 39.78037 | 275.10159 | -195.54085 |
| 1942.167 | 42.72000 | 299.53163 | -214.09163 |
| 1942.250 | 46.75336 | 332.29955 | -238.79283 |
| 1942.333 | 52.64674 | 379.24031 | -273.94682 |
| 1942.417 | 58.82153 | 429.36742 | -311.72437 |
| 1942.500 | 61.83544 | 457.30558 | -333.63470 |
| 1942.583 | 61.78635 | 462.87698 | -339.30428 |
| 1942.667 | 57.59244 | 436.99088 | -321.80601 |
| 1942.750 | 49.46067 | 380.04356 | -281.12223 |
| 1942.833 | 44.37184 | 345.20659 | -256.46291 |
| 1942.917 | 39.10388 | 728.54557 | -650.33780 |
| 1943.000 | 39.97388 | 355.10810 | -275.16033 |
| 1943.083 | 39.81305 | 358.32916 | -278.70307 |
| 1943.167 | 42.75509 | 389.80015 | -304.28997 |
| 1943.250 | 46.79176 | 432.06635 | -338.48284 |
| 1943.333 | 52.68998 | 492.68259 | -387.30264 |
| 1943.417 | 58.86983 | 557.34464 | -439.60499 |
| 1943.500 | 61.88621 | 593.13380 | -469.36139 |
| 1943.583 | 61.83708 | 599.89102 | -476.21686 |
| 1943.667 | 57.63972 | 565.91143 | -450.63199 |
| 1943.750 | 49.50127 | 491.79822 | -392.79568 |
| 1943.833 | 44.40827 | 446.39413 | -357.57760 |
| 1943.917 | 39.13598 | 868.75424 | -790.48228 |
| 1944.000 | 40.00669 | 439.57036 | -359.55698 |
| 1944.083 | 39.84572 | 443.13531 | -363.44387 |
| 1944.167 | 42.79018 | 481.60826 | -396.02790 |
| 1944.250 | 46.83015 | 533.34786 | -439.68755 |
| 1944.333 | 52.73321 | 607.63894 | -502.17252 |
| 1944.417 | 58.91813 | 686.79962 | -568.96336 |
| 1944.500 | 61.93698 | 730.29083 | -606.41686 |
| 1944.583 | 61.88781 | 738.00848 | -614.23286 |
| 1944.667 | 57.68700 | 695.65158 | -580.27757 |
| 1944.750 | 49.54187 | 604.07749 | -504.99374 |
| 1944.833 | 44.44469 | 547.89162 | -459.00225 |
| 1944.917 | 39.16807 | 1004.51346 | -926.17731 |
ts.plot(temperatura, temperatura.pred.mult,
lty = c(1, 1, 2, 2),
col = c("black", "blue", "lightblue", "lightblue"),
main = "Pronóstico Holt-Winters Multiplicativo – Nottingham (5 años)",
ylab = "Temperatura (°F)", xlab = "Año")
legend("topright",
legend = c("Observado", "Pronóstico", "IC 95%"),
col = c("black", "blue", "lightblue"),
lty = c(1, 1, 2))
Interpretación: El pronóstico mantiene el patrón estacional anual de forma estable, con intervalos de confianza que se amplían ligeramente hacia el futuro. La ausencia de tendencia hace que los pronósticos sean razonablemente confiables a 5 años.
# Modelo
temperatura.hw.add <- HoltWinters(temperatura, seasonal = "add")
# 1. Parámetros de suavización
tabla_parametros <- data.frame(
Parametro = c("Alpha (nivel)", "Beta (tendencia)", "Gamma (estacional)"),
Valor = c(
temperatura.hw.add$alpha,
temperatura.hw.add$beta,
temperatura.hw.add$gamma
)
)
# 2. Coeficientes (nivel, tendencia y estacionales)
coeficientes <- as.data.frame(temperatura.hw.add$coef)
tabla_coef <- data.frame(
Coeficiente = rownames(coeficientes),
Valor = coeficientes[,1]
)
# 3. Métrica del modelo
tabla_metricas <- data.frame(
Metrica = "SSE (Error cuadrático)",
Valor = temperatura.hw.add$SSE
)
# Mostrar tablas
kable(tabla_parametros, caption = "Parámetros de suavización")
| Parametro | Valor | |
|---|---|---|
| alpha | Alpha (nivel) | 0.1383228 |
| beta | Beta (tendencia) | 0.0232747 |
| gamma | Gamma (estacional) | 0.2348744 |
kable(tabla_coef, caption = "Coeficientes del modelo")
| Coeficiente | Valor |
|---|---|
| a | 50.2876445 |
| b | -0.0012364 |
| s1 | -10.5245658 |
| s2 | -10.6376401 |
| s3 | -7.7218681 |
| s4 | -3.7136035 |
| s5 | 2.1467664 |
| s6 | 8.3220057 |
| s7 | 11.3016637 |
| s8 | 11.2845670 |
| s9 | 7.0928797 |
| s10 | -1.0465972 |
| s11 | -6.0506043 |
| s12 | -11.3881437 |
kable(tabla_metricas, caption = "Métrica del modelo")
| Metrica | Valor |
|---|---|
| SSE (Error cuadrático) | 1563.474 |
plot(temperatura.hw.add,
main = "Ajuste Holt-Winters Aditivo – Nottingham",
ylab = "Temperatura (°F)",
col = c("black", "darkgreen"))
legend("topright", legend = c("Observado", "Ajustado HW Aditivo"),
col = c("black", "darkgreen"), lty = 1)
temperatura.pred.add <- predict(
temperatura.hw.add,
n.ahead = 5 * 12,
prediction.interval = TRUE
)
# Convertir a data frame
tabla_predi<- data.frame(
Tiempo = time(temperatura.pred.add),
Pronostico = temperatura.pred.add[,1],
Limite_Inferior = temperatura.pred.add[,2],
Limite_Superior = temperatura.pred.add[,3]
)
kable(tabla_predi,caption = "Pronóstico Holt-Winters (Modelo Aditivo)")
| Tiempo | Pronostico | Limite_Inferior | Limite_Superior |
|---|---|---|---|
| 1940.000 | 39.76184 | 44.88449 | 34.63919 |
| 1940.083 | 39.64753 | 44.82124 | 34.47382 |
| 1940.167 | 42.56207 | 47.78865 | 37.33548 |
| 1940.250 | 46.56910 | 51.85037 | 41.28782 |
| 1940.333 | 52.42823 | 57.76600 | 47.09046 |
| 1940.417 | 58.60223 | 63.99830 | 53.20617 |
| 1940.500 | 61.58065 | 67.03681 | 56.12450 |
| 1940.583 | 61.56232 | 67.08035 | 56.04429 |
| 1940.667 | 57.36940 | 62.95107 | 51.78772 |
| 1940.750 | 49.22868 | 54.87577 | 43.58160 |
| 1940.833 | 44.22344 | 49.93768 | 38.50920 |
| 1940.917 | 38.88466 | 44.66780 | 33.10153 |
| 1941.000 | 39.74700 | 45.84789 | 33.64612 |
| 1941.083 | 39.63269 | 45.80300 | 33.46239 |
| 1941.167 | 42.54723 | 48.78865 | 36.30581 |
| 1941.250 | 46.55426 | 52.86846 | 40.24005 |
| 1941.333 | 52.41339 | 58.80204 | 46.02474 |
| 1941.417 | 58.58739 | 65.05213 | 52.12266 |
| 1941.500 | 61.56582 | 68.10827 | 55.02336 |
| 1941.583 | 61.54748 | 68.16927 | 54.92570 |
| 1941.667 | 57.35456 | 64.05727 | 50.65184 |
| 1941.750 | 49.21385 | 55.99907 | 42.42862 |
| 1941.833 | 44.20860 | 51.07789 | 37.33931 |
| 1941.917 | 38.86983 | 45.82473 | 31.91493 |
| 1942.000 | 39.73217 | 47.00919 | 32.45514 |
| 1942.083 | 39.61786 | 46.98070 | 32.25501 |
| 1942.167 | 42.53239 | 49.98257 | 35.08222 |
| 1942.250 | 46.53942 | 54.07842 | 39.00042 |
| 1942.333 | 52.39855 | 60.02786 | 44.76925 |
| 1942.417 | 58.57256 | 66.29362 | 50.85149 |
| 1942.500 | 61.55098 | 69.36525 | 53.73670 |
| 1942.583 | 61.53265 | 69.44156 | 53.62374 |
| 1942.667 | 57.33972 | 65.34468 | 49.33476 |
| 1942.750 | 49.19901 | 57.30141 | 41.09661 |
| 1942.833 | 44.19376 | 52.39499 | 35.99254 |
| 1942.917 | 38.85499 | 47.15639 | 30.55358 |
| 1943.000 | 39.71733 | 48.34197 | 31.09269 |
| 1943.083 | 39.60302 | 48.32791 | 30.87813 |
| 1943.167 | 42.51756 | 51.34403 | 33.69108 |
| 1943.250 | 46.52458 | 55.45397 | 37.59520 |
| 1943.333 | 52.38372 | 61.41732 | 43.35011 |
| 1943.417 | 58.55772 | 67.69684 | 49.41860 |
| 1943.500 | 61.53614 | 70.78206 | 52.29022 |
| 1943.583 | 61.51781 | 70.87179 | 52.16383 |
| 1943.667 | 57.32488 | 66.78818 | 47.86159 |
| 1943.750 | 49.18417 | 58.75802 | 39.61032 |
| 1943.833 | 44.17893 | 53.86455 | 34.49330 |
| 1943.917 | 38.84015 | 48.63876 | 29.04155 |
| 1944.000 | 39.70249 | 49.82419 | 29.58079 |
| 1944.083 | 39.58818 | 49.82288 | 29.35348 |
| 1944.167 | 42.50272 | 52.85162 | 32.15382 |
| 1944.250 | 46.50975 | 56.97403 | 36.04546 |
| 1944.333 | 52.36888 | 62.94972 | 41.78804 |
| 1944.417 | 58.54288 | 69.24143 | 47.84434 |
| 1944.500 | 61.52130 | 72.33871 | 50.70390 |
| 1944.583 | 61.50297 | 72.44036 | 50.56558 |
| 1944.667 | 57.31005 | 68.36854 | 46.25155 |
| 1944.750 | 49.16933 | 60.35004 | 37.98862 |
| 1944.833 | 44.16409 | 55.46811 | 32.86007 |
| 1944.917 | 38.82531 | 50.25373 | 27.39690 |
ts.plot(temperatura, temperatura.pred.add,
lty = c(1, 1, 2, 2),
col = c("black", "darkgreen", "lightgreen", "lightgreen"),
main = "Pronóstico Holt-Winters Aditivo – Nottingham (5 años)",
ylab = "Temperatura (°F)", xlab = "Año")
legend("topright",
legend = c("Observado", "Pronóstico", "IC 95%"),
col = c("black", "darkgreen", "lightgreen"),
lty = c(1, 1, 2))
cat("SSE Multiplicativo:", temperatura.hw.mult$SSE, "\n")
## SSE Multiplicativo: 1541.807
cat("SSE Aditivo: ", temperatura.hw.add$SSE, "\n")
## SSE Aditivo: 1563.474
cat("Diferencia (Mult - Add):", temperatura.hw.mult$SSE - temperatura.hw.add$SSE, "\n")
## Diferencia (Mult - Add): -21.66639
Interpretación comparativa: Para la serie
nottem, dado que la amplitud estacional es relativamente constante a lo largo del tiempo (no crece ni decrece con el nivel), ambos modelos producen resultados similares. Sin embargo, si el SSE del modelo multiplicativo es menor o similar, se prefiere el multiplicativo porque es conceptualmente más apropiado para series donde la variación estacional es proporcional al nivel (temperatura). Si el SSE aditivo es menor, indicaría que la amplitud estacional es verdaderamente constante y se preferiría el aditivo por su mayor parsimonia.
Comentario: La serie
nottemno es adecuada para aplicar el Modelo de Bass. Este modelo está diseñado para describir la difusión de innovaciones — el proceso por el cual un nuevo producto o tecnología es adoptado por una población a lo largo del tiempo, con una curva en forma de campana (adopción crece, alcanza un pico y decrece).nottemes una serie de temperaturas atmosféricas cíclicas y recurrentes, sin un proceso de adopción, saturación de mercado ni punto de inflexión propio de la difusión tecnológica. No existe un “mercado potencial” ni adopciones acumuladas que modelar. Por lo tanto, aplicar Bass a esta serie sería conceptualmente incorrecto.