FactorSVResult#

class cultivars.multivariate.large_dim.factor_volatility.FactorSVResult(*, panel, series_names, loading_draws, factor_draws, h_factor_draws, h_idio_draws, mu_factor_draws, phi_factor_draws, sigma2_factor_draws, mu_idio_draws, phi_idio_draws, sigma2_idio_draws, means, n_draws, n_burn, thin)[source]

Bases: _SummaryMixin, _ConvergenceMixin

The posterior of a factor stochastic-volatility model.

The model is

\[y_t = \Lambda f_t + \varepsilon_t, \qquad f_t \sim N\bigl(0, H_t\bigr), \quad \varepsilon_t \sim N\bigl(0, D_t\bigr),\]

with \(H_t = \operatorname{diag}(e^{h_{1t}}, \ldots, e^{h_{rt}})\) and \(D_t = \operatorname{diag}(e^{\eta_{1t}}, \ldots, e^{\eta_{kt}})\), every log variance a latent AR(1),

\[h_{j,t+1} = \mu_j + \phi_j (h_{jt} - \mu_j) + \sigma_j \xi_{jt},\]

so the conditional covariance \(\Sigma_t = \Lambda H_t \Lambda' + D_t\) moves through \(k + r\) volatility paths and one loading matrix. Identification is the triangular convention: \(\Lambda\) is lower triangular with a unit diagonal in its leading \(r\) rows, so factor \(j\) is scaled and signed by series \(j\). The sampler is an exact Gibbs scheme – factors one Gaussian per period, loadings one weighted regression per row, every log-variance path and its three parameters by the Kim-Shephard-Chib mixture blocks – and what comes back is the posterior: the record stores the retained draws of every unknown, and the point summaries (loadings, factors, the conditional covariance and correlation, the communalities) are posterior means computed from them on demand.

Note

Every *_draws field shares the kept-draw axis S, which is what convergence from _ConvergenceMixin assesses. The fixed loadings (the unit diagonal and the zeros above it) never move and are reported as such rather than flagged. The chain is a plain Gibbs sampler without the Kastner, Fruehwirth-Schnatter and Lopes (2017) interweaving, so loadings and factor scales mix slowly and the volatility paths have low effective sample sizes at short runs; thin and lengthen accordingly, and read convergence before the point summaries. The series means are removed before sampling and kept in means; panel is the raw input.

Variables:
  • panel – The observed (nobs, k) panel.

  • series_names – One label per series.

  • loading_draws – (S, k, r) posterior draws of the loading matrix.

  • factor_draws – (S, T, r) posterior draws of the factor paths.

  • h_factor_draws – (S, T, r) posterior draws of the factor log variances.

  • h_idio_draws – (S, T, k) posterior draws of the idiosyncratic log variances.

  • mu_factor_draws – (S, r) factor log-variance means.

  • phi_factor_draws – (S, r) factor log-variance persistences.

  • sigma2_factor_draws – (S, r) factor log-variance innovation variances.

  • mu_idio_draws – (S, k) idiosyncratic log-variance means.

  • phi_idio_draws – (S, k) idiosyncratic persistences.

  • sigma2_idio_draws – (S, k) idiosyncratic innovation variances.

  • means – (k,) series means removed before sampling.

  • n_draws – Total sampler iterations.

  • n_burn – Burn-in discarded.

  • thin – Post-burn thinning.

See also

  • FactorSV – the model that produces this record.

  • SV – the univariate model each volatility path follows.

  • DFM – the constant-variance factor model.

References

Pitt, M. K., & Shephard, N. (1999). Time-varying covariances: A factor stochastic volatility approach. In Bayesian Statistics 6 (pp. 547-570). Oxford University Press.

Chib, S., Nardari, F., & Shephard, N. (2006). Analysis of high dimensional multivariate stochastic volatility models. Journal of Econometrics, 134(2), 341-371.

Kastner, G., Fruehwirth-Schnatter, S., & Lopes, H. F. (2017). Efficient Bayesian inference for multivariate factor stochastic volatility models. Journal of Computational and Graphical Statistics, 26(4), 905-917.

Example

One factor with a persistent log variance, loaded onto five series with decreasing weights; the posterior recovers the loadings, the factor path and its volatility:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> n, k = 300, 5
>>> h = np.zeros(n)
>>> for t in range(1, n):
...     h[t] = 0.95 * h[t - 1] + 0.3 * rng.standard_normal()
>>> f = np.exp(h / 2) * rng.standard_normal(n)
>>> lam = np.array([1.0, 0.8, 0.6, 0.4, 0.2])
>>> y = np.outer(f, lam) + 0.5 * rng.standard_normal((n, k))
>>> res = FactorSV(y, n_factors=1).fit(n_draws=300, n_burn=100, seed=0)
>>> res.n_series, res.n_factors, res.nobs, res.n_kept
(5, 1, 300, 200)
>>> np.round(res.loadings[:, 0], 1)
array([1. , 0.8, 0.6, 0.4, 0.2])
>>> bool(np.corrcoef(res.factors[:, 0], f)[0, 1] > 0.9)
True
>>> bool(np.corrcoef(res.h_factor_draws.mean(axis=0)[:, 0], h)[0, 1] > 0.7)
True

Private methods#

_column(series)

Resolve a series label or index to a column.

_from_fit(fit, model)

Assemble the public result from a raw fit and its specification.

_summary_table()

Build the structured summary.