PanelVARResult#

class cultivars.multivariate.reduced_form.panel.PanelVARResult(*, endog, names, order, trend, sigma_u, sigma_ml, resid, fittedvalues, design, llf, nobs, n_params, posterior=None, prior_label='none', coefficients, deterministic, unit_names, unit_lengths, effects)[source]#

A fitted panel vector autoregression with pooled slopes.

Every unit \(i\) shares the autoregressive matrices and the innovation covariance and differs only in its intercept,

\[y_{it} = \mu_i + \sum_{l=1}^{p} A_l\, y_{i,t-l} + u_{it}, \qquad u_{it} \sim (0, \Sigma_u), \qquad i = 1, \dots, N,\]

estimated by least squares on the stacked panel with one dummy per unit (effects="unit") or with a single pooled deterministic block (effects="none"). Lags are built inside each unit, so the effective sample is \(\sum_i (T_i - p)\) and no regressor crosses a unit boundary.

The residual matrix is a stack of units rather than one series, and every inherited method that reads residual history reads it through _sample_blocks, so no lagged cross-product and no shock propagation ever crosses a unit boundary. irf, fevd, and stability_check depend only on the pooled matrices and are unqualified.

forecast() is unit-specific and says so: the slopes are pooled but the intercept and the lag history are not, so there is no single path to return.

Note

Two biases bracket this estimator and the summary names the one that applies. With unit dummies the lag coefficients carry the Nickell bias, of order \(1/T\) in the shortest unit and downward for a positive own-lag; it does not shrink as units are added. Without them, heterogeneous intercepts load onto the lags and the pooled slopes are biased toward persistence – on a panel whose units differ in level, effects="none" can nearly double an own-lag coefficient. The first bias is the price of removing the second, and the GMM-in-differences estimators that avoid both are not implemented here. Pooling itself is the stronger assumption: heterogeneous dynamics estimated as if common do not average to the mean dynamics.

Variables:
  • endog – Every unit stacked, in the order given. Not a time series.

  • names – Variable labels, in Cholesky order.

  • unit_names – Unit labels.

  • unit_lengths – Observations per unit before lags are taken.

  • effects – "unit" or "none".

  • order – Autoregressive order, common to all units.

  • trend – Deterministic specification, meaningful only under "none".

  • coefficients – (p, k, k) stack of pooled A_1, ..., A_p.

  • deterministic – One row per unit under fixed effects, otherwise one row per deterministic term.

  • sigma_u – Pooled residual covariance with the degrees-of-freedom correction, which counts the unit indicators.

  • sigma_ml – Pooled residual covariance divided by the effective sample.

  • resid – Residuals, stacked in unit order.

  • fittedvalues – One-step conditional means, stacked in unit order.

  • design – The regressor matrix as estimated.

  • llf – Gaussian log-likelihood.

  • nobs – Effective sample size, the sum of T_i - p.

  • n_params – Free parameters, covariance included.

See also

  • PanelVAR – the model whose fit() returns this record.

  • VARResult – the single-unit case, whose surface this record inherits.

  • GVARResult – the other many-unit system in the package, which lets every unit keep its own dynamics and links them instead of pooling.

References

Holtz-Eakin, D., Newey, W., & Rosen, H. S. (1988). Estimating vector autoregressions with panel data. Econometrica, 56(6), 1371-1395.

Nickell, S. (1981). Biases in dynamic models with fixed effects. Econometrica, 49(6), 1417-1426.

Canova, F., & Ciccarelli, M. (2013). Panel vector autoregressive models: A survey. In VAR Models in Macroeconomics – New Developments and Applications (Advances in Econometrics, Vol. 32, pp. 205-246). Emerald.

Example

