andrey.longitudinal_lingam#
- andrey.longitudinal_lingam(data_list, *, n_lags=1, measure='pwling')[source]#
Learn a temporal causal structure from panel data with Longitudinal LiNGAM.
Longitudinal LiNGAM [1] handles the same units measured at several time points: at each occasion it regresses out the past
n_lagstime points, then applies DirectLiNGAM to orient the instantaneous effects. Use it for repeated-measures / panel designs rather than one long series.- Parameters:
data_list (
Sequence[ArrayLike]) – One dataset per time point, over the same units and identical shape. Each is coerced tofloat64. DataFrames must name their columns alike; the names become the structure’slabels.n_lags (
int) – Number of past time points regressed out before the instantaneous fit, from1to the number of time points minus one.measure (
str) – DirectLiNGAM pairwise independence measure for the instantaneous fit.
- Returns:
Wraps a
temporalTemporalStructure. The first time point has no past, so it is not estimated.structure.timeslists the estimated time points,1toT - 1;structure.time_weights[t][k][i, j]is the weight of edgei -> jat lagkfor the t-th of them (lag 0 is instantaneous), andstructure.lag_weightsrepeats the last time point’s. A lag that reaches before the first time point isNaN. Lagged weights are not pruned, so every lagged graph links every pair of variables, self-loops included; judge lagged effects by weight size.metadata["causal_orders"]holds one causal order per time point, the first one empty; they need not agree, soorderingisNone.metadata["algorithm"]is"longitudinallingam".- Return type:
- Raises:
NotImplementedError – If
measureis not"pwling".TypeError – If
n_lagsis not an int.ValueError – If
data_listhas fewer than two time points, ifn_lagsis outside its range, if the per-time arrays differ in shape, or if the DataFrames’ column names differ.
Notes
At each time point DirectLiNGAM orders the residuals of the lag regressions. Each pairwise regression in its ordering takes the least-squares slope, so every residual it scores is uncorrelated with its regressor in the sample, and listing every unit twice leaves the causal orders unchanged.
Column order. The fit runs on the variables sorted by a rank computed from each column’s own data over all time points, as for
hc(), so reordering the columns relabels the result and changes nothing else, unless two columns are identical.Limitations. Measured on simulated panels with non-Gaussian noise, a dense same-step DAG and a dense lag-1 matrix drawn anew at every time point, and a hidden common cause at the first, from 2 to 5 variables at 20 or 50 time points with 100 to 1,000 units, with
n_lags=1. Its median errors (missing and extra cross-links) stayed far below the empty graph’s at every size. It assumes linear effects and non-Gaussian noise. Each time point’s fit uses only the units’ rows at that time, so its accuracy depends on the number of units, not on the number of time points.References
Examples
>>> import numpy as np >>> from andrey import longitudinal_lingam >>> rng = np.random.default_rng(0) >>> data_list = [rng.uniform(-1, 1, (200, 3)) for _ in range(4)] >>> out = longitudinal_lingam(data_list, n_lags=1) >>> out.structure.type 'temporal'