"Fixed" prior question

Is there any easy way to get pymc3 to pretend to sample a prior distribution and always return a fixed/predefined value? I just need an option to hard code the values of some linear model parameters. Option 2 in the code below works but it would help me if the pymc3 “pretended” to sample and all the results were in the trace. I tried pm.Normal with sigma=0 and pm.Uniform with lower=upper but no luck so far. Please let me know if you have any suggestions.

with pm.Model():
    # Define priors for the unknown parameters
    priors = []
    for i, pri in enumerate(pri_inputs):
        if pri[0] == 1:
            priors.append(pm.Uniform("priors_{}".format(i), lower=pri[1], upper=pri[2])            )
        elif pri[0] == 2:
           priors.append(theano.shared(pri[1], "priors_{}".format(i)))
        elif pri[0] == 3:
           bounded_N = pm.Bound(pm.Normal, lower=pri[3], upper=pri[4])
           priors.append(bounded_N("priors_{}".format(i), mu=pri[1], sigma=pri[2]))
        elif pri[0] == 4:
           bounded_LogN = pm.Bound(pm.Lognormal, lower=pri[3], upper=pri[4])
           priors.append(bounded_LogN("priors_{}".format(i), mu=pri[1], sigma=pri[2]))

    priors = tt.stack(priors)[:, None]

You can try pm.Constant if I understand you correctly, but you can also use a constant number and wrap it in a pm.Deterministic if you want it to show up in the trace without being a variable that is actually attempted to sample.

1 Like

Thank you @ricardoV94. I was experimenting with both before but your post encouraged me to try it again and I am pleased to report that I succeeded :slightly_smiling_face:

Again, for those who may come across a similar problem, below are couple of solutions that worked for me. The first option with pm.Normal it is not pretty but it works. It makes tuning slow and introduces small numerical error.

priors.append(pm.Normal("priors_{}".format(i), mu=pri[1], sigma=1e-8))

However, following @ricardoV94 suggestion I modified the code from original post with the line below and got exactly what I needed:

priors.append(pm.Deterministic("priors_{}".format(i), tt.constant(pri[1])))

It results in the following (note: pri[1]=1.1 and I removed the remaining 4 parameters for clarity):

Multiprocess sampling (2 chains in 2 jobs)
NUTS: [priors_4, priors_2, priors_1, priors_0]
Sampling 2 chains for 1_000 tune and 3_500 draw iterations (2_000 + 7_000 draws total) took 9 seconds.
           mean     sd  hdi_3%  ...  ess_bulk  ess_tail  r_hat
[...]
priors_3  1.100  0.000   1.100  ...    7000.0    7000.0    NaN
[...]

[5 rows x 11 columns]
1 Like