Camden Cheek
Camden Cheek

Reputation: 65

Using categorical variable as an index for other parameters in PyMC3

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

Answers (1)

aseyboldt
aseyboldt

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

Related Questions