IndependentNormalWishartPrior#

class cultivars.bayes.priors.IndependentNormalWishartPrior(*, tightness=0.2, cross_equation=0.5, decay=1.0, exogenous=100.0, sum_of_coefficients=None, persistence=1.0)[source]

Bases: _Prior

Litterman’s full prior under an independent inverse-Wishart pairing.

The variances are exactly MinnesotaPrior’s, cross-equation weight included, and that is the point. The conjugate Normal-inverse-Wishart pairing had to pin that weight to one because it ties the coefficient variance to \(\Sigma\) through a Kronecker product; stating the prior on the coefficients independently of \(\Sigma\),

\[\operatorname{vec}(B) \sim \mathcal{N}\bigl(\operatorname{vec}(B_0),\, V_0\bigr), \qquad \Sigma \sim \mathcal{IW}(S_0, \nu_0), \qquad V_0 \text{ diagonal, } B \perp \Sigma,\]

drops the factorization requirement, so \(V_0\) can carry Litterman’s \(\lambda_2\) and the sum-of-coefficients rows alike. The price is the closed form. With \(B\) and \(\Sigma\) independent a priori, the joint posterior is not a named distribution; it is reached by a two-block Gibbs sampler, coefficients given the covariance by generalized least squares,

\[\operatorname{vec}(B) \mid \Sigma, y \sim \mathcal{N}\bigl(\bar\beta,\, \bar V\bigr), \quad \bar V = \bigl(V_0^{-1} + \Sigma^{-1} \otimes X^\top X\bigr)^{-1},\]

and the covariance given the coefficients by an inverse-Wishart on the residuals, and the marginal likelihood is not available in closed form but is estimated from the Gibbs output by Chib’s (1995) method. That trade – Litterman’s economics back, the evidence simulated rather than exact – is the standard one (Koop & Korobilis 2010), and this class is its name. It is the default prior of GibbsBVAR, and the conjugate BVAR refuses it at fit.

Variables:
  • tightness – Overall confidence, \(\lambda_1\).

  • cross_equation – How much harder cross-variable coefficients shrink, \(\lambda_2\), the hyperparameter this pairing exists to keep.

  • decay – Lag decay, \(\lambda_3\).

  • exogenous – Looseness of the intercept and exogenous block, \(\lambda_4\).

  • sum_of_coefficients – The no-cointegration restriction, \(\lambda_5\); None omits it.

  • persistence – Prior mean of each variable’s own first lag.

Raises:
  • SpecificationError – When a hyperparameter is used, not at construction: if tightness, cross_equation, or exogenous is not positive, if decay is negative, or if sum_of_coefficients is given and not positive, at the first moment or dummy call, which is the model’s fit.

  • DimensionError – If persistence is a sequence whose length is not the number of variables, at the same point.

Note

The moments and rows are those of a MinnesotaPrior with the same fields; the two classes differ only in the pairing with \(\Sigma\) that the estimator infers from the type, and in the label. A MinnesotaPrior handed to the Gibbs model is treated identically; this class exists so the pairing is stated in the prior’s name rather than implied by the model it was passed to.

See also

References

Kadiyala, K. R., & Karlsson, S. (1997). Numerical methods for estimation and inference in Bayesian VAR-models. Journal of Applied Econometrics, 12(2), 99-132.

Chib, S. (1995). Marginal likelihood from the Gibbs output. Journal of the American Statistical Association, 90(432), 1313-1321.

Koop, G., & Korobilis, D. (2010). Bayesian multivariate time series methods for empirical macroeconomics. Foundations and Trends in Econometrics, 3(4), 267-358.

Example

The Gibbs BVAR under this prior keeps the cross-equation weight and reports a Chib marginal likelihood:

>>> import numpy as np
>>> from cultivars.multivariate.large_dim.gibbs import GibbsBVAR
>>> rng = np.random.default_rng(0)
>>> y = np.zeros((120, 2))
>>> for t in range(1, 120):
...     y[t] = 0.7 * y[t - 1] + rng.standard_normal(2)
>>> prior = IndependentNormalWishartPrior(tightness=0.1, cross_equation=0.5)
>>> res = GibbsBVAR(y, order=1, prior=prior).fit(n_draws=300, n_burn=100, seed=0)
>>> res.prior_label, res.beta_draws.shape
('inw(l1=0.1, l2=0.5, l3=1, l4=100)', (200, 3, 2))
>>> res.marginal_likelihood().method
'chib'

The conjugate model refuses it, since its variance does not factor:

>>> from cultivars.multivariate.large_dim.bayesian import BVAR
>>> BVAR(y, order=1, prior=prior).fit(n_draws=10, seed=0)
Traceback (most recent call last):
    ...
cultivars.exceptions.SpecificationError: the prior variance does not factor ...

Private methods#

_label()

Short description for summary tables and comparison rows.

_minnesota()

The MinnesotaPrior whose moments and rows this prior states.