Proceso de media móvil MA(q)
Contents
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn')
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from statsmodels.tsa.arima_process import ArmaProcess # MODELO TEORICO
def graficar_impulso_respuesta(fig, proceso, maxlag=18, **kwargs):
fig.add_trace(go.Bar(y=proceso.impulse_response(maxlag)), **kwargs)
def graficar_autocorrelacion(fig, proceso, maxlag=12, **kwargs):
rezagos = 1 + np.arange(maxlag)
fig.add_trace(go.Bar(x=rezagos, y=proceso.acf(maxlag+1)[1:]), **kwargs)
def graficar_autocorrelacion_parcial(fig, proceso, maxlag=12, **kwargs):
rezagos = 1 + np.arange(maxlag)
fig.add_trace(go.Bar(x=rezagos, y=proceso.pacf(maxlag+1)[1:]), **kwargs)
def graficar_simulacion(fig, proceso, nperiodos=120, **kwargs):
fig.add_trace(go.Scatter(y=proceso.generate_sample(nperiodos)), **kwargs)
def graficar_raices(fig, raices):
r, theta = np.abs(1/raices), np.angle(1/raices, True)
rmax = 1.0 if np.max(r) < 1.0 else np.maximum(r)
fig.add_trace(go.Scatterpolar(
r=r,
theta=theta,
mode = 'markers',
marker_size=14
))
fig.update_layout(
title='Raíces inversas del polinomio de rezagos',
polar={'angularaxis': {'thetaunit': 'radians', 'dtick': np.pi / 4},
'radialaxis': {'tickvals': [0.0, 1.0], 'range': [0, rmax]}}
)
opciones = dict(height=300, width=800, showlegend=False, margin=dict(l=40, r=20, t=40, b=20))
3.2. Proceso de media móvil MA(q)#
Proceso media móvil de primer orden: MA(1)#
Sea \(\left\{\epsilon_t\right\}_{t=-\infty}^\infty\) un proceso ruido blanco. Se define el proceso MA(1) como:
Su valor esperado es:
Su varianza es
Su autocovarianza \(j\), para \(j\geq 1\), es
Por lo tanto, su función de autocorrelación es
Notemos que la función de autocorrelación de \(y_t = \mu + \epsilon_t + \theta\epsilon_{t-1}\) es la misma que para el proceso \(z_t = \mu + \epsilon_t + \frac{1}{\theta}\epsilon_{t-1}\)
plt.style.use('seaborn')
rho1 = lambda x: x / (1+x**2)
theta = np.linspace(-3,3, 121)
fig, ax = plt.subplots()
ax.plot(theta, rho1(theta))
ax.plot([0.5,0.5,2.0,2.0], [0,rho1(0.5), rho1(2.0), 0], ':')
ax.plot([-0.5,-0.5,-2.0,-2.0], [0,rho1(-0.5), rho1(-2.0), 0], ':')
ax.set_xticks([-2.0,-0.5,0.0,0.5, 2.0])
ax.set_yticks([-0.5,0,0.5])
ax.set_xlabel(r'$\theta$')
ax.set_ylabel(r'$\rho_1$');

