Appilcations of state space models

ARMA(p,q) models

Example

MA(1)

zt=εt+βεt1

State space form

[εtεt1]=[0010][εt1εt2]+[εt0]zt=[1β][εtεt1]

Example ARMA(2,1)

zt=α1zt1+α2zt2+εt+βεt1

State space form

[x1,tx2,t]=[α1α210][x1,t1x2,t1]+[εt0]zt=[1β][x1,tx2,t]
zt=β(L)x1,tx1,t=α(L)1wtα(L)zt=β(L)wt

Generalizes to ARMA(p,q)

Unobserved-components models

Example

zt=τt+ctτt=τt1+ηtct=ϕ1ct1+ϕ2ct2+εt

State space form

Δzt=ηt+Δct
[ctct1]=[ϕ1ϕ210][ct1ct2]+[εt0]Δzt=[11][ctct1]+ηt
zt=τt+ctτt=τt1+ηtct=ϕ1ct1+ϕ2ct2+εt

State space form for the level of zt

[τtctct1]=[1000ϕ1ϕ2010][τt1ct1ct2]+[ηtεt]zt=[110][τtctct1]

Unobserved-components models in Statsmodels

Time-varying parameters

zt=xtβt+εtβt=βt1+ηt

Dynamic Factor models

Example

observed variablesz1,t=λ1ft+u1,tz2,t=λ1ft+u2,tcommon factorft=αft1+ηtidiosyncratic componentsu1,t=ϕ1u1,t1+ε1,tu2,t=ϕ2u2,t1+ε2,t

State Space form

[ftu1,tu2,t]=[α000ϕ1000ϕ2][ft1u1,t1u2,t1]+[ηtε1,tε2,t][z1,tz2,t]=[λ110λ201][ftu1,tu2,t]
  • can be extended to multiple factors evolving as VAR(q)

  • and more general AR processes for the idiosyncratic components

DFM are a parsimoneous alternative to VARs with many series

Dynamic factor models in Statsmodels

related common trend model

observed variablesz1,t=ft+u1,tz2,t=ft+u2,tcommon trendft=ft1+ηtstationary termsu1,t=ϕ1u1,t1+ε1,tu2,t=ϕ2u2,t1+ε2,t

State Space form

[ftu1,tu2,t]=[1000ϕ1000ϕ2][ft1u1,t1u2,t1]+[ηtε1,tε2,t][z1,tz2,t]=[λ110λ201][ftu1,tu2,t]
  • z1,t and z2,t share a common stochastic trend - cointegrated

  • the stationary terms can have more complicated dynamics, and may be correlated (e.g VAR instead of AR processes)

The Hodrick-Prescott filter

zt=τt+ctminτt(t=1T(ztτt)2+λt=1T(τt2τt1+τt2)2)

Unobserved components model

zt=τt+ctτt=τt1+βt1+ηtβt=βt1+εt

State space form

[τtβt]=[1101][τt1βt1]+[ηtεt]zt=[10][τtβt]+ct
ctN(0,σc2),εtN(0,σε2),ηtN(0,ση2)
HP-filter restrictions: ση2=0,σc2σε2=λ
  • no parameters are estimated

  • the parameters can be estimated and the restrictions tested

Why You Should Never Use the Hodrick-Prescott Filter

import statsmodels.tsa.api as tsa
from pathlib import Path
import pandas as pd
import matplotlib.pyplot as plt

from fredapi import Fred
fred = Fred(api_key=your_api_key)
start = '1948-01'
end = '2022-01'
df_raw = fred.get_series('GNPC96',  observation_start=start, observation_end=end)
df_raw.index.freq = 'QS'
df_raw.name = 'gdpc1'
df_raw = df_raw.to_frame()
df_raw.head()
gdpc1
1948-01-01 2102.422
1948-04-01 2137.588
1948-07-01 2149.832
1948-10-01 2152.212
1949-01-01 2122.155
hp_cycle, hp_trend = tsa.filters.hpfilter(df_raw[['gdpc1']], lamb=1600)
mod = tsa.UnobservedComponents(df_raw[['gdpc1']], 'lltrend')
res = mod.smooth([1., 0, 1. / 1600]) # 'sigma2.irregular', 'sigma2.level', 'sigma2.trend'
#print(res.summary())
ucm_trend = pd.Series(res.level.smoothed, index=df_raw[['gdpc1']].index)
fig, ax = plt.subplots(figsize=(16, 8))

