Skip to content

Causal computation in pyAgrum

The main entry point for causal inference is pyagrum.causalImpact(), which computes the causal effect of an intervention do(X=x)do(X=x) on a target variable YY within a pyagrum.CausalModel, using do-calculus identification.

pyagrum.causalImpact(cm, , on, doing, knowing=None, values=None)

Section titled “pyagrum.causalImpact(cm, , on, doing, knowing=None, values=None)”

Identify and evaluate the causal effect of do(doing) on on, optionally conditioning on knowing.

The identification procedure tries in order: d-separation (no effect), backdoor adjustment, frontdoor adjustment, and general do-calculus (ID algorithm).

  • Parameters:
    • cm (pyagrum.CausalModel) – The causal model.
    • on (str or set of str) – Target variable(s) of the causal query. A single string is automatically converted to a one-element set.
    • doing (str or set of str) – Intervened variable(s) (the do-operator applies to these). A single string is automatically converted to a one-element set.
    • knowing (str or set of str , optional) – Observed variable(s) to condition on. Default is empty.
    • values (dict of str → str , optional) – Specific values for the on/knowing variables as {variable_name: value_name}. When provided, the returned tensor is sliced to those values. Default is no slicing.
  • Returns:
    • The CausalImpact object encoding the identified formula.
    • The evaluated tensor P(on | do(doing), knowing), or None if the effect is not identifiable.
    • A string explaining the identification method used or why identification failed.
  • Return type: tuple (pyagrum.CausalImpact, pyagrum.Tensor or None, str)

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Y->Z')
>>> cm = pyagrum.CausalModel(bn)
>>> formula, tensor, expl = pyagrum.causalImpact(cm, on='Z', doing='X')
>>> print(expl)

class pyagrum.CausalImpact(cm, , on, doing, knowing=None)

Section titled “class pyagrum.CausalImpact(cm, , on, doing, knowing=None)”

Represents the result of a causal identification query P(on | do(doing), knowing).

CausalImpact encodes the identified causal formula (when the effect is identifiable) as an expression tree that can be evaluated numerically. It also records the identification method used and an explanation string.

The identification procedure tries the following strategies in order: d-separation (no effect), backdoor adjustment, frontdoor adjustment, and general do-calculus (ID algorithm).

Notes

You may prefer to use the high-level function pyagrum.causalImpact() instead of constructing a CausalImpact object directly.

CausalImpact(cm, *, on, doing, knowing=None) -> CausalImpact : Parameters: : - cm (pyagrum.CausalModel) – the causal model. - on (str or set of str) – target variable(s) of the query. A single string is automatically converted to a one-element set. Keyword-only. - doing (str or set of str) – intervened variable(s) (the do-operator applies to these). A single string is automatically converted to a one-element set. Keyword-only. - knowing (str or set of str, optional) – observed variable(s) to condition on. A single string is automatically converted to a one-element set. Default is empty. Keyword-only.

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Y->Z')
>>> cm = pyagrum.CausalModel(bn)
>>> formula, tensor, expl = pyagrum.causalImpact(cm, on='Z', doing='X')
>>> print(expl)

Return the causal model associated with this query.

Return the NodeIds of the intervened variables.

  • Returns: NodeIds of the variables in the doing-set (do-operator).
  • Return type: list[int]

Return the names of the intervened variables.

  • Returns: Variable names in the doing-set.
  • Return type: tuple[str, ...]

Evaluate the identified causal formula and return the result as a tensor.

Return a human-readable explanation of the identification result.

Describes the method used (e.g. ‘d-separation’, ‘backdoor adjustment’, ‘frontdoor adjustment’, ‘do-calculus (ID)’) or explains why identification failed.

  • Returns: Explanation of the identification outcome.
  • Return type: str

Return True if the causal effect was successfully identified.

If False, the effect cannot be computed from the available data given the causal structure, and eval() will raise an exception.

  • Returns: True if the query is identifiable.
  • Return type: bool

Return the NodeIds of the observed variables.

  • Returns: NodeIds of the variables in the knowing-set.
  • Return type: list[int]

Return the names of the observed variables.

  • Returns: Variable names in the knowing-set.
  • Return type: tuple[str, ...]

Return a LaTeX string for the original causal query before identification.

