Pymc3: find_MAP bug with start value and Uniform distribution

Created on 6 Jul 2017  路  6Comments  路  Source: pymc-devs/pymc3

It looks like find_MAP has a problem with a start value when a variable has a Uniform distribution, as shown in the example below (version 3.1). It seems related to #2042.

import numpy as np
import pymc3 as pm
from theano import as_op
import theano.tensor as tt

# Initialize random number generator
np.random.seed(123)

# True parameter values
alpha, sigma = 1, 1
beta = [1, 2.5]

# Size of dataset
size = 100

# Predictor variable
X1 = np.random.randn(size)
X2 = np.random.randn(size) * 0.2

# Simulate outcome variable
Y = alpha + beta[0]*X1 + beta[1]*X2 + np.random.randn(size)*sigma

basic_model = pm.Model()
with basic_model:

    # Priors for unknown model parameters

    # this works fine:
    #alpha = pm.Normal('alpha', mu=0, sd=10)
    #beta0 = pm.Normal('beta0', mu=0, sd=10)
    #beta1 = pm.Normal('beta1', mu=0, sd=10)

    # this doesn't work:
    alpha = pm.Uniform('alpha', -10, 10)
    beta0 = pm.Uniform('beta0', -10, 10)
    beta1 = pm.Uniform('beta1', -10, 10)

    # Expected value of outcome
    mu = alpha + beta0 * X1 + beta1 * X2

    # Likelihood (sampling distribution) of observations
    Y_obs = pm.Normal('Y_obs', mu=mu, sd=1, observed=Y)

start = {'alpha': 0.7, 'beta0': 1.2, 'beta1': 2.1}
map_estimate = pm.find_MAP(model=basic_model, start=start)
map_estimate

Traceback (most recent call last):
File "bug_find_map.py", line 45, in
map_estimate = pm.find_MAP(model=basic_model, start=start)
File "/home/david/soft/anaconda3/lib/python3.6/site-packages/pymc3/tuning/starting.py", line 101, in find_MAP
r = fmin(logp_o, bij.map(start), fprime=grad_logp_o, callback=callback, args, *kwargs)
File "/home/david/soft/anaconda3/lib/python3.6/site-packages/pymc3/blocking.py", line 63, in map
apt[slc] = dpt[var].ravel()
KeyError: 'beta1_interval__'

Most helpful comment

Thanks for reporting @davidbrochart , should be fixed in #2397

All 6 comments

The start argument of find_MAP requires starting positions for the variables in the transformed space (annoying!), i.e. {'alpha_interval__': 0.0, 'beta0_interval__': 0.0, 'beta1_interval__': 0.0}. You don't get this error for Normal because it doesn't undergo a transformation.

To avoid this, you could alternatively specify start positions using the testval argument:

pm.Uniform('beta1', -10, 10, testval=2.1)

Is the testval as start an officially supported way to specify start, or is it something that is subject to change? Because IMHO it's much more convenient than the dictionary based approach, which requires quite a bit of munging.

I'm not sure... IMO it would be nice if both were supported.

Is the testval as start an officially supported way to specify start,

yes, is officially supported and I agree with you that is a very convenient way to specify and initial position.

Thanks for reporting @davidbrochart , should be fixed in #2397

perhaps we could add a with pm.Model(random_testval=True) which samples from the prior.

Was this page helpful?
0 / 5 - 0 ratings