cultivars.bayes.priors#

Priors for the Bayesian vector autoregressions: moments, dummies, and hierarchies.

A prior here is a frozen record that answers three questions about a VAR whose coefficients \(B\) are (width, k) in design-column order: what the coefficients are centred on, coefficient_mean(); how far the data may pull each one away, coefficient_variance(); and which pseudo-observations, if any, are stacked under the sample, dummy_observations(). Every model that takes prior= reads the prior through those three hooks and a _PriorContext describing the sample, so a prior knows nothing about the estimator and an estimator knows nothing about the prior beyond its moments and its rows. The Minnesota family lives in that interface directly. Litterman’s prior sets the mean at independent random walks and the variance at

\[\begin{split}\operatorname{Var}(A_{l,ij}) = \Bigl(\frac{\lambda_1}{l^{\lambda_3}}\Bigr)^{2} \times \begin{cases} 1 & i = j \\ \lambda_2^2\, s_i^2 / s_j^2 & i \ne j, \end{cases}\end{split}\]

and the sum-of-coefficients and dummy-initial-observation priors add rows rather than moments, each a Theil-Goldberger pseudo-sample that says the system is near a unit root or near its pre-sample mean. Priors compose with +: means and variances combine by precision weighting, dummy blocks stack, and NoPrior is the identity, so NormalInverseWishartPrior() + SumOfCoefficientsPrior() + DummyInitialObservationPrior() is the prior of Sims and Zha (1998) and Giannone, Lenza and Primiceri (2015) stated as a sum.

The adaptive priors do not have a variance to state. Under the horseshoe, spike-and-slab, Dirichlet-Laplace, and Normal-Gamma hierarchies each coefficient’s variance is a product of latent scales with their own full conditionals, so those classes keep the moments interface, reporting the variance at their initial scales, and add three hooks the Gibbs sampler drives: initialize the scales, redraw them given the current standardized coefficients, and read the variance they imply. Shrinkage acts on the coefficient divided by the Minnesota unit ratio \(s_i / s_j\), so one latent scale means the same thing whatever the variables’ units, and only the endogenous lag block is shrunk, with the deterministic and exogenous columns held at a fixed loose variance, exactly where the Minnesota prior leaves them.

Two commitments shape the surface. First, the pairing with the residual covariance is stated in the prior’s name and nowhere else. NormalInverseWishartPrior is the conjugate pairing, with the cross-equation weight pinned to one because the Kronecker structure demands it and an exact posterior and marginal likelihood in return; IndependentNormalWishartPrior keeps the weight and pays with a Gibbs sampler and a simulated Chib evidence; MinnesotaPrior is the same moments for the per-equation point path. The conjugate model refuses a prior whose variance does not factor rather than quietly pinning the weight itself. Second, hyperparameters are checked when they are used, not at construction: a prior is a plain frozen dataclass, and the SpecificationError for a negative tightness surfaces at the model’s fit, where the context that makes the check meaningful exists.

Layout. The nine classes defined here are the public priors: MinnesotaPrior, NormalInverseWishartPrior, SumOfCoefficientsPrior, DummyInitialObservationPrior, and IndependentNormalWishartPrior state moments and rows; HorseshoePrior, SpikeAndSlabPrior, DirichletLaplacePrior, and NormalGammaPrior are the adaptive hierarchies. Three more are re-exported from _internals under public names: NoPrior, the identity of composition, and the two volatility-law priors VolatilityPrior and RandomWalkVolatilityPrior, which the stochastic-volatility models read and which do not enter coefficient composition at all. The abstract base _Prior, the adaptive base _AdaptivePrior, the composite built by +, and the _PriorContext record live in _internals; the generalized-inverse-Gaussian sampler the Dirichlet-Laplace and Normal-Gamma conditionals need lives in _core. The consumers are BVAR and StudentBVAR for the conjugate path, GibbsBVAR for the independent and adaptive paths, and VAR for the point-estimate path.

References

Litterman, R. B. (1986). Forecasting with Bayesian vector autoregressions: Five years of experience. Journal of Business & Economic Statistics, 4(1), 25-38.

Doan, T., Litterman, R., & Sims, C. (1984). Forecasting and conditional projection using realistic prior distributions. Econometric Reviews, 3(1), 1-100.

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

Sims, C. A., & Zha, T. (1998). Bayesian methods for dynamic multivariate models. International Economic Review, 39(4), 949-968.

Giannone, D., Lenza, M., & Primiceri, G. E. (2015). Prior selection for vector autoregressions. Review of Economics and Statistics, 97(2), 436-451.

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

Polson, N. G., & Scott, J. G. (2010). Shrink globally, act locally: Sparse Bayesian regularization and prediction. In Bayesian Statistics 9 (pp. 501-538). Oxford University Press.

Example

Compose the Sims-Zha prior and fit the conjugate model; the label records the sum, and the three dummy rows are folded into the posterior exactly:

>>> import numpy as np
>>> from cultivars.multivariate.large_dim.bayesian import BVAR
>>> 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 = (
...     NormalInverseWishartPrior(tightness=0.1)
...     + SumOfCoefficientsPrior(tightness=1.0)
...     + DummyInitialObservationPrior(tightness=1.0)
... )
>>> res = BVAR(y, order=1, prior=prior).fit(n_draws=200, seed=0)
>>> res.prior_label
'niw(l1=0.1, l3=1, l4=100) + soc(1) + dio(1)'
>>> res.n_dummy, res.marginal_likelihood().method
(3, 'analytic')

An adaptive prior goes to the Gibbs model alone, and reports the shrinkage it learned:

>>> from cultivars.multivariate.large_dim.gibbs import GibbsBVAR
>>> res = GibbsBVAR(y, order=1, prior=HorseshoePrior()).fit(
...     n_draws=600, n_burn=200, seed=0
... )
>>> res.prior_label, res.shrinkage_scales().shape
('horseshoe', (1, 2, 2))

Classes#

DirichletLaplacePrior

Dirichlet-Laplace shrinkage: a simplex rations the prior's attention.

DummyInitialObservationPrior

Sims' co-persistence dummy, the single-unit-root prior.

HorseshoePrior

The horseshoe: aggressive shrinkage that lets large signals through.

IndependentNormalWishartPrior

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

MinnesotaPrior

Litterman's prior: shrink toward independent random walks.

NoPrior

NormalGammaPrior

Normal-Gamma shrinkage: the Bayesian lasso's adjustable-kurtosis parent.

NormalInverseWishartPrior

The conjugate Normal-inverse-Wishart prior: Litterman's variances, one weight pinned.

Prior

PriorContext

RandomWalkVolatilityPrior

SpikeAndSlabPrior

Stochastic search variable selection: exclusion as a latent state.

SumOfCoefficientsPrior

The no-cointegration dummies of Doan, Litterman & Sims.

VolatilityPrior