Six units of unequal length share one autoregression around unit means two standard deviations apart. With unit effects the pooled slopes land near the truth and the own-lag of the second variable shows the downward Nickell bias; without them the level differences masquerade as persistence:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> A = np.array([[0.5, 0.2], [0.1, 0.4]])
>>> units = []
>>> for i in range(6):
...     mu = rng.normal(0.0, 2.0, size=2)
...     y = np.zeros((80 + 10 * i, 2))
...     y[0] = mu
...     for t in range(1, y.shape[0]):
...         y[t] = mu + A @ (y[t - 1] - mu) + rng.standard_normal(2)
...     units.append(y)
>>> res = PanelVAR(units, order=1).fit()
>>> res.n_units, res.unit_lengths, res.nobs, res.min_time_dimension
(6, (80, 90, 100, 110, 120, 130), 624, 80)
>>> res.coefficients[0].round(2)
array([[0.53, 0.22],
       [0.14, 0.33]])
>>> pooled = PanelVAR(units, order=1, effects="none", trend="c").fit()
>>> bool(pooled.coefficients[0, 0, 0] > 0.8), bool(pooled.coefficients[0, 1, 1] > 0.55)
(True, True)
>>> sorted(res.unit_effects)[:2], res.forecast(3, unit="unit2").shape
(['unit1', 'unit2'], (3, 2))

Attributes#

coefficients

The (p, k, k) pooled autoregressive matrices.

deterministic

(N, k) unit intercepts under fixed effects, else (d, k) pooled terms.

unit_names

Unit labels, in stacking order.

unit_lengths

Observations each unit contributed before its order leading rows became lags.

effects

"unit" for one intercept per unit, "none" for a pooled deterministic block.

bse

Standard errors, keyed identically to params.

coefficient_covariance

Covariance of the coefficient matrix, sampling or posterior.

companion

The (kp, kp) companion matrix of the autoregressive block.

design

endog

fittedvalues

information_criteria

AIC, BIC, and HQIC derived from the likelihood and parameter count.

is_stable

Whether every companion eigenvalue lies inside the unit circle.

k_endog

Number of endogenous variables.

llf

min_time_dimension

Observations in the shortest unit, which is what the Nickell bias tracks.

n_params

n_units

Number of units.

names

nobs

order

params

Every coefficient, keyed "{equation}: {regressor}".

posterior

prior_label

pvalues

Two-sided p-values against zero, keyed identically to params.

resid

sigma_ml

sigma_u

slopes

The pooled lag coefficients alone, without the unit intercepts.

trend

tvalues

Normal test statistics against zero, keyed identically to params.

unit_effects

Each unit's intercept vector.

Methods#

arch_test(variable[, lags])

Engle's LM test for conditional heteroskedasticity in one equation.

compare(*others[, criterion])

Rank this result against others by an information criterion.

conf_int(*[, alpha])

Confidence bounds for every coefficient.

equation(name)

The coefficients of one equation, keyed by regressor.

fevd([horizon])

Forecast-error variance decomposition.

forecast([steps, unit])

Point forecasts for one unit.

generalized_fevd([horizon])

Variance shares from the generalized responses, normalized to sum to one.

generalized_irf([horizon, cumulative])

Pesaran-Shin impulse responses, which do not depend on variable order.

granger_causality(cause, effect)

Wald test that one variable's lags are jointly zero in another equation.

historical_decomposition()

Attribute each observation to the shocks that produced it.

identify(strategy)

Declare an identification scheme and return the structural view.

irf([horizon, orthogonalized, cumulative])

Impulse responses to a one-standard-deviation shock.

likelihood_ratio_test(unrestricted)

Test this result as the restricted model against a nesting one.

ma_representation([horizon])

Moving-average matrices Psi_0, ..., Psi_horizon.

normality_test(variable)

Jarque-Bera test on one equation's residuals.

portmanteau_test([lags])

Multivariate Ljung-Box test for residual autocorrelation.

residual_diagnostics(*[, portmanteau_lags, ...])

Run every residual test and collect them into one table.

simulate([n, seed, burn])

A fresh sample path from the fitted system.

stability_check()

Eigenvalue verdict for the companion matrix.

structural_shocks()

Orthogonalized innovations P^{-1} u_t, shape (nobs, k).

summary()

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

unit_residuals(unit)

One unit's residuals.

unit_series(unit)

One unit's observations, including the rows consumed as lags.