Distributional do-operator?

Just had look at these resources:

I’m really pleased that PyMC has a do-operator!

The examples I have seen so far only set a constant value for the random variables which are intervened upon. This is excellent for working with perfect interventions or simple counterfactuals. However in many contexts our interventions will be a non-degenerate random variable because our efforts to intervene are imperfect, or at least situations in which the counterfactual distribution is non-degenerate.

I would like an option do(X=U) where U is the distribution under an intervention or counterfactual.

For do(X=U) where U ~ Normal(5,2) I would expect it to look something like this:

do(model, {'X':pm.Normal(5,2)})

Is this already a feature for the do-operator in PyMC and I just missed it in the documentation? Or should I make a feature request?

6 Likes

It’s already possible just not described. You can pass an arbitrary expression that depends on existing model variables:

with pm.Model() as m:
  x = pm.Normal("x")
  y = pm.Normal("y", x)

do_m = pm.do(m, {x: pm.math.switch(x > 0, x, 0})

You can also introduce new variables but they can’t be “named” model variables. You need to use dist.

with pm.Model() as m:
  x = pm.Normal("x")
  y = pm.Normal("y", x)

do_m = pm.do(m, {x: pm.Beta.dist()})

You can also add the variable to the model and then use it in the do intervention if for instance you want to sample it

with pm.Model() as m:
  x = pm.Normal("x")
  y = pm.Normal("y", x)

 
with m:
  new_x = pm.Beta("new_x")

do_m = pm.do(m, {x: new_x})
6 Likes