API reference

andrey.multi_group_direct_lingam#

andrey.multi_group_direct_lingam(data_groups, *, random_state=None)[source]#

Jointly learn one fully oriented DAG per group with multi-group DirectLiNGAM.

All groups share the same d variables. The estimator exploits non-Gaussianity across the datasets to fix a single shared causal order, then estimates a separate weighted adjacency for each group [1]. It applies when several datasets share one causal order but may differ in edge weights.

Parameters:
  • data_groups (Sequence[ArrayLike]) – Two or more datasets over the same d variables; sample counts may differ per group. Each is coerced to float64. DataFrames must name their columns alike; the names become the structures’ labels.

  • random_state (int | None) – Ignored. The method is deterministic; the argument exists so that multi_group_direct_lingam accepts random_state as the other LiNGAM methods do.

Returns:

One envelope per group, in input order. Each wraps a dag GraphStructure; all share the same ordering (the joint causal order) while carrying that group’s own weighted_adjacency (W[i, j] weights i -> j). metadata["algorithm"] is "MultiGroupDirectLiNGAM", with group_index and n_groups.

Return type:

list[StructureOutput]

Raises:

ValueError – If fewer than two groups are given, if the groups disagree on the variable count or on their column names, or if a group is not a usable 2-D matrix or has fewer than n_variables + 1 rows, the fewest with which the pruning step can estimate the edge weights.

Notes

Ties. Each step sums the groups’ scores and breaks ties as direct_lingam() does, ranking each column by its data stacked over the groups. Columns that are copies in any group are handled as copies are in direct_lingam(); a copy gets its single edge only in the groups where it is one.

Limitations. Measured on three groups of 1,000 rows over the same variables, from one sparse random graph (mean degree 2) with linear effects, uniform noise, and weights drawn for each group, from 5 to 20 variables. Its median errors (SHD summed over the groups) were 0 at 5 and 10 variables and 1 at 20, against the empty graph’s 15, 30, and 60. The median fit took 1.2 s at 20 variables, on 4 cores. It assumes linear effects and non-Gaussian noise in every group, and it gives every group the one shared causal order, even when a group’s own order differs.

References

Examples

>>> import numpy as np
>>> from andrey import multi_group_direct_lingam
>>> rng = np.random.default_rng(0)
>>> def group(weight):
...     x = rng.uniform(-1, 1, 1000)
...     y = weight * x + rng.uniform(-1, 1, 1000)
...     return np.column_stack([y, x])
>>> outs = multi_group_direct_lingam([group(0.8), group(-1.5)])
>>> [out.ordering for out in outs]
[(1, 0), (1, 0)]
>>> [round(float(out.weighted_adjacency[1, 0]), 1) for out in outs]
[0.8, -1.5]