andrey.data.SCM#
- class andrey.data.SCM(*, graph, functional, noise, latents=0)[source]#
A structural causal model: a causal graph, functional forms, and exogenous noise.
- Parameters:
graph (
GraphSpec) – A lazy graph spec (for example,andrey.data.graphs.erdos_renyi(...)). A concreteGraphStructureis not accepted.functional (
Functional) – The structural-equation family (for example,andrey.data.functional.linear()).noise (
Noise) – The exogenous-noise family (for example,andrey.data.noise.gaussian()).
Examples
>>> import andrey.data as data >>> scm = data.SCM(graph=data.graphs.erdos_renyi(d=8, avg_degree=2), ... functional=data.functional.linear(), ... noise=data.noise.gaussian()) >>> ds = scm.sample(n=100, seed=0) >>> ds.data.shape (100, 8) >>> ds.graph.kind 'dag'
- sample(n, seed, *, scale='standardize', screen=None, dtype=<class 'numpy.float64'>, shuffle=True)[source]#
Draw
nobservational rows; return aCausalDataset.- Parameters:
n (
int) – Number of samples (rows).seed (
int) – Root seed; the graph, weights, and noise streams are derived from it statelessly.scale (
str) –How the generated values are scaled; no mode changes the graph. In raw linear data a variable’s variance grows down the causal order, so sorting the columns by variance recovers much of that order (var-sortability, Reisach et al. 2021). The default removes it for every functional at any size, so no method gains from the units the generator happens to produce.
"standardize"z-scores each column after generation: every column has mean 0 and variance 1, and var-sortability is exactly 0.5. R^2-sortability, the share of a variable’s variance the other variables explain, is the same under any rescaling of the columns, so it stays as high as in the raw data (Reisach et al. 2023)."unitless"draws the weights and noise scales of the linear model so that every node has variance 1 in the population, with each node’s parameters depending only on its number of parents and no bound on the ratio of a parent’s share of the variance to the noise’s (Algorithm 1 of Herman et al. 2025;draw_unitless()). Var-sortability and R^2-sortability are near 0.5, R^2-sortability a little below it on denser graphs, and the sample variances differ from 1 by sampling error. It takes the linear functional without heteroscedastic noise, does not use the functional’sweight_range, and keeps a dense(d, d)correlation matrix, so it takes at most 1,000 nodes (andrey.data.functional.UNITLESS_MAX_NODES)."rescale"divides each node by its sample standard deviation as it is generated, before its children use it, so variance does not accumulate down the causal order: var-sortability is exactly 0.5 and R^2-sortability near 0.5 on sparse graphs. The model then depends on the sample, and the weights keep theirweight_rangerelative to the noise."raw"returns the generated values as they are.
Temporal functionals take
"standardize"and"raw".screen (
FaithfulnessScreen|None) – If given, reject-resample near-unfaithful draws (bounded; raises aftermax_attempts); the accept rate is recorded inreport.faithfulness_accept_rate.dtype (
DTypeLike) – Output dtype ofdata. The structural equations are always solved infloat64; this only controls the final cast. Every consumer upcasts tofloat64, so the default avoids a lossy round-trip;np.float32gives a half-footprint array.shuffle (
bool) – Shuffle the observed columns with a permutation from the seed’s own column stream, and relabel the true graph and the per-node parameters to match; latent nodes stay last. The graph, weights, and noise are the same either way, so the dataset differs fromshuffle=Falseonly in its column order.provenance["column_order"][j]is the index columnjhas withshuffle=False, where the order follows how the graph was drawn (a scale-free graph’s hubs come first, a small-world graph keeps its ring order).
- Return type:
CausalDataset- Raises:
ValueError – If
scaleis not one of the modes, a temporal functional is given a mode other than"standardize"or"raw","unitless"is given a functional other than linear, heteroscedastic noise, or more than 1,000 nodes.
References
Reisach, A. G., Seiler, C., and Weichwald, S. (2021). Beware of the Simulated DAG! Causal Discovery Benchmarks May Be Easy to Game. Advances in Neural Information Processing Systems 34.
Reisach, A. G., Tami, M., Seiler, C., Chambaz, A., and Weichwald, S. (2023). A Scale-Invariant Sorting Criterion to Find a Causal Order in Additive Noise Models. Advances in Neural Information Processing Systems 36.
Herman, R. J., Wahl, J., Ninad, U., and Runge, J. (2025). Unitless Unrestricted Markov-Consistent SCM Generation: Better Benchmark Datasets for Causal Discovery. Proceedings of the Fourth Conference on Causal Learning and Reasoning, PMLR 275, 1506-1531.