DummyInitialObservationPrior#

class cultivars.bayes.priors.DummyInitialObservationPrior(*, tightness=1.0)[source]

Bases: _Prior

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

One artificial observation in which every variable sits at its pre-sample mean and every deterministic term at one. With pre-sample means \(\bar y\) and tightness \(\delta\), the row is

\[\underbrace{\delta\, \bar y^\top}_{\text{target}} \;=\; \underbrace{\bigl[\,\delta\, 1_{n_{\text{det}}},\; \delta\, \bar y^\top,\; \ldots,\; \delta\, \bar y^\top,\; 0_{k_{\text{exog}}}\bigr]}_{\text{design row}}\; B + \text{error},\]

which says that a system starting at its pre-sample mean, with the deterministic terms switched on, should predict that same mean: either the lag coefficients sum to the identity and the constant is zero, or the constant absorbs whatever the lags leave. Where the sum-of-coefficients rows allow each variable its own unit root, this single row says that if the system is that persistent, it is persistent jointly – a common stochastic trend rather than one per series – and it is what keeps the sum-of-coefficients restriction from ruling out cointegration entirely (Sims 1993; Sims & Zha 1998). The pair is standard equipment in the Giannone, Lenza, and Primiceri (2015) hierarchy, each with its own tightness.

Alone it is improper – every coefficient variance is infinite – so it is a component, not a prior; the conjugate model accepts it only stacked onto a proper base, NormalInverseWishartPrior() + SumOfCoefficientsPrior() + DummyInitialObservationPrior().

Variables:

tightness – How hard the restriction binds; larger is tighter. The Giannone-Lenza-Primiceri \(\delta\) is its reciprocal.

Raises:

SpecificationError – If tightness is not positive, raised when dummy_observations() is first called, which is the model’s fit.

Note

Unlike the sum-of-coefficients rows, this row has non-zero deterministic columns, so it is the one component that ties the intercept (and trend, and panel fixed effects) to the pre-sample level. It is also the one that binds when the pre-sample means are near zero: with \(\bar y \approx 0\) the row reduces to \(0 = \delta\, c + \text{error}\), a statement that the intercept is small.

See also

References

Sims, C. A. (1993). A nine-variable probabilistic macroeconomic forecasting model. In J. H. Stock & M. W. Watson (Eds.), Business Cycles, Indicators, and Forecasting (pp. 179-212). University of Chicago Press.

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.

Example

Two variables at two lags, pre-sample means ten and twenty, at half weight; one row, with the intercept column at the tightness and the means repeated at each lag:

>>> import numpy as np
>>> from cultivars.bayes.priors import PriorContext
>>> ctx = PriorContext(
...     k_endog=2, order=2, scales=np.ones(2),
...     presample_mean=np.array([10.0, 20.0]),
... )
>>> target, design = DummyInitialObservationPrior(tightness=0.5).dummy_observations(ctx)
>>> target
array([[ 5., 10.]])
>>> design
array([[ 0.5,  5. , 10. ,  5. , 10. ]])

The full Giannone-Lenza-Primiceri stack on the conjugate model, with the rows counted on the result:

>>> 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)
>>> base = NormalInverseWishartPrior() + SumOfCoefficientsPrior()
>>> prior = base + DummyInitialObservationPrior()
>>> res = BVAR(y, order=1, prior=prior).fit(n_draws=100, seed=0)
>>> res.prior_label, res.n_dummy
('niw(l1=0.2, l3=1, l4=100) + soc(1) + dio(1)', 3)

Private methods#

_check()

Reject a non-positive tightness.

_label()

Short description for summary tables and comparison rows.