def doMCMC(n, nxx, nxy, nyy, x): # Optional setting for reproducibility use_seed = False d = nxx.shape[0] ns = 2000 if use_seed: # optional setting for reproducibility seed = 42 # Disable printing sys.stdout = open(os.devnull, 'w') # Sufficient statistics NXX = shared(nxx) NXY = shared(nxy) NYY = shared(nyy) # Define model and perform MCMC sampling with Model() as model: # Fixed hyperparameters for priors b0 = Deterministic('b0', th.zeros((d), dtype='float64')) ide = Deterministic('ide', th.eye(d, m=d, k=0, dtype='float64')) # Priors for parameters l0 = Gamma('l0', alpha=2.0, beta=2.0) l = Gamma('l', alpha=2.0, beta=2.0) b = MvNormal('b', mu=b0, tau=l0 * ide, shape=d) # Custom log likelihood def logp(xtx, xty, yty): return (n / 2.0) * th.log(l / (2 * np.pi)) + (-l / 2.0) * ( th.dot(th.dot(b, xtx), b) - 2 * th.dot(b, xty) + yty) # Likelihood delta = DensityDist('delta', logp, observed={ 'xtx': NXX, 'xty': NXY, 'yty': NYY }) # Inference print('doMCMC: start NUTS') step = NUTS() if use_seed: trace = sample(ns, step, progressbar=True, random_seed=seed) else: trace = sample(ns, step, progressbar=True) # Enable printing sys.stdout = sys.__stdout__ # Compute prediction over posterior return np.mean([np.dot(x, trace['b'][i]) for i in range(ns)], 0)
def doADVI(n, xx, xy, yy, x): d = xx.shape[0] ns = 5000 seed = 42 # for reproducibility # Disable printing sys.stdout = open(os.devnull, 'w') # Sufficient statistics NXX = shared(xx) NXY = shared(xy) NYY = shared(yy) # Define model and perform MCMC sampling with Model() as model: # Fixed hyperparameters for priors b0 = Deterministic('b0', th.zeros((d), dtype='float64')) ide = Deterministic('ide', th.eye(d, m=d, k=0, dtype='float64')) # Priors for parameters l0 = Gamma('l0', alpha=2.0, beta=2.0) l = Gamma('l', alpha=2.0, beta=2.0) b = MvNormal('b', mu=b0, tau=l0 * ide, shape=d) # Custom log likelihood def logp(xtx, xty, yty): return (n / 2.0) * th.log(l / (2 * np.pi)) + (-l / 2.0) * ( th.dot(th.dot(b, xtx), b) - 2 * th.dot(b, xty) + yty) # Likelihood delta = DensityDist('delta', logp, observed={ 'xtx': NXX, 'xty': NXY, 'yty': NYY }) # Inference v_params = advi(n=ns, random_seed=seed) trace = sample_vp(v_params, draws=ns, random_seed=seed) # Enable printing sys.stdout = sys.__stdout__ # Compute prediction over posterior return np.mean([np.dot(x, trace['b'][i]) for i in range(ns)], 0)
def __init__(self, ploidy_config: PloidyModelConfig, ploidy_workspace: PloidyWorkspace): super().__init__() # shorthands t_j = ploidy_workspace.t_j contig_exclusion_mask_jj = ploidy_workspace.contig_exclusion_mask_jj n_s = ploidy_workspace.n_s n_sj = ploidy_workspace.n_sj ploidy_k = ploidy_workspace.int_ploidy_values_k q_ploidy_sjk = tt.exp(ploidy_workspace.log_q_ploidy_sjk) eps_mapping = ploidy_config.mapping_error_rate register_as_global = self.register_as_global register_as_sample_specific = self.register_as_sample_specific # mean per-contig bias mean_bias_j = self.PositiveNormal('mean_bias_j', mu=1.0, sd=ploidy_config.mean_bias_sd, shape=(ploidy_workspace.num_contigs,)) register_as_global(mean_bias_j) # contig coverage unexplained variance psi_j = Exponential(name='psi_j', lam=1.0 / ploidy_config.psi_j_scale, shape=(ploidy_workspace.num_contigs,)) register_as_global(psi_j) # sample-specific contig unexplained variance psi_s = Exponential(name='psi_s', lam=1.0 / ploidy_config.psi_s_scale, shape=(ploidy_workspace.num_samples,)) register_as_sample_specific(psi_s, sample_axis=0) # convert "unexplained variance" to negative binomial over-dispersion alpha_sj = tt.maximum(tt.inv((tt.exp(psi_j.dimshuffle('x', 0) + psi_s.dimshuffle(0, 'x')) - 1.0)), _eps) # mean ploidy per contig per sample mean_ploidy_sj = tt.sum(tt.exp(ploidy_workspace.log_q_ploidy_sjk) * ploidy_workspace.int_ploidy_values_k.dimshuffle('x', 'x', 0), axis=2) # mean-field amplification coefficient per contig gamma_sj = mean_ploidy_sj * t_j.dimshuffle('x', 0) * mean_bias_j.dimshuffle('x', 0) # gamma_rest_sj \equiv sum_{j' \neq j} gamma_sj gamma_rest_sj = tt.dot(gamma_sj, contig_exclusion_mask_jj) # NB per-contig counts mu_num_sjk = (t_j.dimshuffle('x', 0, 'x') * mean_bias_j.dimshuffle('x', 0, 'x') * ploidy_k.dimshuffle('x', 'x', 0)) mu_den_sjk = gamma_rest_sj.dimshuffle(0, 1, 'x') + mu_num_sjk eps_mapping_j = eps_mapping * t_j / tt.sum(t_j) # average number of reads erroneously mapped to contig j # the switch is required for a single contig edge case mu_ratio_sjk = tt.switch(tt.eq(mu_den_sjk, 0.0), 0.0, mu_num_sjk / mu_den_sjk) mu_sjk = ((1.0 - eps_mapping) * mu_ratio_sjk + eps_mapping_j.dimshuffle('x', 0, 'x')) * n_s.dimshuffle(0, 'x', 'x') def _get_logp_sjk(_n_sj): _logp_sjk = commons.negative_binomial_logp( mu_sjk, # mean alpha_sj.dimshuffle(0, 1, 'x'), # over-dispersion _n_sj.dimshuffle(0, 1, 'x')) # contig counts return _logp_sjk DensityDist(name='n_sj_obs', logp=lambda _n_sj: tt.sum(q_ploidy_sjk * _get_logp_sjk(_n_sj)), observed=n_sj) # for log ploidy emission sampling Deterministic(name='logp_sjk', var=_get_logp_sjk(n_sj))
def get_mixbml_model(xs, hparams, verbose=0): u"""Returns a PyMC3 probabilistic model of mixture BML. This function should be invoked within a Model session of PyMC3. :param xs: Observation data. :type xs: ndarray, shape=(n_samples, 2), dtype=float :param hparams: Hyperparameters for inference. :type hparams: MixBMLParams :return: Probabilistic model :rtype: pymc3.Model """ # Standardize samples floatX = 'float32' # TODO: remove literal n_samples = xs.shape[0] xs = xs.astype(floatX) xs = standardize_samples(xs, True) if hparams.standardize else xs # Common scaling parameters std_x = np.std(xs, axis=0).astype(floatX) max_c = 1.0 # TODO: remove literal tau_cmmn = np.array([(std_x[0] * max_c)**2, (std_x[1] * max_c)**2]).astype(floatX) # Prior of individual specific effects (\tilde{\mu}_{l}^{(i)}) L_cov = _get_L_cov(hparams) mu1s, mu2s = _indvdl_t(hparams, std_x, n_samples, L_cov) # Noise variance h1, h2 = _noise_variance(hparams, tau_cmmn) # Common interceptions mu1, mu2 = _common_interceptions(hparams, tau_cmmn) # Noise model # obs1 (obs2) is a log likelihood function, not RV obs1, obs2 = _noise_model(hparams, h1, h2) # Pair of causal models v1_params = [mu1, mu1s, obs1] v2_params = [mu2, mu2s, obs2] # lp_m1: x1 -> x2 (b_21 is non-zero) # lp_m2: x2 -> x1 (b_12 is non-zero) lp_m1 = _causal_model(hparams, v1_params, v2_params, tau_cmmn, '21') lp_m2 = _causal_model(hparams, v2_params, v1_params, tau_cmmn, '12') # Prior of mixing proportions for causal models z = Beta('z', alpha=1, beta=1) # Mixture of potentials of causal models def lp_mix(xs): def flip(xs): # Filp 1st and 2nd features return tt.stack([xs[:, 1], xs[:, 0]], axis=0).T return pm.logsumexp( tt.stack([tt.log(z) + lp_m1(xs), tt.log(1 - z) + lp_m2(flip(xs))], axis=0)) DensityDist('dist', lp_mix, observed=xs)
def get_full_bayes_bml_model(xs, hparams, use_wbic=False): u"""Returns a PyMC3 probablistic model of full bayes version of BMLiNGAM model. This function should be invoked within a Model context of PyMC3. :param xs: Observation data. :type xs: numpy.ndarray, shape=(n_sample, 2), dtype=float :param hparams: Hyperparameters for inference :param bool use_wbic: When you use WBIC as an information criteria, set this flag :code:`True`. Estimation of WBIC needs posterior sample on special inverse temperature setting. :return: Probablistic model :rtype: pymc3.Model """ # Standardize samples floatX = 'float32' n_samples = xs.shape[0] xs = xs.astype(floatX) xs = standardize_samples(xs, True) if hparams.standardize else xs # Common scaling parameters std_x = np.std(xs, axis=0).astype(floatX) max_c = 1.0 tau_cmmn = np.array([(std_x[0] * max_c)**2, (std_x[1] * max_c)**2]).astype(floatX) # Prior of individual specific effects (\tilde{\mu}_{l}^{(i)}) L_cov = _get_L_cov(hparams) mu1s, mu2s = _indvdl_t(hparams, std_x, n_samples, L_cov) # Noise variance h1, h2 = _noise_variance(hparams, tau_cmmn) # Common interceptions mu1, mu2 = _common_interceptions(hparams, tau_cmmn) # Noise model obs1, obs2 = _noise_model(hparams, h1, h2) # Pair of causal models v1_params = [mu1, mu1s, obs1] v2_params = [mu2, mu2s, obs2] lp_m1 = _causal_model(hparams, v1_params, v2_params, tau_cmmn, '21') lp_m2 = _causal_model(hparams, v2_params, v1_params, tau_cmmn, '12') def lp_m2_flipped(xs): def flip(xs): # Filp 1st and 2nd features return tt.stack([xs[:, 1], xs[:, 0]], axis=0).T return lp_m2(flip(xs)) # lp_m1: x1 -> x2 (b_21 is non-zero) # lp_m2_flipped: x2 -> x1 (b_12 is non-zero) if hparams.forward: lp = _inverse_temperature(lp_m1, n_samples) if use_wbic else lp_m1 DensityDist('dist', lp, observed=xs) else: lp = _inverse_temperature(lp_m2_flipped, n_samples) if use_wbic else lp_m2_flipped DensityDist('dist', lp, observed=xs)
tt.reshape(tt.tile(sigmas_background, n_components), (n_components, n_dimensions)), 0) + tt.eye(n_components, n_dimensions) * sigmas_signal covs = [ tt.zeros((n_dimensions, n_dimensions)) + tt.eye(n_dimensions, n_dimensions) * sigmas[i, :] for i in range(n_components) ] taus = [ tt.nlinalg.matrix_inverse(covs[i])**2 for i in range(n_components) ] # Gaussian Mixture Model: x = DensityDist('x', logp_gmix(mus, w, taus, n_components), observed=pm.floatX(data)) with model: advi_fit = pm.fit(n=100000, obj_optimizer=pm.adagrad(learning_rate=0.01)) advi_trace = advi_fit.sample(10000) advi_summary = pm.summary(advi_trace, include_transformed=False) pickle_out = open( "advi_summaries/advi_summary_slide" + str(slide) + 'hemisphere_' + str(hemisphere) + ".pickle", "wb") pickle.dump(advi_summary, pickle_out) pickle_out.close()
from pymc3 import NUTS, sample, df_summary, summary, Metropolis with sedmodel: tp = 35.+15.*Normal('tp', 0., 0.5) #temp = 35.+15.*Uniform('temp', lower=-1, upper=1) #alpha = 3.45+0.75*Uniform('alpha', lower=-1, upper=1) plnorm = 0.3+0.2*Normal('plnorm', 0., 0.5) #src.sed.setBB(temp=temp) src.sed.setPL(turnover=tp,plnorm=plnorm) modflux = pho.getFlux(src) def logp(obs): return -0.5*((modflux-obs)/sigma)**2. Y_obs = DensityDist('Y_obs', logp, observed=Y) trace = sample(1000, n_init=50000) # obtain starting values via MAP #start = find_MAP(fmin=optimize.fmin_powell) # instantiate sampler #step = NUTS(scaling=start) # draw 2000 posterior samples #trace = sample(5000, step, start=start) out = np.array([35.+15.*trace['tp'], 0.3+0.2*trace['plnorm']]) import corner print df_summary(trace)
def logp_gmix(mus, pi, taus, n_components): def logp_(value): logps = [tt.log(pi[i]) + logp_normal(mus[i,:], taus[i], value) for i in range(n_components)] return tt.sum(logsumexp(tt.stacklists(logps)[:, :n_samples], axis=0)) return logp_ ## Prior for model: componentMean = ms + np.random.uniform(0,5,n_dimensions) componentTau = np.random.uniform(0,2,n_dimensions) * np.eye(n_dimensions) with pm.Model() as model: mus = MvNormal('mu', mu=pm.floatX(componentMean), tau=pm.floatX(componentTau), shape=(n_components, n_dimensions)) pi = Dirichlet('pi', a=pm.floatX(0.1 * np.ones(n_components)), shape=(n_components,)) packed_L = [pm.LKJCholeskyCov('packed_L_%d' % i, n=n_dimensions, eta=2., sd_dist=pm.HalfCauchy.dist(2.5)) for i in range(n_components)] L = [pm.expand_packed_triangular(n_dimensions, packed_L[i]) for i in range(n_components)] sigmas = [pm.Deterministic('sigma_%d' % i, tt.dot(L[i],L[i].T)) for i in range(n_components)] taus = [tt.nlinalg.matrix_inverse(sigmas[i]) for i in range(n_components)] xs = DensityDist('x', logp_gmix(mus, pi, taus, n_components), observed=data) with model: advi_fit = pm.fit(n=500000, obj_optimizer=pm.adagrad(learning_rate=1e-1)) advi_trace = advi_fit.sample(10000) advi_summary = pm.summary(advi_trace) pickle_out = open("advi_summary.pickle","wb") pickle.dump(advi_summary, pickle_out) pickle_out.close()
# define model mixture log-likelihood def logp_mix(mf): def logp_(value): logps = tt.log(mf) + value return tt.sum(logsumexp(logps, axis=1)) return logp_ # define and fit the probabilistic model with Model() as model: tau = HalfCauchy('tau', beta = 1.) mf = Dirichlet('mf', a = tt.ones(M)/tau, shape=(M,)) xs = DensityDist('logml', logp_mix(mf), observed=LME) with model: approx = fit(method='advi', n = 10000) trace = approx.sample(nsample) traceplot(trace); #compute exceedance probability ep, _ = np.histogram(trace['mf'].argmax(axis = 1), bins = M) ep = pd.DataFrame({'ep':ep/nsample, 'models': cols}) fig = plt.figure(figsize = (10,5)) ax1 = plt.subplot(121) ax2 = plt.subplot(122)
def run_normal_mv_model_mixture_DIY(data, K=3, mus=None, mc_samples=10000, jobs=1, n_cols=10, n_rows=100, neigs=1): def logp_simple(mus, category, aux3): def logp_(value): spatial_factor = 0.00 aux = tt.ones((n_samples, )) logps = tt.zeros((n_samples)) sumlogps = tt.zeros((K, n_samples)) pi = tt.sum(tt.eq(aux3, (aux * category).reshape((n_samples, 1))), axis=1) / 8.0 #TODO son logps y sumlops siempre sustituidos en todos lo valortes for i, label in enumerate(range(K)): pi_l = tt.sum(tt.eq(aux3, (aux * label).reshape( (n_samples, 1))), axis=1) / 8.0 sumlogps = tt.set_subtensor(sumlogps[i, :], (mus[label].logp(value)) + (pi_l - 1) * spatial_factor) sumlogps = tt.sum(sumlogps, axis=0) for label in range(K): indx = tt.eq(category, tt.as_tensor_variable(label)).nonzero() logps = tt.set_subtensor( logps[indx], (mus[label].logp(value)[indx]) + (pi[indx] - 1) * spatial_factor - sumlogps[indx]) return logps return logp_ #K = 3 n_samples, n_feats = data.shape n_samples = n_cols * n_rows max_neigs = 4 * neigs * (neigs + 1) #print max_neigs to_fill = indxs_neigs(range(n_samples), n_cols=n_cols, n_rows=n_rows, n=neigs) inds = np.where(to_fill != -1)[0] to_fill = to_fill[to_fill != -1] aux = tt.ones(n_samples * max_neigs) * -69 shp = (K, n_feats) mus_start = np.percentile(data, np.linspace(1, 100, K), axis=0) alpha = 0.1 * np.ones((n_samples, K)) with pm.Model() as model: packed_L = [ pm.LKJCholeskyCov('packed_L_%d' % i, n=n_feats, eta=2., sd_dist=pm.HalfCauchy.dist(2.5)) for i in range(K) ] L = [ pm.expand_packed_triangular(n_feats, packed_L[i]) for i in range(K) ] #sigma = pm.Deterministic('Sigma', L.dot(L.T)) mus = 0. if mus is None else mus #sds = pm.Uniform('sds',lower=0., upper=150., shape = shp ) mus = pm.Normal('mus', mu=100., sd=1, shape=shp) pi = Dirichlet('pi', a=alpha, shape=(n_samples, K)) category = pm.Categorical('category', p=pi, shape=n_samples) shit_max = pm.Deterministic('shit_max', tt.max(category)) shit_min = pm.Deterministic('shit_min', tt.min(category)) #mvs = [MvNormal('mu_%d' % i, mu=mus[i],tau=pm.floatX(1. * np.eye(n_feats)),shape=(n_feats,)) for i in range(K)] mvs = [pm.MvNormal.dist(mu=mus[i], chol=L[i]) for i in range(K)] aux2 = tt.set_subtensor(aux[inds], category[to_fill]) xs = DensityDist('x', logp_simple(mvs, category, aux2.reshape((n_samples, max_neigs))), observed=data) with model: step2 = step2 = pm.ElemwiseCategorical(vars=[category], values=range(K)) trace = sample(mc_samples, step=step2, tune=1000, chains=4) pm.traceplot(trace, varnames=['mus', 'sds']) plt.title('logp_sum_mo_alpha_700_tunes_spatial_2') mod = stats.mode(trace['category'][int(mc_samples * 0.75):]) return model, mod, trace
def run_normal_mv_model_prior(data, K=3, mus=None, mc_samples=10000, jobs=1, n_cols=10, n_rows=100, neigs=1): n_samples, n_feats = data.shape n_samples = n_cols * n_rows max_neigs = 4 * neigs * (neigs + 1) #print max_neigs to_fill = indxs_neigs(range(n_samples), n_cols=n_cols, n_rows=n_rows, n=neigs) inds = np.where(to_fill != -1)[0] to_fill = to_fill[to_fill != -1] aux = tt.ones(n_samples * max_neigs) * -69 with pm.Model() as model: packed_L = pm.LKJCholeskyCov('packed_L', n=n_feats, eta=2., sd_dist=pm.HalfCauchy.dist(2.5)) L = pm.expand_packed_triangular(n_feats, packed_L) sigma = pm.Deterministic('Sigma', L.dot(L.T)) mus = 0. if mus is None else mus mus = pm.Normal('mus', mu=[[10, 10], [55, 55], [105, 105], [155, 155], [205, 205]], sd=10, shape=(K, n_feats)) #sds = pm.HalfNormal('sds',sd = 50, shape = (K,n_feats) ) #mus = pm.Normal('mus', mu = [10,55,105,155,205], sd = sds , shape=(K,n_feats) ) #nu = pm.Exponential('nu', 1./10, shape=(K,n_feats), testval=tt.ones((K,n_feats)) ) #mus = pm.StudentT('mus',nu=nu, mu = [[10],[55],[105],[155],[205]], sd = 100., shape=(K,n_feats)) pi = Dirichlet('pi', a=pm.floatX([1. for _ in range(K)]), shape=K) #TODO one pi per voxel category = pm.Categorical('category', p=pi, shape=n_samples) #pm.Deterministic('pri', tt.as_tensor_variable(get_prior2(category))) #prior = pm.Deterministic('prior',tt.stack( [tt.sum(tt.eq(category[i], category[indxs_neig(i, n_rows=73, n_cols=74)]))/8.0 for i in range(73*74) ] )) #prior = pm.Deterministic('prior',tt.sum(tt.eq(category , category[[j for j in range(8)]].reshape( (8,1) ) ))) aux2 = tt.set_subtensor(aux[inds], category[to_fill]) prior = pm.Deterministic( 'prior', (tt.sum(tt.eq(aux2.reshape( (n_samples, max_neigs)), category.reshape((n_samples, 1))), axis=1) + 0.0) / 8.0) #prior2 = pm.Normal('prior2', mu = prior, sd = 0.5, shape= n_samples) # aux3 = tt.as_tensor_variable(pm.floatX([1,1,2,2,2,2,2,2,2,2]*100 )) # aux3 = tt.set_subtensor( aux3[(tt.eq(category,1)).nonzero()], 2 ) # prior2 = pm.Deterministic('prior2', aux3 ) # xs = DensityDist('x', logp_gmix(mus[category], L, prior, category), observed=data) with model: step2 = pm.ElemwiseCategorical(vars=[category], values=range(K)) #step = pm.CategoricalGibbsMetropolis(vars = [prior] ) trace = sample(mc_samples, step=[step2], n_jobs=jobs, tune=600) pm.traceplot(trace, varnames=['mus', 'pi', 'Sigma']) plt.title('normal mv model 40 cols') mod = stats.mode(trace['category'][int(mc_samples * 0.75):]) #if chains > 1: # print (max(np.max(gr_stats) for gr_stats in pm.gelman_rubin(trace).values())) return model, mod, trace
shit_max = pm.Deterministic('shit_max', tt.max(category)) shit_min = pm.Deterministic('shit_min', tt.min(category)) pis_print = tt.printing.Print('pis')(pis) category_print = tt.printing.Print('category')(category) #mvs = [MvNormal('mu_%d' % i, mu=mus[i],tau=pm.floatX(1. * np.eye(n_feats)),shape=(n_feats,)) for i in range(K)] #mvs = [pm.MvNormal.dist(mu = mus[i], chol = L[i]) for i in range(K)] mvs = [ pm.MvNormal.dist(mu=mus[i], tau=np.eye(n_feats, dtype=np.float)) for i in range(K) ] aux2 = tt.set_subtensor(aux[inds], category[to_fill]) xs = DensityDist('x', logp_simple(mvs, category, aux2.reshape((n_samples, max_neigs))), observed=data) step2 = pm.ElemwiseCategorical(vars=[category], values=range(K)) mystep = pm.Metropolis(vars=[mus, sds]) trace = sample(10000, start=pm.find_MAP(), step=[mystep, step2], tune=3000, chains=1, discard_tuned_samples=True, exception_verbosity='high') pm.traceplot(trace, varnames=['mus', 'sds']) #plt.title('logp_sum_mo_alpha_700_tunes_spatial_2map')
plt.scatter(ms[0, 0], ms[0, 1], c='r', s=100) plt.scatter(ms[1, 0], ms[1, 1], c='b', s=100) from pymc3.math import logsumexp #Model original with pm.Model() as model: mus = [MvNormal('mu_%d' % i, mu=pm.floatX(np.zeros(2)), tau=pm.floatX(0.1 * np.eye(2)), shape=(2,)) for i in range(2)] pi = Dirichlet('pi', a=pm.floatX(0.1 * np.ones(2)), shape=(2,)) xs = DensityDist('x', logp_gmix(mus, pi, np.eye(2)), observed=data) # # #Model for GMM clustering # with pm.Model() as model: # # cluster sizes # p = pm.Dirichlet('p', a=np.array([1., 1.]), shape=2) # # ensure all clusters have some points # p_min_potential = pm.Potential('p_min_potential', tt.switch(tt.min(p) < .1, -np.inf, 0)) # # # # cluster centers # means = [MvNormal('mu_%d' % i,mu=pm.floatX(np.zeros(2)),tau=pm.floatX(0.1 * np.eye(2)),shape=(2,)) # for i in range(2)] # # break symmetry # order_means_potential = pm.Potential('order_means_potential',tt.switch(means[1]-means[0] < 0, -np.inf, 0))