Skip to content

Lag-0 explanation families under weaker adjacency faithfulness - #17

Merged
Autoplectic merged 1 commit into
mainfrom
lag0-families
Nov 14, 2026
Merged

Autoplectic merged 1 commit into
mainfrom
lag0-families

Conversation

@Autoplectic

@Autoplectic Autoplectic commented Nov 14, 2026 •

Copy link
Copy Markdown
Member

Problem

The PC-style lag-0 layer reads adjacencies from dependence, so it cannot see a link whose dependence shows only jointly. For a lag-0 XOR, Z_t = X_t xor Y_t xor E_t, every pair is independent and the layer reports nothing; test_contemporaneous_xor_leaves_no_pairwise_links pins this behaviour. Keeping links that become dependent given a third variable does not fix it either: the XOR becomes a triangle, and OR gains a false edge induced by its collider.

Change

contemporaneous_families, also available as infer_multiplex(contemporaneous="family"), reports every explanation that weaker adjacency faithfulness allows (Marx, Gretton & Mooij, UAI 2021; Hourican & Quax, arXiv:2610.31724):

  1. Screen. Two processes are linked when their present values are dependent given the lagged conditioning set, or given that set plus one more process's present value. Linked processes form components.
  2. Decisions. In each component of at most 5 processes, every pairwise statement is tested at α/m, a Bonferroni correction over the component's m statements.
  3. Family. Every DAG on the component (up to 29,281) is kept if it is Markov, weakly adjacency faithful (convention="neither" or "not_both"), SGS-minimal, and consistent with any tiers or forbidden arcs.

Outputs:

  • network.contemporaneous_families: one ExplanationFamily per component, with status complete, empty, too_large or unavailable.
  • dataset["contemporaneous"]: marks only what every explanation shares.
  • dataset["contemporaneous_possible"]: marks what any explanation has.

Components that are too large, or too sparse to test, keep the PC-style entries. contemporaneous=True still means the PC-style layer.

The new module infoflow.families provides CIDecisions, explanation_family, ExplanationFamily and decisions_from_distribution (exact decisions for a dit distribution). It builds vectorised DAG and d-separation tables; the 5-node table takes about 1.4 s.

Validation

  • Exact decisions reproduce every population family in the paper:
    • XOR: 3 colliders.
    • Biased-parent XOR: none (4 under "not both").
    • XOR with a descendant: 5 (1 with tiers).
    • Chain: 4.
    • OR: 1 (5 under "not both").
    • Asymmetric interaction: 1 (5 under "not both").
    • The two episodes: 5 and 0 without tiers, 1 and 0 with tiers.
  • Data (static lag-0 motifs, permutation tests): the family equals the population family in 20 of 20 samples at 2000 samples for XOR, XOR with a descendant, OR and the chain. With uncorrected per-statement decisions it matched in only 55–90% of samples and mostly returned empty families otherwise, which is why the decisions are corrected.
  • d-separation agrees with networkx on every 3- and 4-node DAG and on 150 random 5-node DAGs.

Tests and docs

  • tests/test_families.py: 42 tests plus a slow Monte Carlo. Full suite: 317 passed, 13 skipped. ruff, ty and sphinx -W are clean.
  • A new docs page, "Lag-0 explanation families", with updates to the literature review, the interpretation page and the API reference. New bib entries: Marx2021weaker, Hourican2026, Spirtes2000.

Rebased onto main after #16 and #15 merged. The only conflict was the new MultiplexNetwork fields; backbone (#15) and contemporaneous_families are both kept.

@Autoplectic
Autoplectic marked this pull request as ready for review November 14, 2026 20:02
The PC-style lag-0 layer reads adjacencies from dependence, so it cannot see a
link whose dependence shows only jointly: for a lag-0 XOR every pair is
independent and the layer reports nothing. contemporaneous_families (and
infer_multiplex(contemporaneous="family")) instead reports, per component of at
most five processes, every DAG that is Markov, weakly adjacency faithful (Marx,
Gretton & Mooij 2021) and SGS-minimal with respect to a table of
conditional-independence decisions, following Hourican & Quax 2026.

- infoflow/families.py: CIDecisions, explanation_family, ExplanationFamily and
  decisions_from_distribution (exact decisions for a dit distribution). Every DAG
  on up to five nodes is enumerated once, with vectorised d-separation tables.
- Decisions are tested at alpha / m for a component's m statements. One false
  rejection removes the true DAG, so uncorrected decisions leave many families
  empty; corrected ones recovered the population family in 20 of 20 samples of
  each motif (XOR, XOR with a descendant, OR, chain).
- Components that are too large, or whose tables are too sparse to test, keep
  the PC-style entries. The contemporaneous matrix marks only what every
  explanation shares; contemporaneous_possible marks what any has.
- Docs: a lag-0 families page, literature review, interpretation and API.
@Autoplectic
Autoplectic merged commit b405818 into main Nov 14, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant