Skip to content

Causal Model in pyAgrum

Causality in pyAgrum

Causality in pyAgrum primarily involves building a causal model—that is, constructing an (observational) Bayesian network along with a set of latent variables and defining their relationships with observed variables. It also includes the ability to compute causal effects in such models using do-calculus.

pyAgrum provides a set of tools to perform causal inference and estimate causal effects from data. This includes the ability to identify interventions, compute causal impacts, and evaluate the effects of interventions on observed variables.

Note

The causal module can use a LaTeX special arrow (\hookrightarrow) to compactly represent an intervention. By default, it uses the classical “do” notation. You can change this behavior using the following configuration keys:

pyagrum.config["causal","latex_do_prefix"]="\hookrightarrow("
pyagrum.config["causal","latex_do_suffix"]=")"

A pyagrum.CausalModel extends a pyagrum.BayesNet with latent (hidden) variables and explicit causal assumptions. It is the entry point for do-calculus reasoning and causal effect identification.

Causal computation in pyAgrum : Functions for computing causal impacts and applying do-calculus.

A causal model pairing an observational Bayesian network with a causal DAG.

A CausalModel extends an observational BayesNet by adding latent (hidden) variables that represent unobserved common causes between observed variables. The causal DAG includes both observed and latent nodes, while the observational BN contains only the observed ones.

CausalModel(bn) -> CausalModel : Parameters: : - bn (pyagrum.BayesNet) – the observational Bayesian network.

CausalModel(bn, latents, assumeNonSpurious=False) -> CausalModel : Parameters: : - bn (pyagrum.BayesNet) – the observational Bayesian network. - latents (list of (str, list of str)) – description of latent variables. Each entry is a pair (name, children) where name is the latent variable name and children is the list of observed variable names it affects. - assumeNonSpurious (bool) – if True, existing arcs between the children of each latent variable are preserved. Default is False (arcs between affected children are removed as they are assumed to be explained by the latent confounder).

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Y;X->Z;Y->Z')
>>> cm = pyagrum.CausalModel(bn)

Create a model with a latent confounder U between X and Y:

>>> cm = pyagrum.CausalModel(bn, [('U', ['X', 'Y'])], assumeNonSpurious=False)

Add a latent (hidden) variable to the causal model.

The latent variable is added as a common cause of the specified children. By default, any existing arc between two affected children is removed, as it is assumed to be explained by the new latent confounder.

  • Parameters:
    • name (str) – Name of the new latent variable.
    • children (list of str) – Names of the observed variables that are children of this latent variable.
    • assumeNonSpurious (bool , optional) – If True, preserve existing arcs between the specified children. Default is False.
  • Return type: None

Mark an arc in the causal DAG as non-spurious (a genuine causal effect).

  • Parameters:
    • x (int or str) – Tail of the arc (NodeId or variable name).
    • y (int or str) – Head of the arc (NodeId or variable name).
  • Return type: None

Mark an arc in the causal DAG as spurious.

A spurious arc x→y means the observed correlation between x and y is believed to be explained by a latent common cause rather than a direct causal effect. This changes the structural interpretation but does not remove the arc.

  • Parameters:
    • x (int or str) – Tail of the arc (NodeId or variable name).
    • y (int or str) – Head of the arc (NodeId or variable name).
  • Return type: None

Find a backdoor adjustment set between cause and effect.

Returns the first valid backdoor adjustment set found. A backdoor set Z blocks all spurious (non-causal) paths between cause and effect while leaving all directed causal paths open, enabling estimation of the causal effect P(effect | do(cause)) via standard conditioning on Z.

  • Parameters:
    • cause (int or str) – The treatment variable (NodeId or variable name).
    • effect (int or str) – The outcome variable (NodeId or variable name).
  • Returns: A valid backdoor adjustment set as NodeIds, or None if no backdoor set exists. Note: an empty set is a valid backdoor (returned when X has no back-door paths); None means the causal effect cannot be identified via the backdoor criterion.
  • Return type: list[int] | None

pyagrum.DoorCriteria.enumerateBackdoorSets : enumerate all valid sets.

Deprecated alias for causalDAG. Use causalDAG() instead.

Deprecated since version 2.3.2: Use causalDAG() instead.

  • Returns: the causal DAG of the model
  • Return type: pyagrum.DAG

Return the full causal DAG, including latent variables.

  • Returns: The causal DAG (observed + latent nodes).
  • Return type: DAG

Return the children of a variable in the causal DAG.

  • Parameters: x (int or str) – The variable (NodeId or name).
  • Returns: NodeIds of the variable’s children in the causal DAG.
  • Return type: list[int]

Return the connected components of the causal DAG (treating arcs as undirected).

  • Returns: A mapping from component index to the set of NodeIds in that component.
  • Return type: dict[int, list[int]]

Check whether an arc exists in the causal DAG.

  • Parameters:
    • x (int or str) – Tail of the arc (NodeId or variable name).
    • y (int or str) – Head of the arc (NodeId or variable name).
  • Returns: True if the arc x→y exists in the causal DAG.
  • Return type: bool

Find a frontdoor adjustment set between cause and effect.

Returns the first valid frontdoor adjustment set found. A frontdoor set Z intercepts all directed paths from cause to effect and enables estimation of P(effect | do(cause)) even in the presence of unobserved confounders.

  • Parameters:
    • cause (int or str) – The treatment variable (NodeId or variable name).
    • effect (int or str) – The outcome variable (NodeId or variable name).
  • Returns: A valid frontdoor adjustment set as NodeIds, or None if no frontdoor set exists. Note: an empty set is a valid frontdoor in degenerate cases; None means the causal effect cannot be identified via the frontdoor criterion.
  • Return type: list[int] | None

pyagrum.DoorCriteria.enumerateFrontdoorSets : enumerate all valid sets.

Return the NodeId of a variable by name.

  • Parameters: name (str) – The variable name.
  • Returns: The NodeId of the variable.
  • Return type: int
  • Raises: pyagrum.NotFound – If no variable with that name exists in the causal model.

Return the causal sub-model induced by a subset of observed nodes.

The sub-model is restricted to the specified nodes, preserving the relevant portion of the causal DAG and latent structure.

  • Parameters:
    • cm (CausalModel) – The original causal model.
    • subset (list[int]) – NodeIds of the observed variables to keep.
  • Returns: The induced causal sub-model.
  • Return type: CausalModel

Check whether the arc x→y is assumed spurious.

  • Parameters:
    • x (int or str) – Tail of the arc (NodeId or variable name).
    • y (int or str) – Head of the arc (NodeId or variable name).
  • Returns: True if the arc x→y is marked as spurious.
  • Return type: bool

Return the NodeIds of all latent (hidden) variables in the causal model.

  • Returns: NodeIds of latent variables.
  • Return type: list[int]

Return the names of all latent (hidden) variables in the causal model.

  • Returns: Names of latent variables.
  • Return type: set[str]

Return the name of a variable by NodeId.

  • Parameters: id (int) – The NodeId of the variable.
  • Returns: The variable name.
  • Return type: str
  • Raises: pyagrum.NotFound – If no variable with that NodeId exists in the causal model.

Return the names of all variables in the causal model (observed and latent).

  • Returns: The set of all variable names.
  • Return type: set[str]

Return the observational Bayesian network underlying the causal model.

Warning

Do not use this BN for causal inference. It represents the observational distribution only. Use pyagrum.causalImpact() for interventional queries.

  • Returns: The observational BN (observed variables only).
  • Return type: BayesNet

Return the parents of a variable in the causal DAG.

  • Parameters: x (int or str) – The variable (NodeId or name).
  • Returns: NodeIds of the variable’s parents in the causal DAG.
  • Return type: list[int]

Return a Graphviz dot string representing the causal model.

Observed nodes are shown with default styling. Latent nodes are displayed with a distinct background colour. Their names are hidden by default.

  • Parameters:
    • SHOW_LATENT_NAMES (bool , optional) – If True, display the names of latent nodes in the graph. Default is False.
    • NODE_BG (str , optional) – Background colour for latent nodes (hex or CSS colour name). Default is ‘#404040’.
    • NODE_FG (str , optional) – Text colour for latent nodes. Default is ‘white’.
    • EDGE_COL (str , optional) – Edge colour. Default is ‘#4A4A4A’.
  • Returns: A dot-format string representation of the causal model.
  • Return type: str

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Y->Z')
>>> cm = pyagrum.CausalModel(bn)
>>> print(cm.toDot())

Return the variable with the given id or name (observed variables only).

  • Parameters: id_or_name (int | str) – the node id or name of the variable
  • Returns: the discrete variable
  • Return type: DiscreteVariable
  • Raises: pyagrum.NotFound – if the id or name does not correspond to an observed variable in the model

Utility class implementing the backdoor and frontdoor criteria on a causal DAG.

All methods are static and take the DAG as their first argument. This class is stateless: it does not store any model.

A backdoor adjustment set Z between X and Y blocks all spurious (non-causal) paths from X to Y while leaving all directed causal paths open.

A frontdoor adjustment set Z between X and Y intercepts every directed path from X to Y, has no open backdoor path from X to Z, and all backdoor paths from Z to Y are blocked by X.

Notes

High-level search for a single valid set is available via pyagrum.CausalModel.backDoor() and pyagrum.CausalModel.frontDoor().

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Z->Y')
>>> dag = bn.dag()
>>> x, y, z = bn.idFromName('X'), bn.idFromName('Y'), bn.idFromName('Z')
>>> pyagrum.DoorCriteria.satisfiesBackdoorCriterion(dag, x, y, set())
True
>>> pyagrum.DoorCriteria.enumerateFrontdoorSets(dag, x, y)
[{z}]

Return all nodes reachable from X via a backdoor path.

A backdoor path starts with an arc pointing into X (i.e. it begins by going to a parent of X) and then follows any sequence of edges.

  • Parameters:
    • dag (DAG) – The causal DAG.
    • X (int) – NodeId of the source variable.
  • Returns: NodeIds of all nodes reachable from X via a backdoor path.
  • Return type: list[int]

static enumerateBackdoorSets(dag, X, Y, , excluded_nodes=None, max_cardinality=0, only_minimal=True, stopAtFirst=False)

Section titled “static enumerateBackdoorSets(dag, X, Y, , excluded_nodes=None, max_cardinality=0, only_minimal=True, stopAtFirst=False)”

Enumerate valid backdoor adjustment sets for the causal effect of X on Y.

  • Parameters:
    • dag (pyagrum.DAG) – The causal DAG.
    • X (int) – NodeId of the treatment variable.
    • Y (int) – NodeId of the outcome variable.
    • excluded_nodes (set of int , optional) – Nodes that cannot appear in any adjustment set. Default is empty.
    • max_cardinality (int , optional) – Maximum size of returned sets. 0 means no limit. Default is 0.
    • only_minimal (bool , optional) – If True, return only minimal adjustment sets (no redundant variables). Default is True.
    • stopAtFirst (bool , optional) – If True, stop after finding the first valid set. Default is False.
  • Returns: All valid backdoor adjustment sets (as NodeId sets).
  • Return type: list of set of int

static enumerateFrontdoorSets(dag, X, Y, , excluded_nodes=None, max_cardinality=0, only_minimal=True, stopAtFirst=False)

Section titled “static enumerateFrontdoorSets(dag, X, Y, , excluded_nodes=None, max_cardinality=0, only_minimal=True, stopAtFirst=False)”

Enumerate valid frontdoor adjustment sets for the causal effect of X on Y.

  • Parameters:
    • dag (pyagrum.DAG) – The causal DAG.
    • X (int) – NodeId of the treatment variable.
    • Y (int) – NodeId of the outcome variable.
    • excluded_nodes (set of int , optional) – Nodes that cannot appear in any adjustment set. Default is empty.
    • max_cardinality (int , optional) – Maximum size of returned sets. 0 means no limit. Default is 0.
    • only_minimal (bool , optional) – If True, return only minimal adjustment sets. Default is True.
    • stopAtFirst (bool , optional) – If True, stop after finding the first valid set. Default is False.
  • Returns: All valid frontdoor adjustment sets (as NodeId sets).
  • Return type: list of set of int

static existsUnblockedDirectedPath(dag, X, Y, Z)

Section titled “static existsUnblockedDirectedPath(dag, X, Y, Z)”

Test whether a directed path from X to Y exists that is not blocked by Z.

  • Parameters:
    • dag (DAG) – The causal DAG.
    • X (int) – NodeId of the source variable.
    • Y (int) – NodeId of the target variable.
    • Z (list[int]) – Blocking set (NodeIds). A directed path is blocked if it passes through a node in Z.
  • Returns: True if at least one unblocked directed path from X to Y exists.
  • Return type: bool

Return the first valid backdoor adjustment set for the causal effect of X on Y.

  • Parameters:
    • dag (pyagrum.DAG) – The causal DAG.
    • X (int) – NodeId of the treatment variable.
    • Y (int) – NodeId of the outcome variable.
    • excluded_nodes (set of int , optional) – Nodes that cannot appear in any adjustment set. Default is empty.
    • max_cardinality (int , optional) – Maximum size of the adjustment set. 0 means no limit. Default is 0.
    • only_minimal (bool , optional) – If True, return only a minimal adjustment set. Default is True.
  • Returns: The first valid backdoor adjustment set as a list of NodeIds, or None if none exists.
  • Return type: list[int] | None

Return the first valid frontdoor adjustment set for the causal effect of X on Y.

  • Parameters:
    • dag (pyagrum.DAG) – The causal DAG.
    • X (int) – NodeId of the treatment variable.
    • Y (int) – NodeId of the outcome variable.
    • excluded_nodes (set of int , optional) – Nodes that cannot appear in any adjustment set. Default is empty.
    • max_cardinality (int , optional) – Maximum size of the adjustment set. 0 means no limit. Default is 0.
    • only_minimal (bool , optional) – If True, return only a minimal adjustment set. Default is True.
  • Returns: The first valid frontdoor adjustment set as a list of NodeIds, or None if none exists.
  • Return type: list[int] | None

Test whether an open backdoor path from X to Y exists given evidence on Z.

  • Parameters:
    • dag (DAG) – The causal DAG.
    • X (int) – NodeId of the treatment variable.
    • Y (int) – NodeId of the outcome variable.
    • Z (list[int]) – Conditioning set (NodeIds).
  • Returns: True if an open backdoor path from X to Y exists after conditioning on Z.
  • Return type: bool

Return the set of nodes lying on any directed path from X to Y.

  • Parameters:
    • dag (DAG) – The causal DAG.
    • X (int) – NodeId of the source variable.
    • Y (int) – NodeId of the target variable.
  • Returns: NodeIds of all nodes (including X and Y) that lie on at least one directed path from X to Y. Empty if no directed path exists.
  • Return type: list[int] | None

static satisfiesBackdoorCriterion(dag, X, Y, Z)

Section titled “static satisfiesBackdoorCriterion(dag, X, Y, Z)”

Test whether Z satisfies the backdoor criterion for the effect of X on Y.

A set Z satisfies the backdoor criterion with respect to (X, Y) if:

  1. No node in Z is a descendant of X in the causal DAG.
  2. Z blocks every backdoor path between X and Y (paths that begin with an arc pointing into X).
  • Parameters:
    • dag (DAG) – The causal DAG.
    • X (int) – NodeId of the treatment variable.
    • Y (int) – NodeId of the outcome variable.
    • Z (list[int]) – Candidate adjustment set (NodeIds).
  • Returns: True if Z satisfies the backdoor criterion for (X, Y).
  • Return type: bool

static satisfiesFrontdoorCriterion(dag, X, Y, Z)

Section titled “static satisfiesFrontdoorCriterion(dag, X, Y, Z)”

Test whether Z satisfies the frontdoor criterion for the effect of X on Y.

A set Z satisfies the frontdoor criterion with respect to (X, Y) if:

  1. Z intercepts all directed paths from X to Y.
  2. There are no unblocked backdoor paths from X to Z.
  3. All backdoor paths from Z to Y are blocked by X.
  • Parameters:
    • dag (DAG) – The causal DAG.
    • X (int) – NodeId of the treatment variable.
    • Y (int) – NodeId of the outcome variable.
    • Z (list[int]) – Candidate mediator set (NodeIds).
  • Returns: True if Z satisfies the frontdoor criterion for (X, Y).
  • Return type: bool