mixle.inference.causal module¶
do – interventions on a learned heterogeneous Bayesian network (graph-surgery semantics).
The causality front door over mixle.inference.bayesian_network.learn_bayesian_network(). An
intervention do(net, {field: value}) CLAMPS the intervened fields during ancestral sampling —
their own factors (and hence their parents) are cut out of the generation, which is exactly Pearl’s
graph surgery — and everything downstream flows through the fitted conditional factors:
net = learn_bayesian_network(records)
world = do(net, {0: 2.0}) # the world where field 0 is SET to 2.0
world.sample(1000) # interventional draws
world.expectation(2) # E[field 2 | do(field 0 = 2.0)]
average_causal_effect(net, 0, 2.0, 0.0, outcome=2) # E[Y|do(a)] - E[Y|do(b)]
The signature difference from conditioning: intervening on a DOWNSTREAM field leaves its ancestors
at their marginal law (observing it would have shifted them). do gives interventional
distributions; counterfactuals (abduction over exogenous noise) are a separate, harder rung and are
deliberately not claimed here.
- class InterventionalNetwork(net, interventions)[source]
Bases:
objectA Bayesian network under
do(...): sample and summarize the post-intervention world.- sample(size=1, *, seed=None)[source]
Ancestral sampling with the intervened fields clamped (their factors are never consulted).
- expectation(field, *, n=4000, seed=0)[source]
Monte-Carlo
E[field | do(...)]for a numeric field.
- do(net, interventions)[source]
Return the network under Pearl’s
dooperator (see module docstring).
- average_causal_effect(net, treatment, a, b, outcome, *, n=4000, seed=0)[source]
E[outcome | do(treatment=a)] - E[outcome | do(treatment=b)](numeric outcome).
- counterfactual(net, observed, interventions)[source]
What THIS observed record would have been under the intervention (abduction-action-prediction).
Per Pearl’s three steps, walked in topological order:
abduction – a linear-Gaussian field’s exogenous noise is point-identified from the row: its residual
eps = observed - coef @ parents_observed;action – intervened fields take their
dovalues;prediction – the SAME residual replays through the counterfactual parents:
cf = coef @ parents_cf + eps.
Honest boundaries: (1) a field that is not linear-Gaussian keeps its observed value only while its parents are unchanged under the intervention (that much IS identified); if its parents change, its exogenous noise cannot be recovered from one observation and this raises — use
average_causal_effect()for the population answer instead of a guessed individual one. (2) The counterfactual is relative to the network’s DAG as given: purely observational structure learning cannot orient Markov-equivalent edges (x -> y and y -> x fit equally well), so if the causal direction matters, assert it from domain knowledge rather than trusting the learned arrow.