Resumiendo los resultados que hemos obtenido
vemos que ninguno de estos momentos depende del tiempo \(t\), por lo que el proceso MA(1) siempre es covarianza-estacionario.
\(y_t = \epsilon_t + 0.8\epsilon_{t-1}\)
modelo_ma1p = ArmaProcess.from_coeffs(macoefs=[0.8])
fig = make_subplots(rows=1, cols=2, subplot_titles=('Simulación', 'Autocorrelación'))
graficar_simulacion(fig, modelo_ma1p, row=1, col=1)
graficar_autocorrelacion(fig, modelo_ma1p, row=1, col=2)
fig.update_layout(**opciones)
fig.show()
modelo_ma1n = ArmaProcess.from_coeffs(macoefs=[-0.8])
fig = make_subplots(rows=1, cols=2, subplot_titles=('Simulación', 'Autocorrelación'))
graficar_simulacion(fig, modelo_ma1n, row=1, col=1)
graficar_autocorrelacion(fig, modelo_ma1n, row=1, col=2)
fig.update_layout(**opciones)
fig.show()
Invertibilidad de un proceso MA(1)#
Supongamos que \(\mu=0\), con lo que el proceso es
Siempre que \(|\theta|< 1\) podemos invertir el polinomio \((1+\theta \Lag)\):
con lo que
Es decir, podemos representar el proceso MA(1) como un proceso AR(\(\infty\)).
Recordemos que si bien un proceso MA(1) con parámetro \(\theta\) tiene exactamente la misma función de autocorrelación que un proceso con parámetro \(\frac{1}{\theta}\), solo uno de ellos puede ser invertible, porque si \(|\theta|<1\), entonces \(|\frac{1}{\theta}|>1\).
Para ciertos métodos de estimación, sólo será posible estimar el modelo MA(1) si es invertible.
Por ello, para modelos no invertibles se suele cambiar el parámetro por su recíproco.
El proceso MA(q)#
Es fácil extender el proceso MA(1) para incluir más rezagos.
El proceso MA(q) es
con \(\epsilon_t\) ruido blanco.
Su valor esperado es
Su varianza es
mientras que su autocovarianza es
es decir, una característica distintiva de un proceso MA(q) es que todas sus autocorrelaciones para rezagos mayores a \(q\) son cero.
Invertibilidad de un proceso MA(q)#
El proceso MA(q)
será invertible si y solo si las raíces del polinomio \(\Theta(z)\) están todas fuera del círculo unitario.
En ese caso, el proceso se puede representar por
lo cual corresponde a un proceso AR(\(\infty\)).
Función impulso respuesta de un proceso MA(q)#
La función de impulso respuesta está definida por
es decir, nos dice cuánto cambia \(y\) luego de \(j\) períodos ante una perturbación.
Para series estacionarias, podemos escribir
Pero como \(y_t = \mu + \epsilon_t + \theta_1\epsilon_{t-1} + \dots + \theta_q\epsilon_{t-q}\) es fácil ver que
es decir, la función de impulso respuesta es idéntica a los coeficientes del proceso MA(q).
y = ArmaProcess.from_coeffs(macoefs=[0.5, 0.5])
fig = make_subplots(rows=2, cols=2, subplot_titles=('Simulación','Función de Impulso Respuesta', 'Autocorrelación','Autocorrelación Parcial'))
graficar_simulacion(fig, y, row=1, col=1)
graficar_impulso_respuesta(fig, y, row=1, col=2)
graficar_autocorrelacion(fig, y, row=2, col=1)
graficar_autocorrelacion_parcial(fig, y, row=2, col=2)
fig.update_layout(**(opciones | dict(height=500)))
fig.show()
z = ArmaProcess.from_coeffs(macoefs=[-0.6, 0.3, -0.5, 0.5])
fig = make_subplots(rows=2, cols=2, subplot_titles=('Simulación','Función de Impulso Respuesta', 'Autocorrelación','Autocorrelación Parcial'))
graficar_simulacion(fig, z, row=1, col=1)
graficar_impulso_respuesta(fig, z, row=1, col=2)
graficar_autocorrelacion(fig, z, row=2, col=1)
graficar_autocorrelacion_parcial(fig, z, row=2, col=2)
fig.update_layout(**(opciones | dict(height=500)))
fig.show()
fig = go.Figure()
graficar_raices(fig, y.maroots)
fig.update_layout(**(opciones | dict(width=450)))
fig.show()
fig = go.Figure()
graficar_raices(fig, z.maroots)
fig.update_layout(**(opciones | dict(width=450)))
fig.show()
Proceso media móvil de orden infinito: MA(\(\infty\))#
Definimos el proceso MA(\(\infty\)) como
Su media es
Su varianza es
la cual es finita siempre y cuando