def get_model_GP3_BetaBin(t, r, R, VAF0, K, alpha, cov_fcn, *args, **kargs): nsamples, _ = r.shape with pmc.Model() as mdl: lw = get_model_DP(K, alpha) phi = get_model_GP3(t, K, nsamples, cov_fcn) s = pmc.Uniform('s', shape=nsamples, testval=0.5) u = pmc.Deterministic('u', (1.0 - s) / s)[None, :, None] theta = pmc.Deterministic('theta', VAF0 * phi[:, :, None]) pmc.DensityDist('r', sts.betabinmix_logp_fcn(R, u, theta, lw[:, None]), observed=r) return mdl
def build_model(): with pm.Model() as model: lam = pm.Exponential('lam', 1) failure = np.array([0, 1]) value = np.array([1, 0]) def logp(failure, value): return tt.sum(failure * np.log(lam) - lam * value) pm.DensityDist('x', logp, observed={'failure': failure, 'value': value}) return model
def test_density_dist_without_random_not_sampleable(): with pm.Model() as model: mu = pm.Normal('mu', 0, 1) normal_dist = pm.Normal.dist(mu, 1) pm.DensityDist('density_dist', normal_dist.logp, observed=np.random.randn(100)) trace = pm.sample(100) samples = 500 with pytest.raises(ValueError): pm.sample_posterior_predictive(trace, samples=samples, model=model, size=100)
def test_density_dist_with_random_sampleable(): with pm.Model() as model: mu = pm.Normal('mu', 0, 1) normal_dist = pm.Normal.dist(mu, 1) pm.DensityDist('density_dist', normal_dist.logp, observed=np.random.randn(100), random=normal_dist.random) trace = pm.sample(100) samples = 500 ppc = pm.sample_posterior_predictive(trace, samples=samples, model=model, size=100) assert len(ppc['density_dist']) == samples
def test_spawn_densitydist_syswarning(monkeypatch): monkeypatch.setattr("pymc3.distributions.distribution.PLATFORM", "win32") with pm.Model() as model: mu = pm.Normal("mu", 0, 1) normal_dist = pm.Normal.dist(mu, 1) with pytest.warns(UserWarning, match="errors when sampling on platforms"): obs = pm.DensityDist("density_dist", normal_dist.logp, observed=np.random.randn(100))
def test_density_dist(self): obs = np.random.normal(-1, 0.1, size=10) with pm.Model(): mu = pm.Normal('mu', 0, 1) sd = pm.Gamma('sd', 1, 2) a = pm.DensityDist('a', pm.Normal.dist(mu, sd).logp, random=pm.Normal.dist(mu, sd).random, observed=obs) prior = pm.sample_prior_predictive() npt.assert_almost_equal(prior['a'].mean(), 0, decimal=1)
def bms(L, **sample_kwargs): """This function computes the exceedance probabilities (xp) and expected relative frequencies (r) from an array of log-evidences. Args: L (numpy.ndarray): Array of model log-evidences (higher is better fit). Array shape should be (K models; N subjects) **sample_kwargs: Additional arguments to the pymc.sample function. Currently `cores=1` seems to be necessary. Returns: dict: Dictionary with values xp and r. Reference: Stephan, K. E., Penny, W. D., Daunizeau, J., Moran, R. J., & Friston, K. J. (2009). Bayesian model selection for group studies. Neuroimage, 46(4), 1004-1017. """ K, N = L.shape with pm.Model() as bms: def lookup_L(L, N): """This function looks up the log-evidences for all N subjects, given the current model labels m. """ return L[tt.cast(m, dtype="int32"), tt.cast(tt.arange(N), dtype="int32")] # Priors alpha = pm.Uniform("alpha", 0, N, shape=K, testval=np.ones(K)) # Model r = pm.Dirichlet("r", a=alpha, testval=np.ones(K) / K) m = pm.Categorical("m", p=r, shape=N, testval=0) # Look up log evidence ll = pm.DensityDist("ll", logp=lookup_L, observed=dict(L=L, N=N)) # Sample trace = pm.sample(**sample_kwargs) # Build results result = {} result["summary"] = pm.summary(trace, var_names=["alpha", "r"]) result["xp"] = np.array([ np.mean( trace.get_values("r")[:, k] == trace.get_values("r").max(axis=1)) for k in range(K) ]) r_unscaled = np.array( [np.mean(trace.get_values("r")[:, k]) for k in range(K)]) result["r"] = r_unscaled / r_unscaled.sum() return result
def nmf_gpp_hmc(X, M, **kwargs): """ Samples posterior of NMF GPP with Hamiltonian Monte Carlo using the Leapfrog method for . :param X: Data matrix :param M: Number of latent factors (ie. sources) :param kwargs: Options: 'numSamples': Number of samples to be drawn 'linkH' : Link function for H, callable. Inverse link 'argsH' : Extra arguments for linkH. Should be a list. 'linkD' : Link function for D, callable. Inverse link 'argsD' : Extra arguments for linkD. Should be a list. 'sigma_N' : Variance of Gaussian noise. 'burn' : Burn-in to be discarded 'dimD' : Dimension of covariance for D 'dimH' : Dimension of covariance for H :return: Traces of NN matrix factors, D and H """ # parse arguments try: numSamples = kwargs['numSamples'] dimD = kwargs['dimD'] dimH = kwargs['dimH'] numChains = kwargs['numChains'] db_name = kwargs['db_name'] except KeyError: print("Missing parameter with no default. Terminating") sys.exit(1) K, L = X.shape d_in = np.arange(K*M)[:, None] h_in = np.arange(M*L)[:, None] # begin actual model with pm.Model() as mod: ls_D = pm.Gamma(name='lsd', alpha=3, beta=1, shape=(dimD,)) #covD = pm.gp.cov.ExpQuad(input_dim=dimD, ls=ls_D, active_dims=400) covD = pm.gp.cov.Exponential(input_dim=dimD, ls=ls_D) gpD = CustomLatent(cov_func=covD) d = gpD.prior("d", X=d_in.reshape(K, M)) ls_H = pm.Gamma(name='lsh', alpha=3, beta=1, shape=(dimH,)) covH = pm.gp.cov.ExpQuad(input_dim=dimH, ls=ls_H) gpH = CustomLatent(cov_func=covH) h = gpH.prior("h", X=h_in.reshape(L, M)) X_ = pm.DensityDist('X', loglik_X, observed={'X': X, 'd': d, 'h': h}) db = pm.backends.Text(db_name) trace = pm.sample(numSamples, njobs=1, trace=db, chains=numChains) return trace
def main(): if len(sys.argv) < 2 or len(sys.argv) > 3: print( 'usage: python3 inference_dir.py [chain no] [optional output no]') sys.exit() elif len(sys.argv) == 2: c = int(sys.argv[1]) d = int(sys.argv[1]) if len(sys.argv) == 3: c = int(sys.argv[1]) d = int(sys.argv[2]) np.random.seed(c) lang_minibatch = pm.Minibatch(lang_ind, 500) sound_minibatch = pm.Minibatch(sound_ind, 500) model_ln = pm.Model() with model_ln: beta = pm.HalfFlat('beta') "theta = language-level prior over components" theta = tt.stack([ pm.Dirichlet('theta_{}'.format(l), a=tt.ones(K) * beta, shape=K) for l in range(L) ]) psi = [ pm.MvNormal('psi_{}'.format(k), mu=[0] * S, cov=Sigma, shape=S) for k in range(K) ] "phi = component-level collection of distributions over sound change" phi = tt.stack([ tt.concatenate([ pm.Deterministic( 'phi_{}_{}'.format(k, x), tt.nnet.softmax(psi[k][s_breaks[x][0]:s_breaks[x][1]])[0]) for x in range(X) ]) for k in range(K) ]) #phi = tt.stack([tt.concatenate([pm.Deterministic('phi_{}_{}'.format(k,x),softmax_trans(psi[k][s_breaks[x][0]:s_breaks[x][1]])) for x in range(X)]) for k in range(K)]) target = pm.DensityDist('target', logprob(theta=theta, phi=phi), observed=dict(lang_array=lang_minibatch, sound_array=sound_minibatch), total_size=N) inference_ln = pm.ADVI() inference_ln.fit(50000, obj_optimizer=pm.adam(learning_rate=.01, beta1=uniform(.7, .9)), callbacks=[pm.callbacks.CheckParametersConvergence()]) trace_ln = inference_ln.approx.sample() posterior = { k: trace_ln[k] for k in trace_ln.varnames if not k.endswith('__') } posterior['ELBO'] = inference_ln.hist f = open('posterior_ln_{}.pkl'.format(d), 'wb') pkl.dump(posterior, f) f.close()
def gradient(lim, x_label, y_label, z_label, x, m): loss_fn = lambda x, y: -himmelblau(x, y) theano_op = TheanoOp(loss_fn, x, m) with pm.Model() as my_model: grid_x = pm.Uniform(x_label, lower=-lim, upper=lim) grid_y = pm.Uniform(y_label, lower=-lim, upper=lim) theta = T.as_tensor_variable([grid_x, grid_y]) p = pm.DensityDist(z_label, lambda v: theano_op(v), observed=theta) trace = pm.sample(30000, tune=10000, discard_tuned_samples=True) return list(trace)
def test_spawn_densitydist_mpctxwarning(monkeypatch): ctx = multiprocessing.get_context("spawn") monkeypatch.setattr(multiprocessing, "get_context", lambda: ctx) with pm.Model() as model: mu = pm.Normal("mu", 0, 1) normal_dist = pm.Normal.dist(mu, 1) with pytest.warns(UserWarning, match="errors when sampling when multiprocessing"): obs = pm.DensityDist("density_dist", normal_dist.logp, observed=np.random.randn(100))
def sample_grayscale(image, samples=5000, tune=100, nchains=4, threshold=0.2): """Run MCMC on a 1 color image. Works best on logos or text. Parameters ---------- image : numpy.ndarray Image array from `load_image`. Should have `image.ndims == 2`. samples : int Number of samples to draw from the image tune : int Number of tuning steps to take. Note that this adjusts the step size: if you want smaller steps, make tune closer to 0. nchains : int Number of chains to sample with. This will later turn into the number of colors in your plot. Note that you get `samples * nchains` of total points in your final scatter. threshold : float Float between 0 and 1. It looks nicer when an image is binarized, and this will do that. Use `None` to not binarize. In theory you should get fewer samples from lighter areas, but your mileage may vary. Returns ------- pymc3.MultiTrace of samples from the image. Each sample is an (x, y) float of indices that were sampled, with the variable name 'image'. """ # preprocess image_copy = image.copy() if threshold != -1: image_copy[image < threshold] = 0 image_copy[image >= threshold] = 1 # need an active pixel to start on active_pixels = np.array( list(zip(*np.where(image_copy == image_copy.max())))) idx = np.random.randint(0, len(active_pixels), nchains) start = active_pixels[idx] with pm.Model(): pm.DensityDist('image', ImageLikelihood(image_copy), shape=2) trace = pm.sample( samples, tune=tune, chains=nchains, step=pm.Metropolis(), start=[{ 'image': x } for x in start], ) return trace
def test_multiple_observed_rv_without_observations(self): with pm.Model(): mu = pm.Normal("mu") x = pm.DensityDist( # pylint: disable=unused-variable "x", pm.Normal.dist(mu, 1.0).logp, observed={"value": 0.1} ) trace = pm.sample(100, chains=2) inference_data = from_pymc3(trace=trace) assert inference_data assert not hasattr(inference_data, "observed_data") assert hasattr(inference_data, "posterior") assert hasattr(inference_data, "sample_stats")
def marginal(self, name, **kwargs): """The marginal likelihood Args: name: The name of the node observed: The observed data Returns: A :class:`pymc3.DensityDist` with the likelihood """ return pm.DensityDist(name, self.log_likelihood, **kwargs)
def init_graph(self, rt, response, test): data = {'rt': rt, 'response': response, 'test': test} with pm.Model() as graph: s = 1 tau = .2 b = 12 A = pm.Uniform('A', lower=0, upper=b) v1 = pm.Uniform('v1', lower=0, upper=10) v2 = pm.Uniform('v2', lower=0, upper=10) param = {'A': A, 'b': b, 'v1': v1, 'v2': v2, 's': s, 'tau': tau} logp = self.tensor_logp(param) t_resp = pm.DensityDist('t_resp', logp, observed=data) return graph
def test_multiple_observed_rv(): "Test previously buggy MultiObservedRV comparison code." y1_data = np.random.randn(10) y2_data = np.random.randn(100) with pm.Model() as model: mu = pm.Normal("mu") x = pm.DensityDist( # pylint: disable=unused-variable "x", pm.Normal.dist(mu, 1.0).logp, observed={"value": 0.1} ) assert not model['x'] == model['mu'] assert model['x'] == model['x'] assert model['x'] in model.observed_RVs assert not model['x'] in model.vars
def fit_model_dir(N, J, D, R, T, featvar_id, filename, c, normalize, batch=False): print(normalize) print(batch) model = pm.Model() with model: """hyperparameters""" theta_prior = stickbreak_prior('theta', 1., T) alpha = .1 """priors""" theta = pm.Dirichlet('theta', theta_prior, shape=T) phi = tt.stack([ tt.concatenate([ pm.Dirichlet('phi_{}_{}'.format(t, d), tt.ones(R[d]) * alpha, shape=R[d]) for d in range(D) ]) for t in range(T) ]) """likelihood""" target = pm.DensityDist('target', loglik(theta=theta, phi=phi), observed=dict(featvar_id=featvar_id)) """fit model""" inference = pm.ADVI() inference.fit(100000, obj_optimizer=pm.adam(learning_rate=.01, beta1=.8), callbacks=[pm.callbacks.CheckParametersConvergence()]) trace = inference.approx.sample() posterior = { k: trace[k] for k in trace.varnames if not k.endswith('__') } posterior['ELBO'] = inference.hist if batch == False: f = open( 'posterior_dir_{}_{}_{}.pkl'.format( filename.split('.')[0], c, normalize), 'wb') else: f = open( 'posterior_dir_{}_{}_{}_holdout_{}.pkl'.format( filename.split('.')[0], c, normalize, batch), 'wb') pkl.dump(posterior, f) f.close()
def marginal_likelihood(self, name, X, Xu, y, sigma, is_observed=True, **kwargs): R""" Returns the approximate marginal likelihood distribution, given the input locations `X`, inducing point locations `Xu`, data `y`, and white noise standard deviations `sigma`. Parameters ---------- name : string Name of the random variable X : array-like Function input values. If one-dimensional, must be a column vector with shape `(n, 1)`. Xu: array-like The inducing points. Must have the same number of columns as `X`. y : array-like Data that is the sum of the function with the GP prior and Gaussian noise. Must have shape `(n, )`. sigma : scalar, Variable Standard deviation of the Gaussian noise. is_observed : bool Whether to set `y` as an `observed` variable in the `model`. Default is `True`. **kwargs Extra keyword arguments that are passed to `MvNormal` distribution constructor. """ self.X = X self.Xu = Xu self.y = y self.sigma = sigma logp = lambda y: self._build_marginal_likelihood_logp(X, Xu, y, sigma) if is_observed: return pm.DensityDist(name, logp, observed=y, **kwargs) else: shape = infer_shape(X, kwargs.pop("shape", None)) return pm.DensityDist(name, logp, shape=shape, **kwargs)
def check_model_samplability(self): model = pm.Model() with model: normal_dist = pm.Normal.dist() density_dist = pm.DensityDist('density_dist', normal_dist.logp, random=normal_dist.random) step = pm.Metropolis() trace = pm.sample(100, step, tuning=0) try: ppc = pm.sample_ppc(trace, samples=500, model=model, size=100) if len(ppc) == 0: npt.assert_true(len(ppc) == 0, 'length of ppc sample is zero') except: assert False
def test_spawn_densitydist_bound_method(): with pm.Model() as model: mu = pm.Normal("mu", 0, 1) normal_dist = pm.Normal.dist(mu, 1) obs = pm.DensityDist("density_dist", normal_dist.logp, observed=np.random.randn(100)) msg = "logp for DensityDist is a bound method, leading to RecursionError while serializing" with pytest.raises(ValueError, match=msg): trace = pm.sample(draws=10, tune=10, step=pm.Metropolis(), cores=2, mp_ctx="spawn")
def main(): if len(sys.argv) < 2 or len(sys.argv) > 3: print( 'usage: python3 inference_dir.py [chain no] [optional output no]') sys.exit() elif len(sys.argv) == 2: c = int(sys.argv[1]) d = int(sys.argv[1]) if len(sys.argv) == 3: c = int(sys.argv[1]) d = int(sys.argv[2]) np.random.seed(c) np.random.shuffle(lang_ind) np.random.shuffle(sound_ind) lang_minibatch = pm.Minibatch(lang_ind, 500) sound_minibatch = pm.Minibatch(sound_ind, 500) model_dir = pm.Model() with model_dir: beta = pm.HalfFlat('beta') "theta = language-level prior over components" theta = tt.stack([ pm.Dirichlet('theta_{}'.format(l), a=tt.ones(K) * beta, shape=K) for l in range(L) ]) phi = tt.stack([ tt.concatenate([ pm.Dirichlet('phi_{}_{}'.format(k, x), a=tt.ones(R[x]) * alpha, shape=R[x]) for x in range(X) ]) for k in range(K) ]) target = pm.DensityDist('target', logprob(theta=theta, phi=phi), observed=dict(lang_array=lang_minibatch, sound_array=sound_minibatch), total_size=N) inference_dir = pm.ADVI() inference_dir.fit( 50000, obj_optimizer=pm.adam(learning_rate=.01, beta1=uniform(.7, .9)), callbacks=[pm.callbacks.CheckParametersConvergence()]) trace_dir = inference_dir.approx.sample() posterior = { k: trace_dir[k] for k in trace_dir.varnames if not k.endswith('__') } posterior['ELBO'] = inference_dir.hist f = open('posterior_dir_shuffle_{}.pkl'.format(d), 'wb') pkl.dump(posterior, f) f.close()
def gev0_shift_2(dataset): locm = dataset.mean() locs = dataset.std() / (np.sqrt(len(dataset))) scalem = dataset.std() scales = dataset.std() / (np.sqrt(2 * (len(dataset) - 1))) with pm.Model() as model: # Priors for unknown model parameters c1 = pm.Beta( 'c1', alpha=6, beta=9 ) # c=x-0,5: transformation in gev_logp is required due to Beta domain between 0 and 1 loc1 = pm.Normal('loc1', mu=locm, sd=locs) scale1 = pm.Normal('scale1', mu=scalem, sd=scales) c2 = pm.Beta('c2', alpha=6, beta=9) loc2 = pm.Normal('loc2', mu=locm, sd=locs) scale2 = pm.Normal('scale2', mu=scalem, sd=scales) c3 = pm.Beta('c3', alpha=6, beta=9) loc3 = pm.Normal('loc3', mu=locm, sd=locs) scale3 = pm.Normal('scale3', mu=scalem, sd=scales) def gev_logp(value): scaled = (value - loc_) / scale_ logp = -(tt.log(scale_) + (((c_ - 0.5) + 1) / (c_ - 0.5) * tt.log1p( (c_ - 0.5) * scaled) + (1 + (c_ - 0.5) * scaled)**(-1 / (c_ - 0.5)))) bound1 = loc_ - scale_ / (c_ - 0.5) bounds = tt.switch((c_ - 0.5) > 0, value > bound1, value < bound1) return bound(logp, bounds, c_ != 0) tau1 = pm.DiscreteUniform("tau1", lower=0, upper=n_count_data - 2) tau2 = pm.DiscreteUniform("tau2", lower=tau1 + 1, upper=n_count_data - 1) idx = np.arange(n_count_data) c_ = pm.math.switch(tau2 >= idx, pm.math.switch(tau1 >= idx, c1, c2), c3) loc_ = pm.math.switch(tau2 >= idx, pm.math.switch(tau1 >= idx, loc1, loc2), loc3) scale_ = pm.math.switch(tau2 >= idx, pm.math.switch(tau1 >= idx, scale1, scale2), scale3) gev = pm.DensityDist('gev', gev_logp, observed=dataset) trace = pm.sample(2000, chains=1, progressbar=True) posterior = pm.trace_to_dataframe(trace) summary = pm.summary(trace) # geweke_plot = pm.geweke(trace, 0.05, 0.5, 20) return summary, posterior
def full_okada_calculation(params, GPSObject): def full_loglike(theta, x, data, sigma): """ Define a Gaussian log-likelihood function for a model with parameters theta. Some of these parameters might be floats, or tt.dvectors. """ # In FULL mode, all 9 varaibles are inverted. strike = theta[0] dip = theta[1] rake = theta[2] dx = theta[3] dy = theta[4] dz = theta[5] length = theta[6] width = theta[7] Mag = theta[8] # These model parameters are specific for the SPARSE case. model = okada_class.calc_gps_disp_vector(strike, dip, rake, dx, dy, dz, Mag, length, width, params.mu, params.alpha, x) return -(0.5 / sigma**2) * np.sum((data - model)**2) # create our Op using the loglike function we just defined. logl = okada_class.LogLike(full_loglike, GPSObject.gps_obs_vector, GPSObject.gps_xy_vector, params.data_sigma) # The actual Bayesian inference for model parameters. with pm.Model() as model: # Getting variables ready. Constants are defined in sparse_loglike. theta = tt.as_tensor_variable([ params.strike.gen(), params.dip.gen(), params.rake.gen(), params.dx.gen(), params.dy.gen(), params.dz.gen(), params.length.gen(), params.width.gen(), params.Mag.gen() ]) # Use a DensityDist (use a lamdba function to "call" the Op). Sample dist. pm.DensityDist('likelihood', lambda v: logl(v), observed={'v': theta}) trace = pm.sample(params.num_iter, tune=params.burn_in) return trace
def check_scipy_distributions(self): model = pm.Model() with model: norm_dist_logp = st.norm.logpdf norm_dist_random = np.random.normal density_dist = pm.DensityDist('density_dist', normal_dist_logp, random=normal_dist_random) step = pm.Metropolis() trace = pm.sample(100, step, tuning=0) try: ppc = pm.sample_ppc(trace, samples=500, model=model, size=100) if len(ppc) == 0: npt.assert_true(len(ppc) == 0, 'length of ppc sample is zero') except: assert False
def test_spawn_densitydist_function(): with pm.Model() as model: mu = pm.Normal("mu", 0, 1) def func(x): return -2 * (x**2).sum() obs = pm.DensityDist("density_dist", func, observed=np.random.randn(100)) trace = pm.sample(draws=10, tune=10, step=pm.Metropolis(), cores=2, mp_ctx="spawn")
def build_model(): # data failure = np.array([0.0, 1.0]) value = np.array([1.0, 0.0]) # model with pm.Model() as model: lam = pm.Exponential("lam", 1.0) pm.DensityDist("x", logp, observed={ "failure": failure, "lam": lam, "value": value }) return model
def test_density_dist_with_random_sampleable(self, shape): with pm.Model() as model: mu = pm.Normal('mu', 0, 1) normal_dist = pm.Normal.dist(mu, 1, shape=shape) obs = pm.DensityDist( 'density_dist', normal_dist.logp, observed=np.random.randn(100, *shape), shape=shape, random=normal_dist.random) trace = pm.sample(100) samples = 500 size = 100 ppc = pm.sample_posterior_predictive(trace, samples=samples, model=model, size=size) assert ppc['density_dist'].shape == (samples, size) + obs.distribution.shape
def test_multiple_observed_rv_without_observations(self): with pm.Model(): mu = pm.Normal("mu") x = pm.DensityDist( # pylint: disable=unused-variable "x", logpt(pm.Normal.dist(mu, 1.0)), observed={"value": 0.1} ) inference_data = pm.sample(100, chains=2, return_inferencedata=True) test_dict = { "posterior": ["mu"], "sample_stats": ["lp"], "log_likelihood": ["x"], "observed_data": ["value", "~x"], } fails = check_multiple_attrs(test_dict, inference_data) assert not fails assert inference_data.observed_data.value.dtype.kind == "f"
def fit_logreturns(self, data): def likelihood(x): def _normal(x, sigma): # assumes a mu of 0 return pm.Normal.dist(mu=0., sd=sigma).logp(x) nu_t = pm.math.dot(rhos, x[1:]) err = tt.reshape(x[0] - nu_t, [-1]) logps = (w[0] * pm.math.exp(_normal(err, pm.math.exp(s)))) + (w[1] * pm.math.exp(_normal(x[0], float(1e-100)))) return pm.math.log(logps) with pm.Model() as self.model: W = np.array([1., 1.]) w = pm.Dirichlet('w', W) intercept = pm.Normal('intercept', mu=-5, sd=5., testval=-5.) theta = pm.Uniform('theta', lower=0.001, upper=1.) sigma = pm.Uniform('sigma', lower=0.001, upper=10.) rhos = pm.Uniform('rhos', lower=-1., upper=1., shape=self.num_lags) sde = lambda x, theta, mu: (theta * (mu-x), sigma) s = ts.EulerMaruyama('path', 1.0, sde, [theta, intercept], shape=len(data) - self.num_lags, testval=np.ones_like(data[self.num_lags:])) lagged_data = self._lags(data) pm.DensityDist('obs', likelihood, observed=lagged_data) self.trace = pm.sample(3000, tune=3000, nuts_kwargs=dict(target_accept=0.95)) pm.traceplot(self.trace, varnames=[w, intercept, rhos, theta, sigma]) self.estimated_rhos = np.mean(self.trace['rhos'], axis=0) self.estimated_w = np.mean(self.trace['w'], axis=0) self.estimated_intercept = np.mean(self.trace['intercept'], axis=0) self.estimated_theta = np.mean(self.trace['theta'], axis=0) self.estimated_sigma = np.mean(self.trace['sigma'], axis=0) self.data = data
def sample(self, n_samples: int, beta: float = 1.): problem = self.problem log_post_fun = TheanoLogProbability(problem, beta) trace = self.trace x0 = None if self.x0 is not None: x0 = { x_name: val for x_name, val in zip(self.problem.x_names, self.x0) } # create model context with pm.Model() as model: # uniform bounds k = [ pm.Uniform(x_name, lower=lb, upper=ub) for x_name, lb, ub in zip( problem.get_reduced_vector(problem.x_names), problem.lb, problem.ub) ] # convert to tensor vector theta = tt.as_tensor_variable(k) # use a DensityDist for the log-posterior pm.DensityDist('log_post', logp=lambda v: log_post_fun(v), observed={'v': theta}) # step, by default automatically determined by pymc3 step = None if self.step_function: step = self.step_function() # perform the actual sampling trace = pm.sample(draws=int(n_samples), trace=trace, start=x0, step=step, **self.options) # convert trace to inference data object data = az.from_pymc3(trace=trace, model=model) self.trace = trace self.data = data