CDANs¶
Temporal Causal Discovery from Autocorrelated and Non-Stationary Time Series Data.
A pure-Python implementation of the CDANs algorithm from:
Ferdous, M. H., Hasan, U., & Gani, M. O. (2023). CDANs: Temporal Causal Discovery from Autocorrelated and Non-Stationary Time Series Data. Proceedings of the 8th Machine Learning for Healthcare Conference, PMLR 219. paper · arXiv
What CDANs is for¶
Time series that are both autocorrelated (today depends on yesterday) and non-stationary (the dependence pattern itself changes over time). Three limitations of previous methods that CDANs addresses:
- High dimensionality. By using lagged parents as the conditioning set for contemporaneous CI tests, CDANs avoids conditioning on the full past.
- No lagged edges. Most CD-NOD-style methods recover only contemporaneous structure; CDANs recovers both lagged and contemporaneous.
- Order dependence. The discovered skeleton is independent of the variable ordering in the input.
What you get¶
from cdans import CDANs
from cdans.utils import generate_synthetic_cdans
dataset = generate_synthetic_cdans(n_vars=5, n_samples=500, tau_max=2, seed=42)
result = CDANs(tau_max=2, alpha=0.05, ci_test="kci").fit(dataset.data)
print(result.graph.lagged_edges) # set of (src, dst, lag) tuples
print(result.graph.contemp_adj) # n×n adjacency, 1=directed, 1+1=undirected
print(result.graph.changing_modules) # variables whose mechanism varies with C
fit() runs four algorithm steps in sequence:
| Step | Module | What it does |
|---|---|---|
| 1 | Step 1 — Lagged adjacencies (PCMCI) | MCI tests find X_i[t-lag] -> X_j[t] |
| 2 | Step 2 — Partial graph | Build lagged + fully-connected contemp + surrogate |
| 3 | Step 3 — Skeleton refinement | Prune contemp edges using lagged-parent conditioning |
| 4 | Step 4 — Orientation | V-structures + Meek + independent-change principle |
For a single-page narrative covering the algorithm end-to-end, see the step-by-step walkthrough.
Honest scope¶
- Implemented: all four steps including the iterative
independent-change-principle sink-finding for direction inference between
changing modules. Self-contained KCI test (no
causal-learndependency) and self-contained PCMCI implementation (notigramitedependency). - Not yet implemented: the kernel-PCA driving-force visualization
(
cd_non_con_fun.min the MATLAB reference) and the GP-learned KCI kernel widths (if_GP1=1) used by the MATLAB code forT <= 1000. The independent-change side of the GP path is now available viaindependent_change_width="gp"(sklearn ARD-RBF marginal-likelihood optimization). - Empirical defaults are heuristics. The independent-change kernel
bandwidth's
"auto"mode uses an empirically-tuned multiplier of the median heuristic; see the auto-bandwidth section for why and how to override.