Latent Variable DAGs

Implement Robin Evans’ simplification algorithms from [evans2012] and [evans2016].

evans_simplify(graph: NxMixedGraph, *, latents: None | Variable | Iterable[Variable] = None, tag: str | None = None) NxMixedGraph[source]

Reduce the ADMG based on Evans’ simplification rules in [evans2012] and [evans2016].

Parameters:
  • graph – an NxMixedGraph

  • latents – Additional variables to mark as latent, in addition to the ones created by undirected edges

  • tag – The tag for which variables are latent

Returns:

the new graph after simplification

simplify_latent_dag(graph: DiGraph, *, tag: str | None = None) SimplifyResults[source]

Apply Robin Evans’ four rules in succession, in place from [evans2012] and [evans2016].

class SimplifyResults(graph: DiGraph, widows: Set[Variable], redundant: Set[Variable], unidirectional_latents: Set[Variable])[source]

Results from the simplification of a LV-DAG.

Create new instance of SimplifyResults(graph, widows, redundant, unidirectional_latents)

graph: DiGraph

Alias for field number 0

widows: Set[Variable]

Alias for field number 1

redundant: Set[Variable]

Alias for field number 2

unidirectional_latents: Set[Variable]

Alias for field number 3

remove_widow_latents(graph: DiGraph, tag: str | None = None) Tuple[DiGraph, Set[Variable]][source]

Remove latents with no children (in-place).

Parameters:
  • graph – A latent variable DAG

  • tag – The tag for which variables are latent

Returns:

The graph, modified in place

transform_latents_with_parents(graph: DiGraph, tag: str | None = None, suffix: str | None = None) DiGraph[source]

Transform latent variables with parents into exogenous latent variables.

An exogenous latent variable is a node with no parents.

Parameters:
  • graph – A latent variable DAG

  • tag – The tag for which variables are latent

  • suffix – The suffix to postpend to transformed latent variables.

Returns:

The graph, modified in place

remove_redundant_latents(graph: DiGraph, tag: str | None = None) Tuple[DiGraph, Set[Variable]][source]

Remove redundant latent variables.

W is a redundant latent variable if children of W are a subset of another latent variable.

Parameters:
  • graph – A latent variable DAG

  • tag – The tag for which variables are latent

Returns:

The graph, modified in place

remove_unidirectional_latents(graph: DiGraph, tag: str | None = None) Tuple[DiGraph, Set[Variable]][source]

Remove latents with one child (in-place).

Parameters:
  • graph – A latent variable DAG

  • tag – The tag for which variables are latent

Returns:

The graph, modified in place

An implementation of Sara Taheri’s algorithm for using causal queries for experimental design.

taheri_design_admg(graph: NxMixedGraph, cause: str | Variable, effect: str | Variable, *, tag: str | None = None, stop: int | None = None) List[Result][source]

Run the brute force implementation of the Taheri Design algorithm on an ADMG.

Parameters:
  • graph – An ADMG

  • cause – The node that gets perturbed.

  • effect – The node that we’re interested in.

  • tag – The key for node data describing whether it is latent. If None, defaults to y0.graph.DEFAULT_TAG.

  • stop – Largest combination to get (None means length of the list and is the default)

Returns:

A list of LV-DAG identifiability results. Will be length \(2^{(\|V\| - 2 - # bidirected edges)}\)

taheri_design_dag(graph: DiGraph, cause: str | Variable, effect: str | Variable, *, tag: str | None = None, stop: int | None = None) List[Result][source]

Run the brute force implementation of the Taheri Design algorithm on a DAG.

Identify all latent variable configurations inducible over the given DAG that result in an identifiable ADMG under the causal query corresponding to the given cause/effect.

Parameters:
  • graph – A regular DAG

  • cause – The node that gets perturbed.

  • effect – The node that we’re interested in.

  • tag – The key for node data describing whether it is latent. If None, defaults to y0.graph.DEFAULT_TAG.

  • stop – Largest combination to get (None means length of the list and is the default)

Returns:

A list of LV-DAG identifiability results. Will be length \(2^(|V| - 2)\)

class Result(identifiable: bool, estimand: Expression | None, pre_nodes: int, pre_edges: int, post_nodes: int, post_edges: int, latents: List[Variable], observed: List[Variable], lvdag: DiGraph, admg: NxMixedGraph)[source]

Results from the LV-DAG check.

Create new instance of Result(identifiable, estimand, pre_nodes, pre_edges, post_nodes, post_edges, latents, observed, lvdag, admg)

identifiable: bool

Alias for field number 0

estimand: Expression | None

The estimand returned from the related identification algorithm. Is none if not identifiable.

pre_nodes: int

Alias for field number 2

pre_edges: int

Alias for field number 3

post_nodes: int

Alias for field number 4

post_edges: int

Alias for field number 5

latents: List[Variable]

Alias for field number 6

observed: List[Variable]

Alias for field number 7

lvdag: DiGraph

Alias for field number 8

admg: NxMixedGraph

Alias for field number 9

draw_results(results: Iterable[Result], path: str | Path | Iterable[str] | Iterable[Path], ncols: int = 10, x_ratio: float = 4.2, y_ratio: float = 4.2, max_size: int | None = None) None[source]

Draw identifiable ADMGs to a file.