def _sample_pymc3(cls, dist, size, seed): """Sample from PyMC3.""" import pymc3 pymc3_rv_map = { 'MatrixNormalDistribution': lambda dist: pymc3.MatrixNormal( 'X', mu=matrix2numpy(dist.location_matrix, float), rowcov=matrix2numpy(dist.scale_matrix_1, float), colcov=matrix2numpy(dist.scale_matrix_2, float), shape=dist.location_matrix.shape), 'WishartDistribution': lambda dist: pymc3.WishartBartlett( 'X', nu=int(dist.n), S=matrix2numpy(dist.scale_matrix, float)) } dist_list = pymc3_rv_map.keys() if dist.__class__.__name__ not in dist_list: return None with pymc3.Model(): pymc3_rv_map[dist.__class__.__name__](dist) return pymc3.sample(size, chains=1, progressbar=False)[:]['X']
def _sample_pymc3(cls, dist, size, seed): """Sample from PyMC3.""" import pymc3 pymc3_rv_map = { 'MatrixNormalDistribution': lambda dist: pymc3.MatrixNormal( 'X', mu=matrix2numpy(dist.location_matrix, float), rowcov=matrix2numpy(dist.scale_matrix_1, float), colcov=matrix2numpy(dist.scale_matrix_2, float), shape=dist.location_matrix.shape), 'WishartDistribution': lambda dist: pymc3.WishartBartlett( 'X', nu=int(dist.n), S=matrix2numpy(dist.scale_matrix, float)) } sample_shape = { 'WishartDistribution': lambda dist: dist.scale_matrix.shape, 'MatrixNormalDistribution': lambda dist: dist.location_matrix.shape } dist_list = pymc3_rv_map.keys() if dist.__class__.__name__ not in dist_list: return None import logging logging.getLogger("pymc3").setLevel(logging.ERROR) with pymc3.Model(): pymc3_rv_map[dist.__class__.__name__](dist) samps = pymc3.sample(draws=prod(size), chains=1, progressbar=False, random_seed=seed, return_inferencedata=False, compute_convergence_checks=False)['X'] return samps.reshape(size + sample_shape[dist.__class__.__name__](dist))
prec = np.linalg.inv(covariance) mean = [.5, 1, .2] data = scipy.stats.multivariate_normal(mean, covariance).rvs(5000) plt.scatter(data[:, 0], data[:, 1]) with pm.Model() as model: S = np.eye(3) nu = 5 mu = pm.Normal('mu', mu=0, sd=1, shape=3) # Use the transformed Wishart distribution # Under the hood this will do a Cholesky decomposition # of S and add two RVs to the sampler: c and z prec = pm.WishartBartlett('prec', S, nu) # To be able to compare it to truth, convert precision to covariance cov = pm.Deterministic('cov', tt.nlinalg.matrix_inverse(prec)) lp = pm.MvNormal('likelihood', mu=mu, tau=prec, observed=data) start = pm.find_MAP() step = pm.NUTS(scaling=start) def run(n=3000): if n == "short": n = 50 with model: trace = pm.sample(n, step, start)