Search code examples
pythonbayesianpymc3pymc

How to pass Deterministic variables to Metropolis (PyMC)?


I was trying out the examples in the book : Probabilistic-Programming-and-Bayesian-Methods-for-Hackers.

Towards the end of chapter 2 I got stuck at the block of code below.

It purpose is to determine if a simulated data from a posterior distribution matches the original data, the code block is the first step in the process.

I am using pymc not pymc3.

CODE BLOCK:

N = 10000
with pm.Model() as model:
    beta = pm.Normal("beta", mu=0, tau=0.001, testval=0)
    alpha = pm.Normal("alpha", mu=0, tau=0.001, testval=0)
    p = pm.Deterministic("p", 1.0/(1. + tt.exp(beta*temperature + alpha)))
    observed = pm.Bernoulli("bernoulli_obs", p, observed=D)
    # pytensor.config.compute_test_value = "warn"

    simulated = pm.Bernoulli("bernoulli_sim", p,shape= p.shape )
    step = pm.Metropolis(vars=[p])
    trace = pm.sample(N, step=step)

ERROR:


ValueError                                Traceback (most recent call last)
Cell In[32], line 10
      7 # pytensor.config.compute_test_value = "warn"
      9 simulated = pm.Bernoulli("bernoulli_sim", p,shape= p.shape )
---> 10 step = pm.Metropolis(vars=[p])
     11 trace = pm.sample(N, step=step)

File ~\.conda\envs\bayes_course\Lib\site-packages\pymc\step_methods\metropolis.py:168, in Metropolis.__init__(self, vars, S, proposal_dist, scaling, tune, tune_interval, model, mode, **kwargs)
    166     vars = model.value_vars
    167 else:
--> 168     vars = get_value_vars_from_user_vars(vars, model)
    170 initial_values_shape = [initial_values[v.name].shape for v in vars]
    171 if S is None:

File ~\.conda\envs\bayes_course\Lib\site-packages\pymc\util.py:480, in get_value_vars_from_user_vars(vars, model)
    477     notin = list(map(get_var_name, notin))
    478     # We mention random variables, even though the input may be a wrong value variable
    479     # because most users don't know about that duality
--> 480     raise ValueError(
    481         "The following variables are not random variables in the model: " + str(notin)
    482     )
    484 return value_vars

ValueError: The following variables are not random variables in the model: ['p']

Solution

  • I don't believe you need to provide p to Metropolis. It should be able to use the deterministic var through Bernoulli where it was provided.

    From the documentation here:

    Deterministic quantities are just computeed once at the end of the step, with the final values of the other random variables

    This sounds to me like you can remove vars=[p] and use

    step = pm.Metropolis()
    

    directly.

    I tried it locally with some fake data and it appears that p is in the final trace.

    print(trace.posterior)
    
    Data variables:
        temperature    (chain, draw) float64 -62.98 -21.79 -13.69 ... 18.63 18.63
        beta           (chain, draw) float64 -26.23 -26.23 -39.61 ... 25.9 38.93
        alpha          (chain, draw) float64 -53.5 -53.5 -5.149 ... -0.5374 -0.5374
        bernoulli_sim  (chain, draw) int64 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0
        p              (chain, draw) float64 0.0 1.022e-225 ... 4.518e-210 0.0