chc.pathway¶
Stability tier: evolving.
Temporal causal pathways: which set of variables, over which lags, drives a target.
A one-step causal tool answers "does X move the target, and in which direction?". CHC's dynamics
layer answers the temporal question: which variables, at which lags and along which multi-step
chains, sequentially drive a target over time -- and which are actionable levers?
causal_pathway composes the two dynamics-causal primitives to answer it end to end:
- Discover the lagged graph (
chc.discovery.discover_lagged_parents) -- the directx^i_{t-tau} -> x^j_tedges, cleaned by conditioning on already-selected parents. - Reach every ancestor of the target by walking the graph backward (transitive closure over the directed lag-edges), recording each source's shortest onset lag -- the walk-sum candidate support (L1; distinct path products can cancel, so this bounds, not equals, the nonzero support).
- Estimate each ancestor's signed total dynamic effect via Jorda local projections
(
chc.irf.local_projection_irf) -- a signed impulse response, not a presence flag; the total effect does not condition on mediators, so an indirect lever's whole chain counts. - Rank + truncate: order by cumulative
|effect|over the horizon; a near-zero link caps a path (weakest-link, L3), and truncating at a finite horizon loses geometrically little (L2).
The three laws behind steps 2-4 are machine-checked in proofs/causal_pathway.v and
validation/causal_pathway.mac: L1 IRF walk-sum (Lutkepohl 2005 eq. 2.1.22), L2 geometric
horizon-truncation (tail C*rho^{H+1}/(1-rho)), L3 weakest-link multiplicative bottleneck.
HONESTY -- what the signs mean. This is regime (b) of the sign-credibility ladder: the sign is
estimated conditional on an explicit, untestable causal model, between SVAR sign-restrictions
(sign imposed) and LP-IV (sign instrument-identified). Each effect is backdoor-adjusted for the
target's own state only; that identifies the total effect of an exogenous / randomised lever and of
direct parents (Jorda conditional exogeneity), but a hidden confounder, a contemporaneous common
cause, or a discovery error that admits a collider can silently flip a sign -- add the confounder to
the trajectory and it is picked up, omit it and it stays confounded. LP and a suitably-specified VAR
target the same population impulse responses (Plagborg-Moller & Wolf 2021); finite-lag
implementations differ by truncation and finite-sample regularisation, so read horizons well beyond
max_lag as increasingly variance-dominated extrapolation. A composed estimator -- no new
dependency, no new estimator.
PathwayEdge
dataclass
¶
One source on the pathway to the target: its lag, signed effect, and actionability.
CausalPathway
dataclass
¶
PathwayCertificate
dataclass
¶
Numeric evidence that causal_pathway recovers a known signed chain and the laws.
causal_pathway(series, target, controls=None, horizon=8, max_lag=3, alpha=0.01)
¶
Discover the ranked temporal pathway driving series[:, target]; see the module docstring.
series is (T, d_state); controls an optional (T, d_control) of levers. Discovers
the lagged graph, reaches every ancestor of target, estimates each ancestor's signed total
dynamic effect over horizon steps, and returns them ranked by cumulative |effect|.
causal_pathway_certificate(seed=0, n=6000, horizon=8)
¶
Recover a known lever -> mediator -> target chain: signs, onset lag, weakest-link, L2 tail.
Ground truth: exogenous lever u drives mediator m (+0.8), m drives target x
(-0.9), plus an independent white-noise decoy with no path to x. A correct pathway
recovers m at onset lag 1 (negative sign), the indirect lever u at onset lag 2 (negative
sign, the weakest-link product +0.8 * -0.9, L3), keeps the unlinked decoy's contribution
near zero (L3/L1), and the denoised mediator IRF's mass beyond the horizon stays under the
geometric majorant |g_H| * r/(1-r) (L2, r the measured local decay ratio).