# Changing a parameter that isn't on the chain every sample

Hello,

Sorry if this is a very easy solution - I searched for a few hours and wasn’t able to find a solution that I understood.

I was wondering if there was a way to introduce uncertainty in a parameter that is being used in the model, without adding it to the chain. For example, suppose I have a linear relationship between two parameters `x` and `y`, such that

`y = Ax + B`, where `A = -0.006 +/- 0.001` and `B = 1 +/- 0.04`. I am sampling `x` and want to change `A` and `B` each chain sample so I can incorporate the uncertainty in my input parameters into the model uncertainty. Is there a way to do this? Thanks.

EDIT: Sorry all, it looks like my phrasing above was confusing. In pseudo-code, here’s what I want:

``````import numpy as np
import pymc3 as pm

# Dummy data
Y = np.arange(0, 50) + np.random.randn(50)

for sample in int(nburnin + nsamples):
with pm.Model() as model:
A = np.random.normal(-0.006, 0.001)
B = np.random.normal(1.0, 0.04)

y_true = pm.Data('y', Y)
x = pm.Flat('x')
y_syn = A*x + B
#... augment likelihood to look at difference between y_true and y_syn ...
trace = pm.sample(...)

``````

Of course the above code wouldn’t work the way it is intended with PyMC3, but this demonstrates my point visually, I think.

I don’t want to use `pm.Normal('A', mu=-0.006, sigma=0.001` and `pm.Normal('B', mu=1, sigma=0.04)` because (my understanding) is that this would sample those parameters to solve them in the MCMC. I just want the values and their uncertainties added into my model solving for x.

it depends on your statistical model. for example, if A is normally distributed, uncertainty is the ‘sigma’ parameter. (Note: I’m not sure if I understand your question properly!)

Not that I know of. But note that 1 chain is just 1 sampling of the model, so you could just perturb `A` and `B` between calls to `pm.sample` something like

``````
for j in range(nchains):
A += np.random.(...)   # I *think* += operates on the underlying memory rather than creating a new object
B += np.random.(...)
x_chains.append(pm.sample(..., chains=1))

``````
1 Like

Can’t you just add a prior to A and B that has the noise distribution you want?

`A_noisy = pm.Normal("A_noisy", A, 1)`

Where the prior can be any distribution centered around your value `A`

This has the advantage that your sample can take into consideration gradient information. Otherwise you are in untested territory in PyMC3.

I think this is the closest thing to what I need, thanks. I also had the idea of perturbing the A & B each chain, but I thought I’d ask if there was a way to do it each sample.

Thanks!

Sorry for the late reply. Wouldn’t using `A_noisy = pm.Normal("A_noisy", A, 1)` allow the sampling to change the distribution of `A` over the chain? I would want my posterior distribution for `A` to be the same as its prior.

I am not sure what your goal is. You want a prior that’s fixed but random? The way I would think about it would be to have fixed parameters (if the approximation is not too bad). So you don’t have a fixed A with a special pdf but a distribution with fixed parameters. Say `A_mean = 10` and `A_std = 1`. Then `A_noisy = pm.Normal("A_noisy", A_mean, A_std)`. The latter would change obviously during inference but `A` itself would be fixed as those are just numbers. Then the prior for `A_noisy2 = pm.Normal("A_noisy", A_mean, A_std)` in another context is exactly the same as `A_noisy1` was. It’s a different way of thinking about it but I feel it achieves the same result, no? If you don’t like to force a Normal prior you can use something else.

Basically, I have two parameters `A` and `B` that have known value and uncertainty. I don’t need to sample in the MCMC, since their value is already determined. I would, however, like to incorporate their uncertainties into my model. Ideally, I would accomplish this by changing the `A` and `B` parameters each sample, but not updating these parameters each step.

I hope that makes more sense.

I think I understand the idea (although not the rationale). I really don’t know how wise it is to change things that pymc expects to be fixed during sampling.

I still feel that what you want is equivalent in practice to just resetting your prior of A every time you sample, but I might be missing something. How would the generative model for your data look like?

Actually I think you’re correct - resetting the prior each sample would achieve the same thing. I don’t see how to do that using `pymc3.sample()`, however.