ax.plot(df_raw[['gdpc1']], label='real GDP', color='blue', linestyle='solid', linewidth=1)
ax.plot(hp_trend, label='HP trend', color='green', marker='o', linestyle='dashed', linewidth=1, markersize=.5)
ax.plot(ucm_trend, label='UC Model trend', color='red', marker='+', linestyle='dashed', linewidth=1, markersize=.5)
ax.legend();
../../_images/03-Application-SS-models_34_0.png

Frequency-domain filters

  • time series can be thought of as the sum of periodic functions (fluctuations)

    • frequency domain, spectral analysis of time series

  • business cycle components of time series correspond a subset of those fluctuations

    • those with period greater than 1.5 (or 2) years and less than 8 years

    • faster (shorter period) or slower (longer period) fluctuations are interpreted as being outside the business cycle

      • low, business cycle, high frequencies

  • frequency-domain filters aim to extract the business cycle components

    • Baxter-King, Christiano-Fitzgerald

periodic functions?

  • cos(x)=cos(x+2kπ),k=1,2,

  • sin(x)=sin(x+2kπ),k=1,2,

  • as function of time: cos(tω),t=t1,t2,

  • periodicity means that

cos(ωt1)=cos(ωth)ωth=ωt1+2πtht1=2πω
  • ω is the frequency, tht1 is the period

  • a time series zt can be represented as a sum (integral) of

a(ω)cos(ωt)+b(ω)sin(ωt),ω(0,π)
  • business cycle component contains only those components with period between 1.5 and 8 years

    • with quarterly data: 2π32ω2π6

    • with monthly data: 2π96ω2π18

  • band-pass filter: keep only a subset (band) of ω’s in (0,π)

  • both Baxter-King and Christiano-Fitzgerald filters are computed as weighted moving averages of the series, the difference is in what the weights are

    • symmetric (BK) vs asymmetric (CF) weights

    • truncated on both ends (BK) vs using the full sample (CF)

bk_cycle = tsa.filters.bkfilter(df_raw[['gdpc1']])
cf_cycle, _ = tsa.filters.cffilter(df_raw[['gdpc1']])
cf_cycle.name = 'CF cycle'
bk_cycle.columns = ['BK cycle']
hp_cycle.name = 'HP cycle'
fig = plt.figure(figsize=(14, 10))
ax = fig.add_subplot(111)
cf_cycle.plot(ax=ax, style=["r--", ], legend=True)
bk_cycle.plot(ax=ax, style=["b-", ], legend=True)
hp_cycle.plot(ax=ax, style=["g-.", ], legend=True)
<AxesSubplot:>
../../_images/03-Application-SS-models_49_1.png

Frequency domain log-likelihood

Whittle log-likelihood

(θ|z)=ωω(θ|z),ω(2πjT,j=1,2,,T)ω(θ|z)=ln(2π)12ln(det(fz(ω,θ)))12tr(fz(ω,θ)1I(ω,z))
  • fz(ω,θ) is the model-implied spectral density of z at ω

  • I(ω,z) is the periodogram of z at ω

  • it is like a Gaussian log-likelihood for independent observations

  • can be derived by approximating the covariance matrix of z by a block circulant matrix, which can be diagonalized using DFT

    zΣ1(θ)ztr(zC1(θ)z)=tr(zVF1(θ)Vz)=ωtr(f(ω,θ)1I(ω,z))

Block circulant matrix

Circ

The Whittle log-likelihood can be used as

  • an alternative to the Kalman filter

  • a way to estimate a model using only a subset of frequencies, e.g. BC frequencies