StudentBVARResult#

class cultivars.multivariate.large_dim.student.StudentBVARResult(*, endog, names, order, trend, prior_label, coefficients, deterministic, beta_mean, sigma_u, beta_draws, sigma_draws, df, df_draws, weight_mean, resid, fittedvalues, nobs, n_dummy, n_draws, n_burn, thin)[source]#

A fitted Student-t Bayesian VAR: the tails carry a posterior too.

The posterior of

\[y_t = c + \sum_{i=1}^{p} A_i y_{t-i} + u_t, \qquad u_t \sim t_\nu(0, \Sigma),\]

reached through the scale-mixture representation \(u_t \mid w_t \sim N(0, \Sigma / w_t)\), \(w_t \sim \mathrm{Gamma}(\nu/2, \nu/2)\): conditional on the weights the model is the conjugate Normal-inverse-Wishart VAR on rows rescaled by \(\sqrt{w_t}\), so the Gibbs sampler alternates exact conditionals for \((B, \Sigma)\), for the weights, and – when \(\nu\) is not stated – for \(\nu\) on a fixed grid. The propagation surface is the family’s shared one from _VectorPosteriorDrawsResult; what this result adds is the tail index’s posterior, the per-date weights, and three noise hooks that make every propagated object – predictive, simulation, replication – draw its innovations from the t rather than the Gaussian.

Note

sigma_u and sigma_draws are the t distribution’s scale matrix \(\Sigma\), not its covariance; the innovation covariance is \(\Sigma\,\nu / (\nu - 2)\) and is reported as innovation_covariance. The scale is what the structural factorization and the predictive consume, which is why it keeps the family’s name. df is the posterior mean of the kept \(\nu\) draws when estimated and the stated value when fixed; the grid runs over the integers 2 .. 29 and then 30, 35, 40, 50, 60, 80, 100, so an estimated df is a mean of grid points and df_interval reports grid quantiles. weight_mean is the posterior mean of \(w_t\), aligned with resid: a typical date sits near one, and a date the t absorbed as a tail event sits well below it. No marginal likelihood is reported; the module docstring states why.

Variables:
  • prior_label – Short description of the prior estimated under.

  • df – Posterior mean degrees of freedom – the stated value when the caller fixed it.

  • df_draws – (S,) kept degrees-of-freedom draws; empty when fixed.

  • weight_mean – (n,) posterior mean latent precision weights, aligned with resid. Small values mark the dates the t distribution treats as tail events.

  • n_dummy – Artificial rows the prior contributed.

  • n_draws – Total sampler iterations.

  • n_burn – Burn-in discarded.

  • thin – Post-burn thinning.

See also

  • StudentBVAR – the model that produces this record.

  • BVARResult – the Gaussian conjugate posterior this one relaxes.

  • BVARSVResult – the other route to fat marginal tails, through time-varying volatility.

References

Chiu, C.-W. J., Mumtaz, H., & Pinter, G. (2017). Forecasting with VAR models: Fat tails and stochastic volatility. International Journal of Forecasting, 33(4), 1124-1143.

Geweke, J. (1993). Bayesian treatment of the independent Student-t linear model. Journal of Applied Econometrics, 8(S1), S19-S40.

Example

A bivariate VAR(1) whose innovations are \(t_4\), generated through the same scale mixture the sampler uses. The tail index is recovered in the single digits, the dates with the largest residuals carry the smallest weights, and the scale sits below the covariance by the factor \(\nu / (\nu - 2)\):

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> y = np.zeros((200, 2))
>>> for t in range(1, 200):
...     w = rng.gamma(2.0, 0.5)
...     y[t] = 0.5 * y[t - 1] + rng.standard_normal(2) / np.sqrt(w)
>>> res = StudentBVAR(y, order=1).fit(n_draws=400, n_burn=200, seed=0)
>>> res.prior_label, res.n_kept, res.nobs, res.n_dummy
('niw(l1=0.2, l3=1, l4=100)', 100, 199, 0)
>>> res.df_estimated, bool(3.0 < res.df < 10.0), res.df_draws.shape
(True, True, (100,))
>>> res.beta_draws.shape, res.sigma_draws.shape, res.weight_mean.shape
((100, 3, 2), (100, 2, 2), (199,))
>>> largest = np.argsort(np.abs(res.resid).max(axis=1))[-5:]
>>> bool(res.weight_mean[largest].max() < 0.5), bool(0.9 < res.weight_mean.mean() < 1.1)
(True, True)
>>> ratio = np.diag(res.innovation_covariance) / np.diag(res.sigma_u)
>>> bool(np.allclose(ratio, res.df / (res.df - 2.0)))
True
>>> low, mid, high = res.credible_interval("y1", "y1.L1")
>>> bool(0.4 < low < mid < high < 0.65)
True

Attributes#

endog

The observed panel, shape (nobs_total, k).

names

Variable labels, in column order.

order

The autoregressive order p.

trend

"n", "c" or "ct".

prior_label

Short description of the prior estimated under.

coefficients

(p, k, k) lag stack at the posterior mean.

deterministic

(n_det, k) deterministic block at the posterior mean.

beta_mean

(w, k) full posterior mean coefficient matrix.

sigma_u

(k, k) posterior mean t scale matrix, not the covariance.

beta_draws

(S, w, k) coefficient draws.

sigma_draws

(S, k, k) scale-matrix draws.

df

posterior mean of the kept draws, or the stated value.

df_draws

(S,) kept degrees-of-freedom draws; shape (0,) when fixed.

weight_mean

(nobs,) posterior mean latent precision weights, aligned with resid.

resid

(nobs, k) residuals at the posterior mean.

fittedvalues

(nobs, k) one-step means at the posterior mean.

nobs

Effective sample size after the p presample rows.

n_dummy

Artificial rows a dummy-observation prior contributed.

n_draws

Total sampler iterations, burn-in included.

n_burn

Iterations discarded from the start.

thin

Every thin-th post-burn iteration is kept.

df_estimated

Whether the degrees of freedom carry a posterior.

innovation_covariance

The innovation covariance scale * df / (df - 2).

k_endog

Number of endogenous variables.

n_kept

Posterior draws retained.

observed

The effective sample the replications are shaped like, (nobs, k).

stable_share

Posterior probability that the system is stable.

Methods#

convergence(*chains[, include, exclude, ...])

Assess the sampler's convergence over the retained draws.

credible_interval(equation, regressor)

One coefficient's posterior summary: 16th percentile, mean, 84th.

df_interval()

The tail index's posterior summary: 16th percentile, mean, 84th.

forecast([steps, seed])

The posterior predictive: parameter and shock uncertainty.

forecast_paths([steps, seed])

The posterior predictive's raw simulated paths, one per kept draw.

irf([horizon, orthogonalized, cumulative, ...])

Posterior mean impulse responses.

irf_bands([horizon, orthogonalized, ...])

Posterior bands of the impulse responses.

outlier_dates([threshold])

Effective-sample rows the t distribution treats as tail events.

posterior_replications([n_replications, seed])

Replicated effective samples, one per posterior draw used.

simulate([n, seed, burn, draw])

A fresh sample path from the fitted system at the posterior mean or at one draw.

summary()

The estimation summary, renderable as text, HTML, or a dataframe.