Invertibility addresses whether a moving average (MA) or autoregressive moving average (ARMA) process can be reexpressed as an infinite-order autoregressive (AR) process.
This property ensures a unique mapping between the process and its autocorrelation function, critical for parameter estimation from observed data.
Concept of Invertibility
For an MA() process:
invertibility allows rewriting it as:
with coefficients . This is possible when the MA characteristic polynomial:
has roots exceeding 1 in modulus ( for MA(1)).
Invertibility resolves nonuniqueness in MA models, where different values yield the same autocorrelation function.
MA(1) Example
Consider . Rewrite as:
Substitute recursively:
Continuing infinitely:
Thus:
Notice that converges if and only if .
And if converges, then is invertible.
For , the series diverges, rendering it non-invertible.
Nonuniqueness Issue
For MA(1), . Replacing with yields the same .
Example:
and both give , but only (root ) is invertible (), while (root ) is not ().
General MA() and ARMA(,)
Invertibility requires all roots of the MA characteristic equation to have modulus greater than 1.
For ARMA(,), both stationarity (AR roots > 1 in modulus) and invertibility (MA roots > 1 in modulus) are required for a well-defined model.
Implications
Invertibility ensures a unique, physically sensible MA representation, restricting attention to models where past observations can predict the noise term without infinite amplification.
Python Example
import numpy as np
import matplotlib.pyplot as plt
# Simulate MA(1) processes with invertible and non-invertible theta
np.random.seed(42)
n = 100
e_t = np.random.normal(0, 1, n + 1) # White noise
theta_inv = 0.5 # Invertible: |theta| < 1
theta_non = 2.0 # Non-invertible: |theta| > 1
# Generate MA(1) series
Y_inv = np.zeros(n)
Y_non = np.zeros(n)
for t in range(n):
Y_inv[t] = e_t[t + 1] - theta_inv * e_t[t]
Y_non[t] = e_t[t + 1] - theta_non * e_t[t]
# Attempt to recover e_t (invert the process)
e_rec_inv = np.zeros(n)
e_rec_non = np.zeros(n)
for t in range(1, n):
e_rec_inv[t] = Y_inv[t] + theta_inv * e_rec_inv[t - 1]
e_rec_non[t] = Y_non[t] + theta_non * e_rec_non[t - 1]
# Plot original vs recovered noise
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
plt.plot(e_t[1:], label='True $e_t$', alpha=0.5)
plt.plot(e_rec_inv, label='Recovered $e_t$ (Invertible, $\\theta=0.5$)', linestyle='--')
plt.title('Invertible MA(1)')
plt.legend()
plt.subplot(2, 1, 2)
plt.plot(e_t[1:], label='True $e_t$', alpha=0.5)
plt.plot(e_rec_non, label='Recovered $e_t$ (Non-invertible, $\\theta=2.0$)', linestyle='--')
plt.title('Non-invertible MA(1)')
plt.legend()
plt.tight_layout()
plt.show()
# Check autocorrelation
from statsmodels.tsa.stattools import acf
acf_inv = acf(Y_inv, nlags=5, fft=False)
acf_non = acf(Y_non, nlags=5, fft=False)
print(f"ACF (Invertible, theta={theta_inv}): {acf_inv[:3]}")
print(f"ACF (Non-invertible, theta={theta_non}): {acf_non[:3]}")
Explanation
This code simulates two MA(1) processes: one with (invertible) and one with (non-invertible). It attempts to recover the white noise using the infinite AR representation. For , the recovered closely matches the true noise, while for , it diverges due to non-invertibility. The autocorrelation functions (ACF) are computed, showing both processes have the same , illustrating nonuniqueness without invertibility constraints.
Output plots demonstrate the stability of the invertible case versus the explosive behavior of the non-invertible case.