andrey.pcmci#
- andrey.pcmci(data, *, tau_max=1, pc_alpha=0.2, alpha_level=0.05, indep_test='student_t')[source]#
Learn the lagged causal links of one multivariate time series with PCMCI.
PCMCI [1] works in two steps. The PC1 step selects, for each variable, a few candidate parents among the lagged values of all variables. The momentary conditional independence (MCI) step then tests each lagged link given the selected parents of both its ends. Conditioning on the cause’s own past removes the autocorrelation that makes a plain lagged-correlation test report false links. Use it on one series whose causal 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.tau_max (
int) – The largest lag tested, at least1: links at lags1totau_maxare tested.pc_alpha (
float) – Significance level of the PC1 step, in(0, 1): a candidate parent is dropped when a test gives it a p-value abovepc_alpha. A larger value keeps more parents as conditions for the MCI step.alpha_level (
float) – Significance level of the MCI step, in(0, 1): a link is in the graph when its p-value is at mostalpha_level.indep_test (
str) – The partial-correlation test behind every p-value. Both report the same partial correlation;"student_t"takes its p-value from the Student-t distribution and"fisherz"from Fisher’s z-transform.
- Returns:
Wraps a
temporalTemporalStructurewith lags1totau_maxand no lag 0.structure.lag(k)is adigraphwhose edgei -> jis the link from variableiat timet - kto variablejat timet; a self-loop is a variable’s dependence on its own past. The structure has nolag_weights.metadata["p_values"][k - 1][i][j]andmetadata["statistics"][k - 1][i][j]hold the MCI p-value and partial correlation of that link, for every pair, significant or not.metadata["parents"][j]lists the[i, k]pairs (variableiat lagk) that PC1 selected for variablej, strongest first.orderingisNone, andmetadata["algorithm"]is"pcmci".- Return type:
- Raises:
TypeError – If
tau_maxis not an int.ValueError – If
tau_maxis below 1, ifpc_alphaoralpha_levelis not in(0, 1), ifindep_testis neither"student_t"nor"fisherz", or ifdatais not a usable 2-D matrix with at least2 * tau_max * (n_variables + 1) + 3rows, the length at which every test keeps a degree of freedom. Also if a variable repeats another up to scale and shift, at the same step or up to2 * tau_maxsteps apart, before any test runs; one message names every group of copies, a lagged value as'x' at lag k, and says to keep one column per group.
Notes
Every test is a partial-correlation test. The default,
"student_t", takes the p-value from the Student-t distribution withn - |S| - 2degrees of freedom, for|S|conditions, as the authors’ reference implementation does."fisherz"uses Fisher’s z-transform instead; its p-values differ slightly, so a link close toalpha_levelcan flip. The partial correlation is the correlation of the least-squares residuals of the two tested values given the conditions. It is computed from the correlation matrix, and from the residuals themselves when the conditions are collinear to working precision, as lagged copies of a strongly autocorrelated series can be.All tests use the same time steps, the last
n_samples - 2 * tau_max, where every lag a test can condition on exists: the MCI test of a link at lagkconditions on the cause’s parents, which reach backk + tau_maxsteps. PC1 runs in roundsp = 0, 1, ...: each round tests every remaining candidate given thepstrongest other candidates, one conditioning set per candidate, then drops those that test independent. A candidate’s strength is the smallest absolute partial correlation it has had so far. Equal strengths are ordered by each variable’s rank, as inhc(); the column-order guide says what the rank keeps.Limitations. Measured on simulated linear-Gaussian series with an autodependency in every variable and one cross-link per variable at lag 1 or 2, from 10 to 160 variables with 500 to 2,000 time steps, with
tau_max=2. It found nearly every true link at every size, but its false links grew with the number of variables: its median errors (lag-resolved SHD) stayed below the empty graph’s at 10 variables, came close to it at 20, and exceeded it from 40 on. It assumes linear effects, a stationary series, and no hidden common causes. It does not test same-step (lag 0) links: an effect within one time step is missed and can show up as a false lagged link. An MCI test conditions on up to2 * n_variables * tau_max - 1lagged values, so the series needs many more time steps than that. The MCI step alone runsn_variables ** 2 * tau_maxtests.References
Examples
>>> import numpy as np >>> from andrey import pcmci >>> 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 = pcmci(np.column_stack([x, y]), tau_max=2, alpha_level=0.01) >>> out.structure.lag(1).oriented_edges() [(0, 1, 'directed')] >>> out.structure.lag(2).oriented_edges() []