Hi, I have been working on a simple recursive bayesian update example. The idea is to keep update my model whenever new observations come in and it can be from different distributions. Given some historical data z_1, z_2,\ldots z_k, I am interested in the following thing given a new observation z_{k+1}:
p(z_1, z_2, \ldots. z_{k+1} \propto p(z_{k+1} | x) p(x|z_1, \ldots z_k)
Where p(z_{k+1} | x) is the likelihood function with mean value at z_{k+1} while
p(x|z_1, \ldots z_k) is prior.
So the first step I am trying to figure out is how to write a custom likelihood function based on the results from Kernel density estimation.
Here is my code:
# 50 samples from N(20,2). Lets assume this is our historical data
s1 = np.random.normal(20, 2, 50)
# This is the custom prior from the tutorial that makes me be able to learn the prior from KDE results
def from_posterior(param, samples):
smin, smax = np.min(samples), np.max(samples)
width = smax - smin
x = np.linspace(smin, smax, 100)
y = stats.gaussian_kde(samples)(x)
x = np.concatenate([[x[0] - 3 * width], x, [x[-1] + 3 * width]])
y = np.concatenate([[0], y , [0]])
return Interpolated(param, x, y)
# Here is my own likelihood function
samples = s1
smin, smax = np.min(samples), np.max(samples)
width = smax - smin
kde = stats.gaussian_kde(samples)
x = np.linspace(smin, smax, 100)
y = kde(x)
x = np.concatenate([[x[0] - 3 * width], x, [x[-1] + 3 * width]])
y = np.concatenate([[0], y , [0]])
m = np.sum(x* y/np.sum(y))
def likelihood(samples, m, mu, x):
kde = stats.gaussian_kde(samples)
l = kde(x - m + mu)
return l
# pymc3 sampling. Given a new observation, say s1[0] again for simplicity purpose, I want to update my posterior. That is to say
#p(x|z_1,…z_{k+1}) = p(z_{k+1| x} p(x| z_1,…z_k}
#Where p(x| z_1,…z_k} is prior and p(z_{k+1| x} is likelihood function. The resson why I do x-m +mu in my likelihood function is to make sure my likelihood function’s expected value is at the observed value.
basic_model = Model()
with basic_model:
mu = from_posterior("mu", s1)
#Y_obs = Normal("Z", mu = mu, observed = s1[0])
Y_obs = pm.Potential("observed likelihood", likelihood(s1, m, mu, s1[0]))
trace = sample(1000)
I always got error like
Traceback (most recent call last):
File “”, line 4, in
File “”, line 3, in likelihood
File “/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/stats/kde.py”, line 241, in evaluate
output_dtype = np.common_type(self.covariance, points)
File “<array_function internals>”, line 180, in common_type
File “/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/numpy/lib/type_check.py”, line 764, in common_type
raise TypeError(“can’t get common type for non-numeric array”)
TypeError: can’t get common type for non-numeric array
But if I remove the kde(x-m+mu) line it will get rid of the error.
Can anyone give me some hints about this issues? Or any other suggestions working on similar problem is appreciated as well.