FunctionalVARResult#
- class cultivars.multivariate.reduced_form.functional.FunctionalVARResult(*, curves, grid, basis, basis_matrix, mean_curve, scores, factors, explained_variance=None, decay=None)[source]#
A fitted functional vector autoregression.
Each curve \(y_t(\cdot)\), observed on a grid of \(n\) points, is written as a mean curve plus a combination of \(r\) basis functions,
\[y_t(s) \approx \bar y(s) + \sum_{j=1}^{r} \xi_{tj}\, \phi_j(s), \qquad \xi_t = \sum_{i=1}^{p} A_i\, \xi_{t-i} + c + u_t,\]and the dynamics live entirely in the score vector \(\xi_t\). The curve-level surface is the score surface mapped through the basis matrix \(\Phi = [\phi_j(s_k)]\): fitted curves are \(\bar y + \hat\xi_t \Phi'\), forecast curves are the factor forecast through \(\Phi'\), and the response of the whole curve to a factor shock is the factor impulse response through \(\Phi\).
Composition, stated plainly:
factorsis a completeVARResulton the basis scores, and every factor-level question – coefficients, standard errors, Granger causality, stability, residual diagnostics, factor impulse responses – is answered there, not re-exported here one method at a time. This object owns what the factor result cannot know: the basis, the projection’s quality, and the maps back to curve space.Note
Two floors bound every curve-level number. The projection floor,
reconstruction_rmse, is how far the data sit from their own best representation in the basis before any dynamics enter; no fitted or forecast curve can beat it. The factor VAR’s own fit is the second, and the one-step curve error is the two combined. Under"fpca"the basis is estimated from these curves, so the floor is in-sample optimal and the retained share of variance is reported; under the fixed bases it is whatever the chosen functions allow, andexplained_varianceisNonebecause the question has no analogue. The basis is a mean-square choice, not a dynamic one: a variance-share target on level-dominated curves (yields, say) can keep a single level component and discard the slope and curvature movements the dynamics are about, which is whatn_componentsis for.- Variables:
curves – The sample, one curve per row.
grid – The evaluation points, one per column of
curves.basis – Which basis family was used.
basis_matrix – The
(n_points, r)basis the scores live in.mean_curve – The curve subtracted before projection – the sample mean under
"fpca", zero under the fixed bases, whose level factor plays that role itself.scores – The
(nobs, r)projected sample the factor VAR was fitted to.factors – The fitted factor VAR, carrying the entire reduced-form surface at factor level.
explained_variance – Share of centered sample variance each retained component carries, under
"fpca";Noneotherwise.decay – The Nelson-Siegel decay used, under
"nelson-siegel";Noneotherwise.
See also
FunctionalVAR– the model whosefit()returns this record and chooses the basis.VARResult– the type offactors, where all factor-level inference lives.term_structure– the yield-curve models that fix the Nelson-Siegel structure and add the pricing restrictions this basis does not impose.
References
Bosq, D. (2000). Linear Processes in Function Spaces. Springer.
Diebold, F. X., & Li, C. (2006). Forecasting the term structure of government bond yields. Journal of Econometrics, 130(2), 337-364.
Ramsay, J. O., & Silverman, B. W. (2005). Functional Data Analysis. Springer.
Example
Curves that share a fixed shape and move through a random-walk level and an autoregressive tilt. Two principal components carry the two movements, the reconstruction floor is a fraction of the noise, and the curve forecast, the fitted curves and the curve impulse responses are the factor surface pushed through the basis:
>>> import numpy as np >>> rng = np.random.default_rng(0) >>> grid = np.linspace(0.0, 1.0, 25) >>> level = 0.1 * np.cumsum(rng.standard_normal(80)) >>> tilt = np.zeros(80) >>> for t in range(1, 80): ... tilt[t] = 0.7 * tilt[t - 1] + 0.1 * rng.standard_normal() >>> shape = np.sin(np.pi * grid) >>> curves = level[:, None] + tilt[:, None] * (grid - 0.5) + shape >>> curves = curves + 0.01 * rng.standard_normal((80, 25)) >>> res = FunctionalVAR(curves, grid, order=1, basis="fpca", n_components=2).fit() >>> res.k_factors, res.n_points, res.nobs, res.factors.names (2, 25, 80, ('pc1', 'pc2')) >>> res.explained_variance.round(3), bool(res.reconstruction_rmse < 0.02) (array([0.991, 0.008]), True) >>> res.fitted_curves().shape, res.forecast_curves(3).shape, res.irf_curves(4).shape ((79, 25), (3, 25), (5, 25, 2)) >>> bool(np.allclose(res.scores, (curves - res.mean_curve) @ res.basis_matrix)) True
Attributes#
The |
|
The |
|
|
|
The |
|
The |
|
The |
|
The fitted factor VAR on |
|
Per-component shares of centered variance under |
|
The Nelson-Siegel decay the loadings were built at, else |
|
Number of basis functions. |
|
Number of grid points per curve. |
|
Number of curves in the sample. |
|
Root-mean-square projection error over all curves and grid points. |
Methods#
One-step conditional mean curves over the factor VAR's effective sample. |
|
|
Deterministic multi-step curve forecasts from the end of the sample. |
|
The curve's response over time to a one-unit factor shock. |
The sample as the basis sees it, over the full sample. |
|
|
The estimation summary, renderable as text, HTML, or a dataframe. |