Package for defining large scale Structural Causal Models(SCMs), interventions and sampling from them.
where $ N_Z, N_Y, N_X $ is the standard normal.
from pycausal import *
model = SCM("Simple Causal Graph")
X = Variable("X", stats.norm(loc=0,scale=1))
Z = Variable("Z", stats.beta(0.5,0.5))
Ny = HiddenVariable("Ny", stats.norm(loc=0,scale=1))
Y = Ny * Z + exp( X**2 ) << "Y"
model.draw()
with the corresponding graphical causal model,
model.sample(2)
or
(~model)(2)
{'Z': array([0.99181398, 0.02439115]),
'X': array([-0.07538367, 1.69771261]),
'Y': array([ 2.64181855, 17.87651557]) }
model.intervention({ X: 0 },2)
or
imodel = model&{ X: 0 }
imodel(2)
{'X': array([0, 0]),
'Z': array([0.34692997, 0.16893219]),
'Y': array([1.42016021, 0.86607793]) }
We can stack interventions aswell
imodel = model&{ X: 0, Ny: 2}
imodel(2)
is the same as
imodel = model&{X: 0}&{Ny: 2}
imodel(2)
or
imodel = model&{X: 0}
jmodel = imodel&{Ny: 2}
jmodel(2)
We can also sample specific variables instead of the full model.
Y.sample(2)
equivalently, we can write
( ~Y )(2)
array([ 2.64181855, 17.87651557])
Or do independence tests(based on samples or graphical).
Y.independent_of(Ny, significance=0.05)
equivalently, we can write
Y | Ny
False
We can actually define custom operations using func
, and define matrix variables and assignments.
model = SCM("Matrix assignments model")
new_op = func( jax.nn.softmax, name="softmax")
X = Variable("X", stats.uniform(-2,5), shape=[2,2])
Ny = HiddenVariable("Ny",stats.beta(0.4,0.1), shape=[1,1])
y2 = -(sin(X)*2)@np.ones(shape=[2,2])
y3 = new_op(y2)
Y = reduce_sum(y3 + Ny, axis=[-1,-2], keepdims=False) << "Y"
python3 setup.py sdist bdist_wheel
pip install .