Saltar al contenido

# series-de-tiempo-con-python

Series de Tiempo con Python

Volver a la portada del curso
Notebook

Práctica con Datos Reales

Sección 4 · Proyecto Aplicado de Series de Tiempo

Notebook: práctica con datos reales

Los pedidos de PyShop son sintéticos: se generaron con una tendencia, una estacionalidad y un ruido conocidos. En este notebook repites el proceso completo con una serie real, la concentración de CO2 en la atmósfera medida en el observatorio de Mauna Loa, Hawái, de 1958 a 2001. Viene incluida en statsmodels, así que no hay que descargar nada. Esta guía acompaña al notebook practica-con-datos-reales y te dice qué buscar en cada sección y qué resultados debes obtener.

Objetivos

  • Cargar una serie semanal real con huecos y llevarla a mensual.
  • Descomponerla y decidir entre modelo aditivo y multiplicativo.
  • Comprobar la estacionariedad con ADF y diferenciar.
  • Comparar Holt-Winters, SARIMA y el naive estacional en un periodo de prueba.
  • Pronosticar 2002 con un intervalo de confianza.

1. Carga y limpieza

El dataset trae 2284 semanas, de 1958-03-29 a 2001-12-29, con 59 semanas sin medición (NaN). El CO2 es un stock, un nivel en ppm: al pasar a mensual se promedia, no se suma.

from statsmodels.datasets import co2

semanal = co2.load_pandas().data["co2"]
print(len(semanal), int(semanal.isna().sum()))   # 2284 59
mensual = semanal.resample("MS").mean()
print(int(mensual.isna().sum()))                  # 5
serie = mensual.interpolate()
print(len(serie), round(serie.min(), 1), round(serie.max(), 1))  # 526 313.4 373.8

Al promediar por mes, la mayoría de los huecos semanales desaparecen; quedan 5 meses vacíos (junio y octubre de 1958, febrero a abril de 1964) que se interpolan. El resultado es lo que devuelve cargar_co2(): 526 meses, de 313.4 a 373.8 ppm.

2. Descomposición

El notebook aplica seasonal_decompose(serie, model="additive", period=12). La tendencia pasa de 315.45 ppm al inicio a 370.79 al final; el CO2 promedio sube de 316.0 ppm en 1959 a 370.85 en 2001, unos 1.3 ppm por año. Los efectos estacionales (enero a diciembre) son:

EneFebMarAbrMayJunJulAgoSepOctNovDic
−0.020.631.422.502.922.280.74−1.32−3.04−3.14−2.05−0.92

El máximo está en mayo y el mínimo en octubre, con una amplitud de 6.07 ppm. Por qué la aditiva: la oscilación de cada año casi no cambia (6.08 ppm de máximo a mínimo en 1960 y 5.11 en 2000) aunque el nivel subió más de 50 ppm. Si ajustas también la multiplicativa, los factores quedan entre 0.991 y 1.009: con una oscilación tan pequeña frente al nivel, ambas versiones dan casi lo mismo.

3. Estacionariedad

La prueba ADF sobre la serie mensual da un p-valor de 0.9989: no se puede rechazar que tenga raíz unitaria, la serie no es estacionaria. Después de serie.diff(12).diff(), una diferencia estacional y una regular, el p-valor es 0.0. Por eso el SARIMA del notebook usa $d = 1$ y $D = 1$.

4. Comparar modelos

Se entrena con 1958-1998 y se prueba con los 36 meses de 1999-2001, cortando por fecha:

import numpy as np
from statsmodels.tsa.holtwinters import ExponentialSmoothing
from statsmodels.tsa.statespace.sarimax import SARIMAX

tr, te = serie[:"1998-12"], serie["1999-01":]
hw = ExponentialSmoothing(tr, trend="add", seasonal="add",
                          seasonal_periods=12).fit()
sar = SARIMAX(tr, order=(1, 1, 1),
              seasonal_order=(0, 1, 1, 12)).fit(disp=False)
naive = np.tile(tr.iloc[-12:].to_numpy(), 3)
for nombre, p in [("HW", hw.forecast(36)), ("SARIMA", sar.forecast(36)), ("naive", naive)]:
    print(nombre, round(np.mean(np.abs(te.to_numpy() - np.asarray(p))), 3))
ModeloMAE (ppm)
Holt-Winters aditivo0.826
SARIMA(1,1,1)(0,1,1,12)0.969
Naive estacional2.866

Aquí el naive estacional repite los 12 meses de 1998 tres veces y no sube: como el CO2 crece unos 1.3 ppm por año, su error aumenta año con año. Holt-Winters y SARIMA capturan la tendencia y quedan por debajo de 1 ppm, menos de 0.3 % del nivel. En los pedidos, Holt-Winters multiplicativo también ganó; en el CO2 gana el aditivo, porque la serie es aditiva.

5. Intervalo y pronóstico de 2002

Con sar.get_forecast(36).conf_int(), 35 de los 36 meses reales caen dentro del intervalo del 95 %. Para diciembre de 2001 el SARIMA pronostica 372.11 ppm con intervalo [369.73, 374.49]; el real fue 371.02. Al final, el notebook reentrena con toda la serie y pronostica 2002: un promedio anual de 372.55 ppm, con mayo en 375.34 e intervalo [374.41, 376.27]. Holt-Winters da un promedio de 372.34.

Qué debes obtener

526 meses, amplitud estacional de 6.07 ppm con máximo en mayo, ADF 0.9989 antes de diferenciar y 0.0 después, y MAE de 0.826 (HW), 0.969 (SARIMA) y 2.866 (naive estacional). Si tus números difieren, revisa que promediaste en lugar de sumar y que el corte es 1998-12. Como práctica, repite la comparación con un horizonte de 12 meses en lugar de 36 y observa cuánto baja el error del naive estacional.

Recursos