Ale
Ale

Reputation: 133

PYMC2 ZeroProbability error

I have a model with 6 parameters with uniform priors:

parameter1 = pm.Uniform('parameter1',0.01,1)
parameter2 = pm.Uniform('parameter2',0,2)
parameter3 = pm.DiscreteUniform('parameter3',1,50)
parameter4 = pm.Uniform('parameter4',0,1.75)
parameter5 = pm.Uniform('parameter5', 0.005, 0.25)
parameter6 = pm.Uniform('parameter6', 0.005, 0.15)

I have a custom likelihood function that returns log likelihood value:

@pm.potential
def log_l(experiment=experiment,parameter1=parameter1,parameter2=parameter2,parameter3=parameter3,parameter4=parameter4,parameter5=parameter5,parameter6=parameter6):

    if parameter5<parameter4:
        return -np.inf

    parameters=[parameter1, parameter2, parameter3]

    log_l=calculate_probability(parameters, t_m, tol, n_integration, parameter4, parameter5, parameter6, experiment.decon_all[freq,:,:])

    return log_l

Where calculate_probability is a my function that returns log likelihood for this model given parameter values and observed data. For some reason when MCMC samples:

model = pm.MCMC([parameter1,parameter2,parameter3,parameter4,parameter5,parameter6,log_l])
model.sample(100)

and the programme satisfies the if condition (parameter5<parameter4) I get this error:

pymc.Node.ZeroProbability: Potential log_l forbids its parents' current values

I was wondering if anyone knows what I may be doing wrong?

Upvotes: 1

Views: 161

Answers (1)

unutbu
unutbu

Reputation: 880937

Per the docs:

Potentials have one important attribute, logp, the log of their current probability or probability density value given the values of their parents. The only other additional attribute of interest is parents, a dictionary containing the potential’s parents.

So the parents of your log_l are the arguments of log_l:

In [11]: list(log_l.parents.keys())
Out[11]: ['experiment', 'parameter2', 'parameter3', 'parameter1', 'parameter4', 
          'parameter6', 'parameter5']

Per this answer (my emphasis):

When a random variable is defined as a function of another random variable, PyMC checks that no value of the parent distribution leads to an impossible value for the child distribution.

Making log_l return -np.inf implies certain values of the parent variables are impossible. Hence, PyMC raises a ZeroProbability exception.


So instead of constraining the model by using

if parameter5<parameter4:
    return -np.inf

you could define parameter5 with

parameter4 = pm.Uniform('parameter4', 0, 1.75)
parameter5 = pm.Uniform('parameter5', parameter4, 0.25)

to ensure that parameter5 > parameter4.

Upvotes: 1

Related Questions