The query has the form P(on | do(doing), knowing).

  • Parameters:
    • doOperatorPrefix (str , optional) – Prefix for the do-operator notation. Default is ‘do(‘.
    • doOperatorSuffix (str , optional) – Suffix for the do-operator notation. Default is ‘)’.
  • Returns: LaTeX string of the causal query.
  • Return type: str

Return the NodeIds of the target variables.

  • Returns: NodeIds of the variables in the on-set.
  • Return type: list[int]

Return the names of the target variables.

  • Returns: Variable names in the on-set.
  • Return type: tuple[str, ...]

Print the AST of a CausalImpact function in a human readable way.

Return the identified causal formula as a JSON-serialisable dictionary.

The dictionary mirrors the AST node hierarchy. Each node is a dict with an "op" key identifying its type, plus type-specific keys:

  • Binary operators (+, -, *, /): {"op": "+", "op1": {...}, "op2": {...}}
  • Conditional probability P(vars | knowing): {"op": "P", "vars": [...], "knowing": [...]}
  • Joint probability P(vars): {"op": "P", "vars": [...]}
  • Summation / marginalisation var\sum_{\text{var}}: {"op": "sum", "var": "...", "term": {...}}

Returns None if the effect is not identified (i.e. isIdentified() is False).

  • Returns: The AST as a nested dict, or None if not identifiable.
  • Return type: dict[str, object]

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Y->Z')
>>> cm = pyagrum.CausalModel(bn)
>>> ci = pyagrum.CausalImpact(cm, on='Z', doing='X')
>>> import json
>>> print(json.dumps(ci.toDict(), indent=2))

toLatex(, doOperatorPrefix=None, doOperatorSuffix=None)

Section titled “toLatex(, doOperatorPrefix=None, doOperatorSuffix=None)”

Return a LaTeX string representation of the causal impact formula.

  • Parameters:
    • doOperatorPrefix (str , optional) – LaTeX prefix for the do-operator. Defaults to the value in pyAgrum config.
    • doOperatorSuffix (str , optional) – LaTeX suffix for the do-operator. Defaults to the value in pyAgrum config.
  • Returns: LaTeX representation of the causal impact expression.
  • Return type: str

Return a string representation of the identified causal formula.

  • Returns: Human-readable form of the formula (e.g. a sum-product expression over conditional probabilities).
  • Return type: str

pyagrum.counterfactual(cm, , on, whatif, profile=None, values=None)

Section titled “pyagrum.counterfactual(cm, , on, whatif, profile=None, values=None)”

Compute a counterfactual distribution using Pearl’s twin network method.

Answers the question: ‘Given that we observed profile, what would on have been if whatif had been set as specified in values?’

The computation follows the three-step algorithm from Pearl (2018), The Book of Why, chapter 8: abduction (update parentless node priors from the profile), action (apply do(whatif) on the twin model), and prediction (evaluate the causal effect on the twin).

  • Parameters:
    • cm (pyagrum.CausalModel) – The causal model.
    • on (str or set of str) – Target variable(s) of the counterfactual query. A single string is automatically converted to a one-element set.
    • whatif (str or set of str) – Variable(s) whose values are changed in the counterfactual scenario. A single string is automatically converted to a one-element set.
    • profile (dict of str → str , optional) – The factual observation as {variable_name: value_name}. This grounds the counterfactual (step 1: abduction). Default is empty (no factual observation).
    • values (dict of str → str , optional) – Counterfactual values for the whatif variables as {variable_name: value_name}. If omitted, the full distribution over all whatif values is returned.
  • Returns: The counterfactual distribution P(on | do(whatif)) evaluated on the twin model, optionally sliced by values.
  • Return type: pyagrum.Tensor

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Y->Z')
>>> cm = pyagrum.CausalModel(bn)
>>> t = pyagrum.counterfactual(cm, on='Z', whatif='X',
... profile={'Y': 'True'}, values={'X': 'False'})

pyagrum.counterfactualModel(cm, profile=None, whatif=None)

Section titled “pyagrum.counterfactualModel(cm, profile=None, whatif=None)”

Build the twin causal model for a counterfactual query.

