FAVAR#

class cultivars.multivariate.large_dim.factor_augmented.FAVAR(panel, observed, *, n_factors, order, slow=None, trend='c', observed_names=None, panel_names=None)[source]#

Factor-augmented VAR over a wide informational panel, BBE (2005).

Extract, clean, augment, fit. Principal components of the standardized panel estimate the factors; when slow series are declared, the observed block’s contemporaneous influence is regressed out of them against the slow-panel components,

\[\hat F_t = C_t - \hat b_Y' Y_t, \qquad C_t = \hat b_S' C^{\text{slow}}_t + \hat b_Y' Y_t + \text{error},\]

with \(C_t\) the full-panel components and \(C^{\text{slow}}_t\) the components of the slow series alone, which is what makes a recursive policy identification on the result defensible; the cleaned factors and the observed block then form a small VAR estimated by composition; and the observation equation is fitted by least squares, one panel series at a time.

Variables:
  • _panel – The validated (nobs, n_series) panel as a float array.

  • _observed – The validated (nobs, m) observed block.

  • _n_factors – The number of principal-component factors.

  • _order – The autoregressive order of the augmented VAR.

  • _slow – Column positions of the slow series, or None.

  • _trend (Literal['n', 'c', 'ct']) – The deterministic terms of the augmented VAR.

  • _observed_names – One label per observed variable.

  • _panel_names – One label per panel series.

Parameters:
  • panel (ArrayLike) – The (nobs, n_series) informational panel. Standardized internally; responses are reported back in original units.

  • observed (ArrayLike) – The (nobs, m) observed block – the variables whose shocks are of interest, a policy rate being the canonical case. A one-dimensional array is read as one variable.

  • n_factors (int) – Number of principal-component factors to extract, at least 1 and at most min(nobs - 1, n_series).

  • order (int) – Autoregressive order of the augmented VAR, at least 0.

  • slow (Sequence[str] | None) – Names of the panel series that do not respond to the observed block within the period, for the Bernanke-Boivin-Eliasz cleaning; at least n_factors + 1 of them. None skips the cleaning, and the summary says so.

  • trend (Literal['n', 'c', 'ct']) – Deterministic terms of the augmented VAR, "n", "c" or "ct".

  • observed_names (Sequence[str] | None) – Labels for the observed block. Defaults to y1 ... ym.

  • panel_names (Sequence[str] | None) – Labels for the panel series. Defaults to x1 ... xN.

Raises:
  • SpecificationError – If n_factors is not a positive integer or exceeds what the panel supports, a label set has the wrong length or repeats, a slow name is unknown, too few slow series are declared, or order or trend is rejected by the augmented VAR at fit.

  • DimensionError – If the panel is not a time-down-the-rows matrix or the observed block does not have one row per panel period.

See also

References

Bernanke, B. S., Boivin, J., & Eliasz, P. (2005). Measuring the effects of monetary policy: A factor-augmented vector autoregressive (FAVAR) approach. Quarterly Journal of Economics, 120(1), 387-422.

Example

A panel whose fast half responds to the policy shock within the period. Without cleaning the factor absorbs the shock; declaring the slow half removes it:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> n = 400
>>> factor = np.zeros(n)
>>> for t in range(1, n):
...     factor[t] = 0.7 * factor[t - 1] + rng.standard_normal()
>>> shock = rng.standard_normal(n)
>>> policy = 0.5 * factor + shock
>>> lam = rng.uniform(0.5, 1.5, 30)
>>> slow_half = np.outer(factor, lam[:15]) + 0.5 * rng.standard_normal((n, 15))
>>> fast_half = np.outer(factor, lam[15:]) + 0.5 * rng.standard_normal((n, 15))
>>> fast_half += 0.8 * np.outer(shock, rng.uniform(0.5, 1.5, 15))
>>> panel = np.column_stack([slow_half, fast_half])
>>> names = tuple(f"s{i}" for i in range(15)) + tuple(f"q{i}" for i in range(15))
>>> raw = FAVAR(panel, policy, n_factors=1, order=1, panel_names=names).fit()
>>> clean = FAVAR(
...     panel, policy, n_factors=1, order=1, panel_names=names, slow=names[:15]
... ).fit()
>>> raw.cleaned, clean.cleaned, clean.factors.k_endog
(False, True, 2)
>>> leak = lambda res: abs(np.corrcoef(res.scores[:, 0], shock)[0, 1])
>>> bool(leak(raw) > 0.3), bool(leak(clean) < 0.1)
(True, True)
>>> FAVAR(panel, policy, n_factors=1, order=1, slow=("x1",))
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: the cleaning needs more slow series than ...

Methods#

fit()

Extract the factors, clean them, and estimate the augmented VAR.