Autocorrelograma y pruebas de ruido blanco para el IMAE de Costa Rica
Contents
1.2. Autocorrelograma y pruebas de ruido blanco para el IMAE de Costa Rica#
Ejemplo numérico para ilustrar el uso del autocorrelograma y el autocorrelograma parcial.
Nota Para ejecutar este cuaderno se requiere el paquete bccr
. Si no lo tiene, ejecute la siguiente celda
try:
import bccr
except ImportError:
print('Module bccr missing. Installing it now')
!pip install bccr
from bccr import SW
import matplotlib.pyplot as plt
plt.style.use('seaborn')
import pandas as pd
import numpy as np
import statsmodels.api as sm
from scipy.stats.distributions import chi2
import os
figpath = "../figures/"
Importamos los datos#
La clase ServicioWeb
permite obtener datos directamente del Banco Central de Costa Rica
Buscamos series que tenga “IMAE” en su DESCRIPCION, frecuencia mensual. Filtramos los resultados para ver solo las series en nivel, y dejamos solo aquellos qe tengan la palabra “IMAE” en su descripción
imaes = SW.buscar(todos='IMAE', frecuencia='M')
imaes = imaes[imaes.Unidad == 'Nivel']
imaes[imaes.descripcion.str.contains('IMAE')]
DESCRIPCION | descripcion | Unidad | Medida | periodo | |
---|---|---|---|---|---|
codigo | |||||
913 | Node('/BCCR/Sector Real/IMAE con IEAT, Serie Original [913]') | Indice Mensual de Actividad Económica (IMAE) con la Industria Electronica de Alta Tecnologia (IEAT). Serie Original | Nivel | NO DEFINIDO | Mensual |
914 | Node('/BCCR/Sector Real/IMAE con IEAT, Tendencia Ciclo [914]') | Índice Mensual de Actividad Económica (IMAE) con la Industria Electrónica de Alta Tecnología (IEAT). Serie Tendencia... | Nivel | NO DEFINIDO | Mensual |
915 | Node('/BCCR/Sector Real/IMAE sin IEAT, Serie Original [915]') | Índice Mensual de Actividad Económica (IMAE) sin la Industria Electrónica de Alta Tecnología (IEAT). Serie Original | Nivel | NO DEFINIDO | Mensual |
916 | Node('/BCCR/Sector Real/IMAE sin IEAT, Tendencia Ciclo [916]') | Índice Mensual de Actividad Económica (IMAE) sin la Industria Electrónica de Alta Tecnología (IEAT). Serie Tendencia... | Nivel | NO DEFINIDO | Mensual |
22718 | Node('/BCCR/Sector Real/IMAE con IEAT, Desestacionalizada [22718]') | Índice Mensual de Actividad Económica (IMAE) con la Industria Electrónica de Alta Tecnología (IEAT). Serie Desestaci... | Nivel | NO DEFINIDO | Mensual |
25158 | Node('/BCCR/Sector Real/IMAE con IEAT, Desestacionalizada [22718]/IMAE específico [25158]') | IMAE específico1991=100 | Nivel | No definida | Mensual |
22967 | Node('/BCCR/Sector Real/IMAE sin Zona Franca Serie Original [22967]') | IMAE sin Zona Franca Serie Original | Nivel | NO DEFINIDO | Mensual |
22970 | Node('/BCCR/Sector Real/IMAE sin Zona Franca Serie Tendencia Ciclo [22970]') | IMAE sin Zona Franca Serie Original | Nivel | NO DEFINIDO | Mensual |
35449 | Node('/BCCR/Sector Real/IMAE , Serie Original [35449]') | IMAE , Serie Original | Nivel | NO DEFINIDO | Mensual |
35553 | Node('/BCCR/Sector Real/IMAE Tendencia Ciclo [35553]') | IMAE Tendencia Ciclo | Nivel | NO DEFINIDO | Mensual |
35660 | Node('/BCCR/Sector Real/IMAE, Serie Desestacionalizadal [35660]') | IMAE, Serie Desestacionalizadal | Nivel | NO DEFINIDO | Mensual |
De esta lista, escogemos los indicadores 35449 (serie original) y 35553 (tendencia-ciclo) (éstas están discontinuadas, usarememos entonces las series 87703 y 87764, que de momentos no pueden encontrarse con bccr, pero sí descargarse). Descargamos los datos y cambiamos los nombres de las series.
imae = SW(Original=87703, Tendencia_ciclo=87764)
Graficamos las dos series para ver su dinamica.
imae.plot(figsize=[12,5])
<AxesSubplot:xlabel='fecha'>
Autocorrelograma#
Obtenemos autocorrelogramas (48 rezagos, con intervalos de 95% de significancia (Bartlett)) para las series en nivel, primera diferencia, y diferencia estacional.
OPCIONES = dict(lags=48, alpha=0.05, title='')
plot_acf = sm.graphics.tsa.plot_acf
plot_pacf = sm.graphics.tsa.plot_pacf
log_imae = np.log(imae)
fig, axs = plt.subplots(3,2, figsize=[16,9], sharex=True, sharey=True)
for indic, ax in zip(imae, axs.T):
plot_acf(log_imae[indic].dropna(), ax=ax[0], **OPCIONES);
plot_acf(log_imae[indic].diff().dropna(), ax=ax[1], **OPCIONES);
plot_acf(log_imae[indic].diff(12).dropna(), ax=ax[2], **OPCIONES);
for indic, ax in zip(imae, axs[0]):
ax.set_title(indic)
for ax in axs[-1]:
ax.set_xlabel(r'Rezago $\tau$')
ax.set_xticks(np.arange(0,49,12));
axs[0,0].set_ylabel(r'$\log(IMAE)$')
axs[1,0].set_ylabel(r'$\Delta log(IMAE)$')
axs[2,0].set_ylabel(r'$\Delta_{12} log(IMAE)$')
fig.suptitle('Autocorrelograma del IMAE (original y tendencia-ciclo) en Costa Rica', size=16)
fig.savefig(figpath + 'IMAE-acf.pdf', bbox_inches='tight')
Autocorrelograma parcial#
Repetimos el ejercicio, pero esta vez obtenemos autocorrelogramas parciales (48 rezagos, con intervalos de 95% de significancia) para las series en nivel, primera diferencia, y diferencia estacional.
OPCIONES = dict(lags=48, alpha=0.05, title='', method='ols')
fig, axs = plt.subplots(3,2, figsize=[16,9], sharex=True, sharey=True)
for indic, ax in zip(imae, axs.T):
plot_pacf(log_imae[indic].dropna(), ax=ax[0], **OPCIONES);
plot_pacf(log_imae[indic].diff().dropna(), ax=ax[1], **OPCIONES);
plot_pacf(log_imae[indic].diff(12).dropna(), ax=ax[2], **OPCIONES);
for indic, ax in zip(imae, axs[0]):
ax.set_title(indic)
for ax in axs[-1]:
ax.set_xlabel(r'Rezago $\tau$')
ax.set_xticks(np.arange(0,49,12));
axs[0,0].set_ylabel(r'$\log(IMAE)$')
axs[1,0].set_ylabel(r'$\Delta log(IMAE)$')
axs[2,0].set_ylabel(r'$\Delta_{12} log(IMAE)$')
fig.suptitle('Autocorrelograma parcial del IMAE (original y tendencia-ciclo) en Costa Rica', size=16)
fig.savefig(figpath + 'IMAE-pacf.pdf', bbox_inches='tight')
Pruebas de ruido blanco#
¿Es es crecimiento mensual del IMAE tendencia-ciclo un proceso ruido blanco?
growth = log_imae['Tendencia_ciclo'].diff().dropna()
T = growth.size # número de datos
M = 7 # máximo número de rezagos
rezagos = np.arange(1, M+1)
alpha = 0.05 # significancia de los test
Calculamos las autocovarianzas, a partir de un rezago
rho = sm.tsa.acf(growth, fft=True, nlags=M)[1:]
Calculamos el estadístico de Box-Pierce, para todos los rezagos desde el 1 hasta el 7
Qstar = T * (rho ** 2).cumsum()
Calculamos el estadístico de Ljung-Box
Q = T * (T+2) * ((rho ** 2)/(T-rezagos)).cumsum()
Calculamos los valores críticos, tomando en cuenta que \(k=0\) porque los datos que estamos usando no son residuos
vcrits = np.array([chi2(k).ppf(1-alpha) for k in rezagos])
Con carácter informativo nada más, calculamos la autocorrelación parcial
rhop = sm.tsa.pacf(growth, nlags=M, method='ols')[1:]
Juntamos todos los resultados en una tabla de resumen.
resumen = pd.DataFrame({'AC':rho, 'PAC': rhop, 'Box-Pierce':Qstar, 'Ljung-Box':Q, f'$\chi^2(m-k)$': vcrits}, index=rezagos)
resumen.index.name = 'Rezagos'
resumen.round(3)
AC | PAC | Box-Pierce | Ljung-Box | $\chi^2(m-k)$ | |
---|---|---|---|---|---|
Rezagos | |||||
1 | 0.106 | 0.106 | 4.184 | 4.218 | 3.841 |
2 | 0.085 | 0.075 | 6.885 | 6.948 | 5.991 |
3 | 0.068 | 0.052 | 8.596 | 8.682 | 7.815 |
4 | 0.057 | 0.040 | 9.790 | 9.896 | 9.488 |
5 | 0.034 | 0.017 | 10.231 | 10.345 | 11.070 |
6 | 0.021 | 0.006 | 10.402 | 10.520 | 12.592 |
7 | 0.016 | 0.005 | 10.499 | 10.619 | 14.067 |
Exportar datos#
Finalmente, exportamos los datos para poder replicar este ejercicio con otros programas (Stata, EViews, R).
log_imae.to_csv('log_imae.csv')