Implements steps 1-2 of Pearl’s three-step counterfactual algorithm: compute the posterior of parentless (idiosyncratic) nodes in the observational BN given profile as evidence, then replace their priors in a copy of the model with those posteriors.

  • Parameters:
    • cm (pyagrum.CausalModel) – The original causal model.
    • profile (dict of str → str , optional) – The factual observation as {variable_name: value_name}. Default is empty (no observation; the twin model equals the original).
    • whatif (str or set of str , optional) – Intervened variable(s) in the counterfactual scenario. These are excluded from the set of idiosyncratic nodes that get updated. A single string is automatically converted to a one-element set. Default is empty.
  • Returns: The twin causal model ready for the prediction step.
  • Return type: pyagrum.CausalModel

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Y->Z')
>>> cm = pyagrum.CausalModel(bn)
>>> twin = pyagrum.counterfactualModel(cm, profile={'Y': 'True'}, whatif='X')

Computes a counterfactual distribution using Pearl’s twin network method.

A counterfactual query asks: ‘Given that we observed profile, what would on have been if whatif had been set to the values in values?’

The computation follows the three-step algorithm from Pearl (2018), The Book of Why, chapter 8:

  1. Abduction – compute the posterior distribution of parentless (idiosyncratic) nodes in the original BN given the observed profile.
  2. Action – build a twin causal model in which the priors of those nodes are replaced by their posteriors from step 1, then apply do(whatif) on the twin.
  3. Prediction – evaluate the causal impact of the intervention on the twin model to obtain the counterfactual distribution of on.

Notes

Prefer using the high-level function pyagrum.counterfactual() instead of constructing a Counterfactual object directly.

Counterfactual(cm, on, whatif, profile={}, values={}) -> Counterfactual : Parameters: : - cm (pyagrum.CausalModel) – the causal model. - on (set of str or set of int) – target variables of the counterfactual query. - whatif (set of str or set of int) – variables whose values are changed in the counterfactual scenario. - profile (dict of str → str) – the factual observation, given as {variable_name: value_name}. Default is empty. - values (dict of str → str) – counterfactual values for the whatif variables, given as {variable_name: value_name}. If omitted, the full joint distribution over all whatif values is returned.

Examples

>>> import pyagrum as gum
>>> bn = pyagrum.BayesNet.fastPrototype('X->Y->Z')
>>> cm = pyagrum.CausalModel(bn)
>>> t = pyagrum.counterfactual(cm, on='Z', whatif='X',
... profile={'Y': 'True'}, values={'X': 'False'})

Build the twin causal model from the original model and a factual profile.

This static method implements steps 1-2 of the three-step counterfactual algorithm: it computes the posterior of parentless (idiosyncratic) nodes in the observational BN given the profile evidence, then replaces their prior distributions in a copy of the model with those posteriors.

  • Parameters:
    • cm (pyagrum.CausalModel) – The original causal model.
    • profile (dict of str → str) – The factual observation as {variable_name: value_name}.
    • whatif (set of str) – Intervened variables in the counterfactual scenario. These are excluded from the set of idiosyncratic nodes that get updated.
  • Returns: The twin causal model ready for the prediction step.
  • Return type: CausalModel

pyagrum.counterfactualModel : high-level function wrapper.

Return the CausalImpact used to compute the counterfactual distribution.

The formula is evaluated on the twin model.

  • Returns: The identified causal impact on the twin model.
  • Return type: CausalImpact

Return the names of the target variables.

  • Returns: Variable names in the on-set.
  • Return type: set[str]

Return the original causal model.

  • Returns: The original causal model passed to the constructor.
  • Return type: CausalModel

Return the factual evidence used for abduction.

  • Returns: The observed profile as {variable_name: value_name}.
  • Return type: dict[str, str]

Execute the counterfactual computation (steps 2 and 3).

This method is called automatically by the constructor. Call it explicitly only if you need to re-run after modifying the object’s state.

  • Return type: None

Return a string description of the counterfactual query and its result.

  • Returns: Human-readable summary of the counterfactual computation.
  • Return type: str

Return the twin causal model built during the abduction step.

The twin model has the same structure as the original but with updated priors for parentless nodes (based on the observed profile).

Return the counterfactual distribution as a tensor.

  • Returns: The distribution P(on | do(whatif)) evaluated on the twin model, optionally sliced by values if provided at construction.
  • Return type: Tensor

Return the counterfactual assignments for the whatif variables.

  • Returns: The counterfactual values as {variable_name: value_name}. Empty dict if no specific values were requested.
  • Return type: dict[str, str]

Return the names of the intervened variables.

  • Returns: Variable names in the whatif-set.
  • Return type: set[str]