Reputation: 65
I'm trying to use a categorical variable as an index to choose from a list of parameters for another distribution in PyMC3. I have tried doing this with both pm.switch()
and by indexing an array of parameters. The code runs fine, but the categorical variable appears to be stuck at whatever I define as the testval.
Attempt 1:
import pymc3 as pm
import theano.tensor as tt
with pm.Model() as model:
b = pm.Bernoulli('b', .2, testval=0)
mu = pm.math.switch(b, 0, 10)
n = pm.Normal('n', mu=mu, sd=1)
trace = pm.sample(10000, tune=1000)
Attempt 2:
with pm.Model() as model:
b = pm.Bernoulli('b',.2, testval=1)
mus = tt.as_tensor([0,10])
n = pm.Normal('n', mu=mus[b], sd=1)
trace = pm.sample(10000, tune=1000)
With both attempts, pm.summary(trace)
shows that b
is only being sampled as 0 in the first attempt and 1 in the second attempt (corresponding to the given testvals).
What am I doing wrong that the distribution of b
is not being sampled as the distribution I defined?
Upvotes: 1
Views: 905
Reputation: 1090
pymc3 uses different step methods for n
and b
as one is discrete and the other one is continuous – it can't change them at the same time. At the start b
is 1 and n
is 10. If you propose to change b
to 0 the logp will be way to small, as n
would be 10 sd's from its mean. Changes to n
will be accepted, but only if it doesn't move away from 10 too much. It will not get close enough to 0 that a change in b
would get an reasonable probability.
The typical set of the posterior can be separated into two regions (something like {0} \times [-a, +a] and {1} \times [10-a, 10+a]) and the sampler can't move between them: Some discrete version of multi-modality.
Upvotes: 1