MFVARResult#
- class cultivars.multivariate.reduced_form.mixed_frequency.MFVARResult(*, observed, endog, latent_cov, coefficients, deterministic, sigma_u, resid, loglikelihood, kinds, period, names, order, trend, nobs, weights=None)[source]
Bases:
_SummaryMixin,_VectorPropagationMixinThe latent high-frequency path implied by a mixed-frequency sample.
The model lives at the high frequency,
\[z_t = c + \sum_{i=1}^{p} A_i\, z_{t-i} + u_t, \qquad u_t \sim N(0, \Sigma_u),\]and a variable of kind
"high"is observed as \(z_{it}\) every period, a"stock"as \(z_{it}\) at the end of each low-frequency period, and a"flow"as the weighted sum \(\sum_{j=0}^{m-1} w_j z_{i,t-j}\) over the \(m\) sub-periods ending at \(t\); every other entry of the sample isnan. With \((A, \Sigma_u, c)\) taken as given, the Kalman smoother over a state stacking \(\max(p, m)\) lags returns the conditional mean and covariance of the whole latent path given every reading in the sample, and this record is that path dressed as a VAR result.Note
Nothing here was estimated.
coefficients,sigma_uanddeterministicare the inputs toMFVARechoed back, so there are no standard errors, no information criteria and no comparison surface, andloglikelihoodis the likelihood of the observed entries at those parameters – a diagnostic for comparing parameter sets, not a fit statistic. What the record does carry is the full propagation surface, because the smoothed path is complete: forecasts, impulse responses and decompositions readendogandresidexactly as a VAR result reads its data, with the caveat thatresidare innovations of the smoothed path, smoother than the true innovations where a variable was not observed.- Variables:
observed – The mixed-frequency sample as supplied,
nanpreserved.endog – The inferred latent path,
(nobs, k)and complete. Namedendograther thansmoothed_stateon purpose: it is what the propagation surface consumes, so forecasting and impulse responses work here unchanged, reading the inferred path exactly as a VAR result reads its data.latent_cov – Smoothed state covariances of the contemporaneous block,
(nobs, k, k).coefficients – The
(order, k, k)coefficients used, as supplied.deterministic – Deterministic coefficients, one row per term; the supplied intercept, or zero rows when there was none.
sigma_u – The
(k, k)innovation covariance used, as supplied.resid – Innovations of the inferred path over the effective sample:
z_t - c - A_1 z_{t-1} - ... - A_p z_{t-p}evaluated on the smoothed path. This is what the historical decomposition and the structural shocks consume.loglikelihood – Log-likelihood of the observed entries.
kinds – The frequency role of each variable.
weights – Explicit per-variable sub-period weights, when supplied.
period – Sub-periods per low-frequency period.
names – Variable labels.
order – Autoregressive order.
trend – Deterministic specification implied by the intercept.
nobs – Effective sample size, the rows of
resid.
See also
MFVAR– the model whosesmooth()returns this record and whose docstring records why it does not estimate.MIDASVARResult– the low-frequency alternative, which is estimated.VARResult– the estimated high-frequency result whose parametersMFVAR.from_resultcarries here.
References
Mariano, R. S., & Murasawa, Y. (2003). A new coincident index of business cycles based on monthly and quarterly series. Journal of Applied Econometrics, 18(4), 427-443.
Durbin, J., & Koopman, S. J. (2012). Time Series Analysis by State Space Methods (2nd ed.). Oxford University Press.
Example
A monthly bivariate VAR(1) in which the second variable is seen only as a quarterly average. The smoothed path recovers it to about half its standard deviation, the pointwise uncertainty is lowest in the middle month of each quarter, where both neighbours are tied to the same reading, the implied quarterly readings reproduce the ones observed, and the propagation surface runs on the inferred path:
>>> import numpy as np >>> rng = np.random.default_rng(0) >>> A = np.array([[[0.5, 0.2], [0.1, 0.6]]]) >>> S = np.array([[1.0, 0.3], [0.3, 1.0]]) >>> z = np.zeros((240, 2)) >>> for t in range(1, 240): ... z[t] = A[0] @ z[t - 1] + rng.multivariate_normal(np.zeros(2), S) >>> y = z.copy() >>> y[:, 1] = np.nan >>> for t in range(2, 240, 3): ... y[t, 1] = z[t - 2 : t + 1, 1].mean() >>> res = MFVAR(A, S, kinds=["high", "flow"], period=3).smooth(y) >>> res.endog.shape, res.nobs, res.observed_fraction.round(3) ((240, 2), 239, array([1. , 0.333])) >>> error = res.endog[:, 1] - z[:, 1] >>> bool(np.sqrt(np.mean(error**2)) < 0.5 * z[:, 1].std()) True >>> se = res.latent_stderr[:, 1] >>> bool(se[4] < se[3]) and bool(se[4] < se[5]) True >>> implied = res.implied_low_frequency() >>> bool(np.allclose(implied[2::3, 1], y[2::3, 1])) True >>> res.forecast(2).shape, res.irf(4).shape, res.is_stable ((2, 2), (5, 2, 2), True)
Private methods#
Build the structured summary. |