andrey.granger#
- andrey.granger(data, *, maxlag=2, cv=5)[source]#
Learn the lagged causal graph of a multivariate time series by lasso Granger causality.
A variable Granger-causes another when its past improves the prediction of the other’s present [1]. Each variable is regressed on the past
maxlagsteps of every variable by the lasso [2], with the penalty chosen by cross-validation; a nonzero coefficient is a lagged edge. Use it for one multivariate series whose effects take at least one time step.- Parameters:
data (
ArrayLike) – A multivariate time series, one row per time step. Coerced tofloat64. A DataFrame’s column names become the structure’slabels.maxlag (
int) – Number of past time steps each regression uses, at least 1.cv (
int) – Number of cross-validation folds that choose each regression’s penalty, at least 2.
- Returns:
Wraps a
temporalTemporalStructurewith lags1tomaxlagand no lag 0.structure.lag(k)is adigraphwith the edgei -> jwhenx_i(t - k)has a nonzero coefficient in the regression ofx_j(t), self-loops included;structure.lag_weights[k - 1][i, j]is that coefficient, in the data’s units.orderingisNone, andmetadata["algorithm"]is"granger".- Return type:
- Raises:
TypeError – If
maxlagorcvis not an int.ValueError – If
maxlagis less than 1, ifcvis less than 2, ifdatahas fewer thanmaxlag + cvrows, so that some fold would hold no time step, or ifdatahas fewer than 2 columns.
Notes
An edge says that the past of one variable helps predict another beyond the past of every variable in
data. Granger causality misses effects within one time step, and a common cause left out ofdatacan produce edges.Each regression is fitted on standardized variables, so the edges do not depend on the units of any variable; the coefficients are converted back to the data’s units. Cross-validation chooses the penalty that predicts best, which often keeps small coefficients on lags with no effect: judge the edges by the size of their weights. The folds are consecutive blocks of time steps, and the fit is deterministic. With
andrey.config(num_workers=k), the regressions run onkthreads and return the same coefficients.The penalty is the plain lasso of Arnold et al. [2]. Shojaie and Michailidis [3] propose a truncating lasso penalty that also selects the lag order; it is not implemented here.
Limitations. Measured on simulated linear-Gaussian VAR(2) series with no same-step links, standardized, from 10 to 160 variables with 1,000 time steps, with
maxlag=2. It found most true lagged edges but returned many false ones, so its median errors (missing and extra lagged edges) exceeded the empty graph’s at every size: on half the series at 10 variables and on all of them from 20 on. It assumes linear effects and tests no same-step effects. Each variable’s regression takesmaxlaglags of every variable as inputs, so the work grows withmaxlagand with the square of the number of variables.References
Examples
>>> import numpy as np >>> from andrey import granger >>> rng = np.random.default_rng(0) >>> x = rng.standard_normal(500) >>> y = np.r_[0.0, 0.8 * x[:-1]] + rng.standard_normal(500) >>> out = granger(np.column_stack([x, y]), maxlag=1) >>> round(float(out.structure.lag_weights[0][0, 1]), 1) 0.8