Accelerated

More than 5,000x faster than other popular packages.

more than5,000xfaster

Andreycausal-learngCastleTetradbnlearnInvariantCausalPredictionpcalgMost attractive quadrant

0.0010.010.11101001k10k00.250.50.7511.52empty graphFit time, seconds (log)Errors (empty graph = 1)FCIICPPCGFCIFCI-JCIIAMBCD-NODInter-IAMBMMPC

Each line runs from a method's smallest graph to its largest. Down and left is better. Details in the release cards

more than900xfaster

Andreyxgesbnlearncausal-learnpcalgMost attractive quadrant

0.0010.010.11101001k10k00.250.50.7511.52empty graphFit time, seconds (log)Errors (empty graph = 1)Hill climbingTabu searchGESXGESGIESExact searchCALMMMHCRSMAX2

Each line runs from a method's smallest graph to its largest. Down and left is better. Details in the release cards

more than200xfaster

Andreycausal-learnTetradMost attractive quadrant

0.0010.010.11101001k10k00.250.50.7511.52empty graphFit time, seconds (log)Errors (empty graph = 1)GRaSP-FCIBOSS-FCIGRaSPBOSS

Each line runs from a method's smallest graph to its largest. Down and left is better. Details in the release cards

more than10xfaster

Andreycausal-learnlingamCAMauthors' R RESITMost attractive quadrant

0.0010.010.11101001k10k00.250.50.7511.52empty graphFit time, seconds (log)Errors (empty graph = 1)RESITCAMDirectLiNGAMMultiGroupDirectLiNGAM

Each line runs from a method's smallest graph to its largest. Down and left is better. Details in the release cards

more than100xfaster

Andreytigramitelingamcausal-learnMost attractive quadrant

0.0010.010.11101001k10k00.250.50.751Fit time, seconds (log)1 − link F1PCMCIGrangerLPCMCIPCMCI+VARMA-LiNGAMJ-PCMCI+LongitudinalLiNGAM

Each line runs from a method's smallest graph to its largest. Down and left is better. Details in the release cards

more than100xfaster

AndreylingamTetradcausal-learnMost attractive quadrant

0.0010.010.11101001k10k00.250.50.7511.52empty graphFit time, seconds (log)Errors (empty graph = 1)BottomUpParceLiNGAMCAM-UVRCDGIN

Each line runs from a method's smallest graph to its largest. Down and left is better. Details in the release cards

more than1,000xfaster

Andreycausal-learnMost attractive quadrant

0.0010.010.11101001k10k00.250.50.7511.52empty graphFit time, seconds (log)Errors (empty graph = 1)ANMPNL

Each line runs from a method's smallest graph to its largest. Down and left is better. Details in the release cards

Explore why Andrey is so fast

Accurate

More than 80% fewer errors than other popular packages.

  • Fewer errors than the other package

    Each family's largest cut, summed over every size both ran.

    1. PNL89% fewer errors

      Andrey6
      causal-learn55
    2. RESIT70% fewer errors

      Andrey19
      lingam RESIT63
    3. PC on mixed data, degenerate Gaussian test69% fewer errors

      Andrey30
      Tetrad96
    4. BOSS50% fewer errors

      Andrey43
      causal-learn86
    5. CALM, paper schedule32% fewer errors

      Andrey27
      causal-learn40
  • Tested against the true graphs

    Every release is tested against the true graphs that generated the data. Its release card gives every method's errors beside the other package's.

    Release cards

Agentic

A command line that never prompts and answers in JSON, so an agent can run it alone.

All-in-one

44 supported methods for every kind of data, and five kinds of causal graph.

  • Compared with other packages

    Scroll sideways for every package.

    Andreycausal-learnTetradpcalgbnlearn
    Coverage
    Distinct methods422121810
    Temporal dataYesYesYesNoNo
    Mixed dataYesPartly: No mixed-data test or score; only KCI and the generalized score take category codes, and neither is built for them.YesNoYes
    Nonlinear dataYesYesYesNoNo
    Interventional dataYesPartly: CD-NOD only, for data from several domains, with no targets.Partly: Intervention variables tagged in a metadata file join the first knowledge tier as ordinary variables; no method takes the targets.YesPartly: The mbde score only, for categorical data in its score-based searches.
    Permutation invarianceYesNoPartly: PC and FCI follow the variables' names; BOSS, GRaSP, and GIN changed with the column order.NoNo
    Real data
    Missing valuesYesPartly: PC and CD-NOD only, with the Fisher-z test.YesNoYes
    Background knowledgeYesPartly: PC, FCI, CD-NOD, the LiNGAM methods, and exact search; GES, BOSS, and GRaSP take none.YesPartly: Fixed adjacencies only, with no directions or tiers.Yes
    Edge confidenceYesPartly: Bootstrap edge probabilities for the LiNGAM methods only.YesNoYes
    Speed
    CPU parallelizationYesPartly: Several CPU cores for RLCD and the FastKCI test only.Partly: Several threads for FGES, BOSS, GFCI, and PC's adjacency search.Partly: Several cores for the skeleton step of its stable.fast method only.Partly: A cluster for its constraint-based methods and DirectLiNGAM only.
    GPU accelerationYesPartly: CALM only.NoNoNo
    Open benchmarksYesNoNoNoNo
    Agentic
    JSON command lineYesNoPartly: causal-cmd writes the graph, and only the graph, to a JSON file.NoNo
    Schema for every methodYesNoPartly: Typed parameter defaults and bounds, in an HTML manual.NoNo
    Agent skillYesNoPartly: py-tetrad's development branch has a skill and guides; no release has them.NoNo
    Read from each package's released code: causal-learn 0.1.4.8, Tetrad 7.6.10, pcalg 2.7-12, and bnlearn 5.2.1.
  • Five kinds of causal graph

    DAGs, CPDAGs, PAGs, cyclic graphs, and graphs over time.

