Hidden Confounding in Extremal Causal Discovery
Independent research project by Anuj Kumar examining how an unobserved common cause can create directional extremal dependence between observed variables, and how two extremal causal-discovery procedures respond in a controlled finite-sample experiment.
Consider a hidden confounder Z that affects two observed variables with unequal strengths,
Z -> V1 and Z -> V2,
with no direct V1 -> V2 edge. Can this latent common cause produce a directionally asymmetric extremal signal in the observed data, and does that signal survive the downstream structure-learning procedures used by causalXtreme and extremeSCM?
This project is deliberately exploratory. It studies one hand-built six-node SCM at n = 1000 with 10 reproducible seeds; it does not claim general failure or robustness of either method.
Three stages were validated.
-
causalXtreme baseline: EASE estimates a causal ordering and
causal_discovery()then induces a maximal DAG compatible with that order. Across 10 Student-t simulations, 7/10 EASE orders were topologically valid with respect to the simulated true DAG. Mean SID was 0.05 and mean SHD was 0.63. The induced DAG always contained 10 edges for p = 5, so SHD reflects the density of the induced graph rather than a sparse-graph target. -
Hidden-confounder tail analysis: for the SCM V1 = 1.5 Z + e1 and V2 = 0.4 Z + e2, the upper-tail Gamma asymmetry Gamma12 > Gamma21 occurred in 9/10 runs. The package's default two-tail Psi asymmetry occurred in 10/10 runs. However, EASE placed V1 before V2 only 4/10 times under both Gamma and Psi. Pairwise tail asymmetry therefore did not deterministically propagate into the global ordering.
-
extremeSCM pruning: conditional on the fixed observed ordering V3 -> V1 -> V2 -> V4 -> V5, the maximal candidate DAG contained 10 forward-compatible edges. The spurious candidate V1 -> V2 survived pruning in 10/10 Student-t runs and 10/10 Gaussian runs; V2 -> V1 survived in 0/10 runs in both settings. Mean TPR was 1.00. Mean package-defined FPR was 0.226 for Student-t and 0.213 for Gaussian.
The appropriate conclusion is therefore a finite-sample exploratory finding: the hidden common cause creates reproducible directional extremal asymmetry in this design, and under the specified pruning configuration the spurious V1 -> V2 candidate is retained consistently. This is not evidence that either method has generally been proved to fail under latent confounding.
SCM used in the hidden-confounder experiment
Heavy-tailed version:
- Z ~ t(1.5)
- V1 = 1.5 Z + e1
- V2 = 0.4 Z + e2
- V3 = e3
- V4 = 1.0 V3 + e4
- V5 = 0.6 V1 + e5
All six noise variables are independent Student-t with df = 1.5. Z is hidden before the observed-data analysis.
Observed truth after hiding Z therefore contains only:
- V3 -> V4
- V1 -> V5
and explicitly does not contain V1 -> V2.
causalXtreme::causal_tail_matrix() has a both_tails argument. The validated analysis computes both formulations explicitly:
both_tails = FALSE: upper-tail Gammaboth_tails = TRUE: two-tail Psi (also the package default)
The original Phase 2 code called the default two-tail output "Gamma". The final repository corrects this terminology and reports Gamma and Psi separately.
The extremeSCM pruning stage is loaded from the external repository at a pinned commit. The final script clones the repository automatically and checks out commit 3901aa0 (the latest commit on the repository's main branch available when this project was validated).
The pruning pipeline is:
observed data -> Pareto transformation -> empirical extremal variogram -> HR extremal CI test -> graph-based pruning.
data2mpareto() retains observations whose row-wise maximum Pareto-transformed value is above the empirical threshold corresponding to p = 0.90. The fast pruning implementation uses a graph-derived conditioning set from mb_selector(), and the edge order is shuffled internally; the experiment fixes the random seed before each run.
report/
hidden-confounding-extremal-causal-discovery.pdf
hidden-confounding-extremal-causal-discovery.md
hidden-confounding-extremal-causal-discovery.tex
R/
phase1_causalxtreme_baseline.R
phase2_hidden_confounder.R
phase4_extremal_pruning.R
results/
phase1/
phase1_causalxtreme_baseline_results.csv
phase2/
phase2_hidden_confounder_results.csv
phase4/
phase4_studentt_results.csv
phase4_gaussian_results.csv
phase4_all_results.csv
phase4_studentt_seed1_candidate_dag.csv
phase4_studentt_seed1_pruned_dag.csv
phase4_gaussian_seed1_candidate_dag.csv
phase4_gaussian_seed1_pruned_dag.csv
README.md
REPRODUCIBILITY.md
LICENSE
.gitignore
Phase 3 was a source/theory audit of the extremeSCM manuscript and repository, so there is no separate Phase 3 script.
Install causalXtreme from GitHub:
install.packages("remotes")
remotes::install_github("nicolagnecco/causalXtreme")Then run the scripts from the project root.
phase4_extremal_pruning.R clones and pins extremeSCM automatically. It also loads the package dependencies requested by extremeSCM/main/load_packages.R.
Run from the project root:
source("R/phase4_extremal_pruning.R")The script writes its validated result CSVs to the project working directory. Copy or move those CSVs into results/phase4/ when reproducing outside the packaged repository.
Validated environment used for the original project included R 4.6.1 on Windows 11 x64, causalXtreme 0.0.0.9000, graphicalExtremes 0.3.5, and pcalg 2.7-12. See REPRODUCIBILITY.md for the dependency notes and exact external extremeSCM commit.
- This is a single SCM design, not a random-DAG sweep.
- n = 1000 and tau = 0.90 are fixed; threshold sensitivity is not studied.
- The pruning stage is conditional on a supplied order rather than an end-to-end estimated order.
- Student-t data are a stress-test setting for an extremal CI procedure whose test is derived for the Huesler-Reiss model class; the Gaussian replication is included as an assumption-aligned check.
- The Gaussian construction contains a negligible Z -> V3 coefficient of 0.001 because the external simulator requires a single-root structure. It is a technical device, not a substantive causal claim.
- The FPR reported in
evaluate_dag()is the package's implementation: false-positive adjacency-matrix entries divided by all zero entries of the true adjacency matrix, including diagonal cells.
- Gnecco, N., Meinshausen, N., Peters, J., and Engelke, S. (2021). Causal Discovery in Heavy-Tailed Models. The Annals of Statistics, 49(3), 1755-1778. https://arxiv.org/abs/1908.05097
- Engelke, S., Gnecco, N., and Rottger, F. (2025). Extremes of Structural Causal Models. https://arxiv.org/abs/2503.06536
causalXtreme: https://github.com/nicolagnecco/causalXtremeextremeSCM: https://github.com/nicolagnecco/extremeSCM
MIT. See LICENSE.