MinnesotaPrior.coefficient_variance#

MinnesotaPrior.coefficient_variance(context)[source]#

Litterman’s variances, tighter for cross terms and for longer lags.

Three kinds of column, three rules. A variable’s own lag gets \((\lambda_1 / l^{\lambda_3})^2\), the only rule with no scale in it, because a coefficient on a variable’s own past is dimensionless. A cross lag gets the same thing multiplied by \(\lambda_2\) and by \(s_i / s_j\), the ratio that makes a coefficient linking two variables measured in different units shrink by the same amount it would if they were measured in the same ones. Deterministic terms and exogenous regressors get \((\lambda_1 \lambda_4 s_i)^2\), which with the default exogenous is four orders of magnitude looser than an own lag and is meant to be.

The deterministic block is a loop rather than a single row because its width is a property of the family, not a constant: none for a trendless specification, one for a constant, two for a constant and trend, and one per unit for a fixed-effects panel. Writing it as out[0] was silently one column short for every "ct" model and off by N - 1 for every panel – a prior whose columns do not line up with the design shrinks the wrong coefficients and reports a number rather than raising.

Parameters:

context (_PriorContext) – The sample description; k_endog, order, scales, width, lag_offset, n_deterministic, and k_exog are read.

Return type:

NDArray[double]

Returns:

A (width, k) array of variances in design-column order, every entry finite and positive.

Raises:

SpecificationError – If a hyperparameter is out of range.

Example

Two variables, one lag, residual scales one and four; the cross-lag variance in the first equation is scaled down by \((1/4)^2\) and in the second scaled up by \(4^2\):

>>> import numpy as np
>>> from cultivars.bayes.priors import PriorContext
>>> ctx = PriorContext(
...     k_endog=2, order=1, scales=np.array([1.0, 4.0]),
...     presample_mean=np.zeros(2),
... )
>>> prior = MinnesotaPrior(tightness=0.2, cross_equation=0.5)
>>> prior.coefficient_variance(ctx).round(4)
array([[4.0e+02, 6.4e+03],
       [4.0e-02, 1.6e-01],
       [6.0e-04, 4.0e-02]])