From data to graph

From a table of measurements to its causal graph, in a few lines of Python.

Sachs and colleagues measured 11 proteins and phospholipids in 853 human immune cells. PC finds 8 of the 17 links in the known signaling network, and none outside it.

rafmekplcpip2pip3erkaktpkapkcp38jnk
The recovered graph, drawn with andrey.viz.draw.

More examples

example.py
import andrey
from andrey.data import load_dataset

df = load_dataset("sachs").data
out = andrey.pc(df)
print(out)
example.py
pc  cpdag  |  11 nodes  |  8 edges (6 undirected, 2 directed)

  raf -- mek
  plc -- pip3
  pip2 -- pip3
  erk -- akt
  erk -- pka
  akt -- pka
  p38 -> pkc
  jnk -> pkc

  indep_test: fisherz
  tie_break: rank

Five kinds of causal graph

A causal graph says which variables drive which, and how much the data can tell decides its kind. Four methods on data about a lawn, its sprinkler, and the rain: three on a table of measurements, and VARMA-LiNGAM on the same lawn day by day.

seasonrainsprinklerwetslippery
DAG, from DirectLiNGAM. One direction for every edge: non-Gaussian noise settles each one.
seasonrainsprinklerwetslippery
CPDAG, from PC. The data cannot say which way the two edges from season point, so they stay plain lines.
seasonrainsprinklerwetslippery
PAG, from FCI. Circles on both ends: either direction, or a hidden common cause, fits the data.
sprinkler(t-1)wet(t-1)rain(t-1)sprinkler(t)wet(t)rain(t)
Graph over time, from VARMA-LiNGAM. Rain wets the lawn the same day; the sprinkler wets it the next day, and a dry lawn turns the sprinkler on the next day.
sprinklerwetrain
Cyclic graph, the same graph with time collapsed. The sprinkler and the lawn drive each other, though every arrow over time points forward.

What each kind of graph means

Agent support

The andrey command never prompts and answers in JSON, and it describes every method's parameters, so an agent can use it with no person watching. andrey --skill prints a guide the agent loads as a skill.

  1. Find a method

    andrey list names all 46 methods, with the graph each returns.

  2. Read its contract

    andrey run pc --help --json gives each parameter's type, default, and meaning as JSON Schema.

  3. Run it

    The run prints the graph as JSON, its nodes named by the data's header row.

$ andrey list | jq -r '.[] | [.name, .output, .status] | @tsv'
pc cpdag supportedfci pag supportedgfci pag supported... 43 more
exit 0
$ andrey run pc --help --json | jq -c '.method.params.properties.alpha'
{"type":"number","default":0.05,"exclusiveMinimum":0.0,"exclusiveMaximum":1.0,"description":"Significance level of the conditional-independence test.","concept":"alpha","aliases":[],"choice_aliases":{}}
exit 0
$ andrey run pc --data sachs.csv | jq -c '.structure | .labels as $n | .edges[] | [$n[.source], $n[.target], .type]'
["raf","mek","undirected"]["plc","pip3","undirected"]["pip2","pip3","undirected"]["erk","akt","undirected"]["erk","pka","undirected"]["akt","pka","undirected"]["p38","pkc","directed"]["jnk","pkc","directed"]
exit 0
rafmekplcpip2pip3erkaktpkapkcp38jnk
The graph in that JSON, drawn with andrey.viz.draw.

Command-line reference

Methods for every kind of data

Andrey is a Python package for learning causal graphs from observational data, with constraint-based, score-based, permutation-based, functional causal model, temporal, latent-variable, and pairwise methods. 46 methods in 7 families. Every method name links to its API reference. An experimental method has no published benchmark, and its API may change without deprecation.

Constraint-based

Score-based

Permutation-based

Functional causal models

Temporal causal discovery

Latent variables

Pairwise direction

Documentation

Cover: an engraved crystal lit by three lamps, one lamp and the facet it lights amber, drawn in navy linesLatest post · Multi-domain dataWhat multi-domain data are, why data from several environments help causal discovery, and the methods Andrey has for them: CD-NOD, FCI-JCI, and J-PCMCI+.