Hello,
I want to initialize the mass matrix of the NUTS sampler with a covariance matrix calculated from the posterior samples of an MCMC chain that has converged. My small example is:
import pandas as pd
import numpy as np
import pymc3 as pm
#### Generate data
np.random.seed(123)
alpha, sigma = 1, 1 # True parameter values
size = 100 # Size of dataset
# Simulate outcome variable
Y = alpha + np.random.randn(size)*sigma
basic_model = pm.Model()
with basic_model:
# Priors for unknown model parameters
alpha = pm.Normal('alpha', mu=0, sd=10)
sigma = pm.HalfNormal('sigma', sd=1)
# Expected value of outcome
mu = alpha
# Likelihood (sampling distribution) of observations
Y_obs = pm.Normal('Y_obs', mu=mu, sd=sigma, observed=Y)
step1 = pm.NUTS(vars=[alpha,sigma], is_cov=True)
trace = pm.sample(500, step=[step1], tune=1000, discard_tuned_samples=False)
creating the dataframe of posterior samples in the predefined order
df = pd.DataFrame()
for myname in trace.varnames:
if myname in ["alpha", "sigma"]:
k = pd.DataFrame(trace[500:][myname])
print(myname)
df = pd.merge(df, k, left_index=True, right_index=True, how='outer')
# var/cov matrix
covmatrix = np.cov(df.values)
then if I run my model again only with
step1 = pm.NUTS(vars=[alpha, sigma], is_cov=True, scaling=covmatrix)
Here in the sampling step I always get
“PositiveDefiniteError: Scaling is not positive definite: Simple check failed. Diagonal contains negatives”
Of course in this small and simple example tuning the NUTS would not be necessary. Nevertheless, it should still work, shouldn’t it?
It is possible to e.g. invert the calculated covariance matrix with numpy, so it is not singular. Thus, I don’t understand the error message. Can anyone help me to get this code functioning?