I am unable to understand why the following code is not able to recover the paramters of the model. The same method was able to recover the parameters in a quadratic polynomial quite well. Please help.
def sin(a,b,c,d,x):
return a + b*np.sin(c*x+d)
x = np.linspace(0,10,1000)
y = sin(0,0.5,0.5,4,x) + np.random.normal(0, 0.05, len(x))
with pm.Model() as model_sin:
a = pm.Uniform('a',-10,10)
b = pm.Uniform('b',-10,10)
c = pm.Uniform('c',-10,10)
d = pm.Uniform('d',-10,10)
epsilon = pm.Exponential('epsilon', 1/30)
mu = sin(a,b,c,d,x)
y_pred = pm.beta('y_pred', mu ,observed=y)
trace_sin = pm.sample(1000, step = pm.NUTS())
plt.scatter(x,y,c='r')
plt.plot(x,sin(trace_sin['a'].mean(),trace_sin['b'].mean(),trace_sin['c'].mean(),trace_sin['d'].mean(),x), c='b')
Your priors cover multiple equally valid solutions. For example, a negative amplitude (b
) is equally explained by a phase (d
) of pi/2.
In MCMC sampling, multiple equivalent solutions in the prior space can result in multimodal posterior distributions (generally not a good thing). You can check for this by generating a trace plot. Here's what trace plot looks like after running your code:
which clearly shows multiple modes (in this case across the different chains) in the b, c, d
latent variables.
Taking the mean of the samples from a multimodal distribution often gives you parameterizations that are improbable. In the trace plot here, we're going to see means for b,c,d
that are outside any of the modes. This is why you see the failure to generate reasonable mean parameterizations.
Try restricting your prior distributions so that only unique solutions to the function space are specified.