Pearl Layer 1 — Association
Observational AssociationP(Y | X) — what correlates with what, without intervening
How to read this output
The result has two tables (substitution + fringe), each with one row per bin. Read each row as: 'in this bin, the observed quantity behaved like…'
e.g. count=11 means 11 of the simulated years fell into this bin
e.g. mean_Q_fringe=4.97 in the Q4 (highest-price) bin → fringe producers entered when price was high
e.g. ρ=+0.76 means strong positive monotone association (the quantity rises with the binning variable in rank-order)
e.g. p=0.027 → significant at the 5% level (but with this small N treat any p > 0.01 with caution)
Key takeaway: A large |ρ| with small p says 'X and Y co-move'. It does NOT say 'X caused Y'. To distinguish, climb the ladder to L2 (intervention) or L3 (counterfactual).
What L1 (Association) computes
Formal: P(Y | X) — conditional distribution of Y given observed X, no manipulation
Substitution association — Spearman rank correlation
bin = { restricted: years where shock.export_restriction > 0,
normal: years where shock.export_restriction = 0 }
ρ_sub = corr_Spearman( Q_sub_t , shock.export_restriction_t )
within each bin (return ρ, p-value, mean & std of Q_sub)Fringe association — Spearman by price quartile
Q1..Q4 = price quartiles over the simulation horizon
ρ_fringe = corr_Spearman( Q_fringe_t , P_t )
within each quartile (return ρ, p-value, mean & std of Q_fringe)Caveat: ρ measures association only. A non-zero ρ does NOT imply 'restriction caused substitution' — a confounder (e.g. policy regime, year fixed effects) could explain both. Use L2 to sever those confounders via graph surgery.
Source: src/minerals/pearl_layers.py — observe_substitution_association(), observe_fringe_association()
No L1 query run yet
Pick a scenario on the left and click Run L1 Association. The result shows observational correlations — the first rung of Pearl's ladder, before any intervention or counterfactual reasoning.