def get_model2_trained(trace2, logDiff_obs=None, logPoff_obs=None): ''' return model2 trained based on trace2. If observed_t and/or observed_k are specified, return the model conditioned on those values ''' model2_trained = pm.Model() with model2_trained: ### model2 - LA (LCK activation) ########################### # random variables x and y rv_logDiff = pm.Uniform('rv_logDiff', -3, 0, observed=logDiff_obs) rv_logPoff = pm.Uniform('rv_logPoff', -5, 0, observed=logPoff_obs) # random variables rv_noise_lambdaALCK_LA02 = pm.HalfNormal('rv_noise_lambdaALCK_LA02', sd=trace2.rv_noise_lambdaALCK_LA02.mean()) # noise # Sigmoid params rv_min_lambdaALCK_LA02 = pm.TruncatedNormal('rv_min_lambdaALCK_LA02', mu = trace2.rv_min_lambdaALCK_LA02.mean(), sd = trace2.rv_min_lambdaALCK_LA02.std(), upper = 0.01) rv_max_lambdaALCK_LA02 = pm.TruncatedNormal('rv_max_lambdaALCK_LA02', mu = trace2.rv_max_lambdaALCK_LA02.mean(), sd = trace2.rv_max_lambdaALCK_LA02.std(), lower = 0.01) rv_center_logDiff_lambdaALCK_LA02 = pm.Normal('rv_center_logDiff_lambdaALCK_LA02', mu = trace2.rv_center_logDiff_lambdaALCK_LA02.mean(), sd = trace2.rv_center_logDiff_lambdaALCK_LA02.std()) rv_divisor_logDiff_lambdaALCK_LA02 = pm.TruncatedNormal('rv_divisor_logDiff_lambdaALCK_LA02', mu = trace2.rv_divisor_logDiff_lambdaALCK_LA02.mean(), sd = trace2.rv_divisor_logDiff_lambdaALCK_LA02.std(), upper = 0) rv_center_logPoff_lambdaALCK_LA02 = pm.Normal('rv_center_logPoff_lambdaALCK_LA02', mu=trace2.rv_center_logPoff_lambdaALCK_LA02.mean(), sd=trace2.rv_center_logPoff_lambdaALCK_LA02.std()) rv_divisor_logPoff_lambdaALCK_LA02 = pm.TruncatedNormal('rv_divisor_logPoff_lambdaALCK_LA02', mu = trace2.rv_divisor_logPoff_lambdaALCK_LA02.mean(), sd = trace2.rv_divisor_logPoff_lambdaALCK_LA02.std(), lower = 0) rv_tmp_x1 = (rv_logDiff - rv_center_logDiff_lambdaALCK_LA02)/\ rv_divisor_logDiff_lambdaALCK_LA02 rv_tmp_sig1 = 1.0 / (1 + np.exp(-rv_tmp_x1)) rv_tmp_x2 = (rv_logPoff - rv_center_logPoff_lambdaALCK_LA02)/\ rv_divisor_logPoff_lambdaALCK_LA02 rv_tmp_sig2 = 1.0 / (1 + np.exp(-rv_tmp_x2)) rv_lambdaALCK_LA02 = pm.Normal('rv_lambdaALCK_LA02', mu=rv_min_lambdaALCK_LA02 +\ (rv_max_lambdaALCK_LA02 - rv_min_lambdaALCK_LA02)*\ rv_tmp_sig1 * rv_tmp_sig2, sd=rv_noise_lambdaALCK_LA02) return model2_trained
def test_HSStep_unsupported(): np.random.seed(2032) M = 5 N = 50 X = np.random.normal(size=N * M).reshape((N, M)) beta_true = np.random.normal(10, size=M) y = np.random.normal(X.dot(beta_true), 1) with pm.Model(): beta = HorseShoe("beta", tau=1, shape=M) pm.TruncatedNormal("alpha", mu=beta.dot(X.T), sigma=1, observed=y) with pytest.raises(NotImplementedError): HSStep([beta]) with pm.Model(): beta = HorseShoe("beta", tau=1, shape=M) mu = pm.Deterministic("mu", beta.dot(X.T)) pm.TruncatedNormal("y", mu=mu, sigma=1, observed=y) with pytest.raises(NotImplementedError): HSStep([beta]) with pm.Model(): beta = HorseShoe("beta", tau=1, shape=M) mu = pm.Deterministic("mu", beta.dot(X.T)) pm.Normal("y", mu=mu, sigma=1, observed=y) beta_2 = HorseShoe("beta_2", tau=1, shape=M) with pytest.raises(ValueError): HSStep([beta, beta_2])
def ParamModel(param_name, Params_): # param = SearchParam(param_name, Params_) # prior_def = param[3] # prior_def, definition for the prior probability # # [ XA.PriorFunc_????, arg1, arg2, arg3, ... ] prior_type = prior_def[0] arg1 = prior_def[1] arg2 = prior_def[2] # # XA.PriorFunc_Unknown = -1 # XA.PriorFunc_Uniform = 0 # arg1 = lower, arg2 = upper # XA.PriorFunc_Norm = 1 # arg1 = mean, arg2 = sd # XA.PriorFunc_Gamma = 2 # arg1 = alpha, arg2 = beta # XA.PriorFunc_Beta = 3 # arg1 = alpha, arg2 = beta # XA.PriorFunc_TruncatedNorm = 4 # arg1 = mean, arg2 = sd, arg3 = lower, arg4 = upper # XA.PriorFunc_TruncatedNorm_sd_ratio = 5 # arg1 = mean, arg2 = sd, arg3 = ratio # # Making data for prior # if (prior_type == PriorFunc_Uniform): # return pm.Uniform(param_name, lower=arg1, upper=arg2) # elif (prior_type == PriorFunc_Norm): # return pm.Normal(param_name, mu=arg1, sd=arg2) # elif (prior_type == PriorFunc_Gamma): # return pm.Gamma(param_name, alpha=arg1, beta=arg2) # elif (prior_type == PriorFunc_Beta): # return pm.Beta(param_name, alpha=arg1, beta=arg2) # elif (prior_type == PriorFunc_TruncatedNorm): # arg3 = prior_def[3] arg4 = prior_def[4] # return pm.TruncatedNormal(param_name, mu=arg1, sd=arg2, lower=arg3, upper=arg4) # elif (prior_type == PriorFunc_TruncatedNorm_sd_ratio): # arg3 = prior_def[3] lower_ = arg1 - arg3 * arg2 upper_ = arg1 + arg3 * arg2 # return pm.TruncatedNormal(param_name, mu=arg1, sd=arg2, lower=lower_, upper=upper_)
def __init__(self, light_curve, rotation_period, n_spots, contrast, latitude_cutoff=10, partition_lon=True): pm.gp.mean.Mean.__init__(self) if contrast is None: contrast = pm.TruncatedNormal("contrast", lower=0.01, upper=0.99, testval=0.4, mu=0.5, sigma=0.5) self.f0 = pm.TruncatedNormal("f0", mu=1, sigma=1, testval=light_curve.flux.max(), lower=-1, upper=2) self.eq_period = pm.TruncatedNormal("P_eq", lower=0.8 * rotation_period, upper=1.2 * rotation_period, mu=rotation_period, sigma=0.2 * rotation_period, testval=rotation_period) BoundedHalfNormal = pm.Bound(pm.HalfNormal, lower=1e-6, upper=0.99) self.shear = BoundedHalfNormal("shear", sigma=0.2, testval=0.01) self.comp_inclination = pm.Uniform("comp_inc", lower=np.radians(0), upper=np.radians(90), testval=np.radians(1)) if partition_lon: lon_lims = 2 * np.pi * np.arange(n_spots + 1) / n_spots lower = lon_lims[:-1] upper = lon_lims[1:] else: lower = 0 upper = 2 * np.pi self.lon = pm.Uniform("lon", lower=lower, upper=upper, shape=(1, n_spots)) self.lat = pm.TruncatedNormal("lat", lower=np.radians(latitude_cutoff), upper=np.radians(180 - latitude_cutoff), mu=np.pi / 2, sigma=np.pi / 2, shape=(1, n_spots)) self.rspot = BoundedHalfNormal("R_spot", sigma=0.2, shape=(1, n_spots), testval=0.3) self.contrast = contrast self.spot_period = self.eq_period / (1 - self.shear * pm.math.sin(self.lat - np.pi / 2) ** 2) self.sin_lat = pm.math.sin(self.lat) self.cos_lat = pm.math.cos(self.lat) self.sin_c_inc = pm.math.sin(self.comp_inclination) self.cos_c_inc = pm.math.cos(self.comp_inclination)
def dummy_model_fit(): model = pm.Model(theano_config={'compute_test_value': 'ignore'}) with model: pm.TruncatedNormal('amplitude', ) alpha = pm.TruncatedNormal('alpha',) beta = pm.TruncatedNormal('beta', ) pm.Deterministic('mu_s', alpha + beta) # dummy function to load traces. pm.TruncatedNormal('mu_b', lower=0, shape=2, mu=[1, 2], sd=5) return model
def build_model(self, name='normal_model'): # Define Stochastic variables with pm.Model(name=name) as self.model: # Global mean pitch angle self.mu_phi = pm.Uniform('mu_phi', lower=0, upper=90) self.sigma_phi = pm.InverseGamma('sigma_phi', alpha=2, beta=15, testval=8) self.sigma_gal = pm.InverseGamma('sigma_gal', alpha=2, beta=15, testval=8) # define a mean galaxy pitch angle self.phi_gal = pm.TruncatedNormal( 'phi_gal', mu=self.mu_phi, sd=self.sigma_phi, lower=0, upper=90, shape=len(self.galaxies), ) # draw arm pitch angles centred around this mean self.phi_arm = pm.TruncatedNormal( 'phi_arm', mu=self.phi_gal[self.gal_arm_map], sd=self.sigma_gal, lower=0, upper=90, shape=len(self.gal_arm_map), ) # convert to a gradient for a linear fit self.b = tt.tan(np.pi / 180 * self.phi_arm) # arm offset parameter self.c = pm.Cauchy('c', alpha=0, beta=10, shape=self.n_arms, testval=np.tile(0, self.n_arms)) # radial noise self.sigma_r = pm.InverseGamma('sigma_r', alpha=2, beta=0.5) r = pm.Deterministic( 'r', tt.exp(self.b[self.point_arm_map] * self.data['theta'] + self.c[self.point_arm_map])) # likelihood function self.likelihood = pm.Normal( 'Likelihood', mu=r, sigma=self.sigma_r, observed=self.data['r'], )
def test_aesara_switch_broadcast_edge_cases(self): # Tests against two subtle issues related to a previous bug in Aesara where aet.switch would not # always broadcast tensors with single values https://github.com/pymc-devs/aesara/issues/270 # Known issue 1: https://github.com/pymc-devs/pymc3/issues/4389 data = np.zeros(10) with pm.Model() as m: p = pm.Beta("p", 1, 1) obs = pm.Bernoulli("obs", p=p, observed=data) # Assert logp is correct npt.assert_allclose( obs.logp(m.test_point), np.log(0.5) * 10, ) # Known issue 2: https://github.com/pymc-devs/pymc3/issues/4417 # fmt: off data = np.array([ 1.35202174, -0.83690274, 1.11175166, 1.29000367, 0.21282749, 0.84430966, 0.24841369, 0.81803141, 0.20550244, -0.45016253, ]) # fmt: on with pm.Model() as m: mu = pm.Normal("mu", 0, 5) obs = pm.TruncatedNormal("obs", mu=mu, sigma=1, lower=-1, upper=2, observed=data) # Assert dlogp is correct npt.assert_allclose(m.dlogp([mu])({"mu": 0}), 2.499424682024436, rtol=1e-5)
def make_model(nB,x,y,sigma_beta): mixture_model = pm.Model() with mixture_model: # Define common priors sigma = pm.HalfCauchy('sigma', beta=sigma_beta) #weight = [pm.Uniform('weight_%d' %i, lower=0.05, upper=1.5) for i in range(nB)] weight = [pm.TruncatedNormal('weight_%d' %i,mu=1.0/nB, sigma=0.25,lower=0.05,upper=1.5) for i in range(nB)] #loc = [pm.Uniform('loc_%d' %i,lower=0, upper=np.max(x)*1.0) for i in range(nB)] loc = [pm.TruncatedNormal('loc_%d' %i,mu=1.7, sigma=0.6,lower=0.8,upper=1.5*np.max(x)) for i in range(nB)] #scale = [pm.HalfCauchy('scale_%d' %i,beta=0.15,testval=0.5) for i in range(nB)] #scale = [pm.Uniform('scale_%d' %i,lower=0.08,upper=0.6) for i in range(nB)] scale = [pm.TruncatedNormal('scale_%d' %i,mu=0.3, sigma=0.15,lower=0.08,upper=0.6) for i in range(nB)] shape = [pm.TruncatedNormal('shape_%d' %i,mu=-0.35,sigma=0.25,lower=-1.0,upper=0.1) for i in range(nB)] likelihood = pm.Normal('y', mu = mix(x,loc,scale,shape,weight,nB), sigma=sigma, observed=y) return mixture_model
def build_model(self, name=''): # Define Stochastic variables with pm.Model(name=name) as self.model: # Global mean pitch angle self.phi_gal = pm.Uniform('phi_gal', lower=0, upper=90, shape=len(self.galaxies)) # note we don't model inter-galaxy dispersion here # intra-galaxy dispersion self.sigma_gal = pm.InverseGamma('sigma_gal', alpha=2, beta=20, testval=5) # arm offset parameter self.c = pm.Cauchy('c', alpha=0, beta=10, shape=self.n_arms, testval=np.tile(0, self.n_arms)) # radial noise self.sigma_r = pm.InverseGamma('sigma_r', alpha=2, beta=0.5) # define prior for Student T degrees of freedom # self.nu = pm.Uniform('nu', lower=1, upper=100) # Define Dependent variables self.phi_arm = pm.TruncatedNormal( 'phi_arm', mu=self.phi_gal[self.gal_arm_map], sd=self.sigma_gal, lower=0, upper=90, shape=self.n_arms) # convert to a gradient for a linear fit self.b = tt.tan(np.pi / 180 * self.phi_arm) r = pm.Deterministic( 'r', tt.exp(self.b[self.data['arm_index'].values] * self.data['theta'] + self.c[self.data['arm_index'].values])) # likelihood function self.likelihood = pm.StudentT( 'Likelihood', mu=r, sigma=self.sigma_r, nu=1, #self.nu, observed=self.data['r'], )
def test_aesara_switch_broadcast_edge_cases_2(self): # Known issue 2: https://github.com/pymc-devs/pymc3/issues/4417 # fmt: off data = np.array([ 1.35202174, -0.83690274, 1.11175166, 1.29000367, 0.21282749, 0.84430966, 0.24841369, 0.81803141, 0.20550244, -0.45016253, ]) # fmt: on with pm.Model() as m: mu = pm.Normal("mu", 0, 5) obs = pm.TruncatedNormal("obs", mu=mu, sigma=1, lower=-1, upper=2, observed=data) npt.assert_allclose(m.dlogp([mu])({"mu": 0}), 2.499424682024436, rtol=1e-5)
def build_model(self, name=''): # Define Stochastic variables with pm.Model(name=name) as self.model: # Global mean pitch angle self.phi_gal = pm.Uniform('phi_gal', lower=0, upper=90, shape=len(self.galaxies)) # note we don't model inter-galaxy dispersion here # intra-galaxy dispersion self.sigma_gal = pm.InverseGamma('sigma_gal', alpha=2, beta=20, testval=5) # arm offset parameter self.c = pm.Cauchy('c', alpha=0, beta=10, shape=self.n_arms, testval=np.tile(0, self.n_arms)) # radial noise self.sigma_r = pm.InverseGamma('sigma_r', alpha=2, beta=0.5) # ----- Define Dependent variables ----- # Phi arm is drawn from a truncated normal centred on phi_gal with # spread sigma_gal gal_idx = self.gal_arm_map.astype('int32') self.phi_arm = pm.TruncatedNormal('phi_arm', mu=self.phi_gal[gal_idx], sd=self.sigma_gal, lower=0, upper=90, shape=self.n_arms) # transform to gradient for fitting self.b = tt.tan(np.pi / 180 * self.phi_arm) # r = exp(theta * tan(phi) + c) # do not track this as it uses a lot of memory arm_idx = self.data['arm_index'].values.astype('int32') r = tt.exp(self.b[arm_idx] * self.data['theta'] + self.c[arm_idx]) # likelihood function (assume likelihood here) self.likelihood = pm.Normal( 'Likelihood', mu=r, sigma=self.sigma_r, observed=self.data['r'], )
def threepl_model(dataset): """Defines the mcmc model for three parameter logistic estimation. Args: dataset: [n_items, n_participants] 2d array of measured responses Returns: model: PyMC3 model to run """ n_items, n_people = dataset.shape observed = dataset.astype('int') threepl_pymc_model = pm.Model() with threepl_pymc_model: # Ability Parameters (Standardized Normal) ability = pm.Normal("Ability", mu=0, sigma=1, shape=n_people) # Difficuly multilevel prior sigma_difficulty = pm.HalfNormal('Difficulty_SD', sigma=1, shape=1) difficulty = pm.Normal("Difficulty", mu=0, sigma=sigma_difficulty, shape=n_items) # Discrimination multilevel prior rayleigh_scale = pm.Lognormal("Rayleigh_Scale", mu=0, sigma=1/4, shape=1) discrimination = pm.Bound(Rayleigh, lower=0.25)(name='Discrimination', beta=rayleigh_scale, offset=0.25, shape=n_items) # guessing prior exponential_lambda = pm.TruncatedNormal('Exponential_Scale', mu=15, sigma=2, shape=1, lower=10, upper=20) guessing = pm.Exponential('Guessing', lam=exponential_lambda, shape=n_items) # Compute the probabilities kernel = ability[None, :] - difficulty[:, None] kernel *= discrimination[:, None] probabilities = pm.Deterministic("PL_Kernel", guessing[:, None] + (1 - guessing[:, None]) * pm.math.invlogit(kernel)) # Get the log likelihood log_likelihood = pm.Bernoulli("Log_Likelihood", p=probabilities, observed=observed) return threepl_pymc_model
def bayes_dummy_model_ref(uniform, max_allowed_specificMB=None, gd=None, sampler='nuts', ys=None, gd_mb=None, h=None, w=None, use_two_msm=True, nosigma=False, pd_calib_opt=None, random_seed=4, y0=None, y1=None): # if use_two_msm: slope_pfs = [] slope_melt_fs = [] for y in ys: slope_pf, slope_melt_f = get_slope_pf_melt_f(gd_mb, h=h, w=w, ys=y) slope_pfs.append(slope_pf.mean()) slope_melt_fs.append(slope_melt_f.mean()) with pm.Model() as model_T: if uniform: melt_f = pm.Uniform("melt_f", lower=10, upper=1000) pf = pm.Uniform('pf', lower=0.1, upper=10) else: pf = pm.TruncatedNormal('pf', mu=pd_calib_opt['pf_opt'][ pd_calib_opt.reg == 11.0].dropna().mean(), sigma=pd_calib_opt['pf_opt'][ pd_calib_opt.reg == 11.0].dropna().std(), lower=0.5, upper=10) melt_f = pm.TruncatedNormal('melt_f', mu=pd_calib_opt['melt_f_opt_pf'][ pd_calib_opt.reg == 11.0].dropna().mean(), sigma=pd_calib_opt['melt_f_opt_pf'][ pd_calib_opt.reg == 11.0].dropna().std(), lower=1, upper=1000) # need to put slope_melt_fs and slope_pfs into [], other wise it does not work for jay aet_slope_melt_fs = pm.Data('aet_slope_melt_fs', slope_melt_fs) # pd.DataFrame(slope_melt_fs, columns=['slope_melt_fs'])['slope_melt_fs']) aet_slope_pfs = pm.Data('aet_slope_pfs', slope_pfs) # pd.DataFrame(slope_pfs, columns=['slope_pfs'])['slope_pfs']) aet_mbs = aet_slope_pfs * pf + aet_slope_melt_fs * melt_f mb_mod = pm.Deterministic('mb_mod', aet_mbs) with model_T: ref_df = gd.get_ref_mb_data(y0=y0, y1=y1) # sigma = pm.Data('sigma', 100) # how large are the uncertainties of the direct glaciological method !!! sigma = pm.Data('sigma', 100) # np.abs(ref_df['ANNUAL_BALANCE'].values/10)) # how large are the uncertainties of the direct glaciological method !!! observed = pm.Data('observed', ref_df['ANNUAL_BALANCE'].values) if nosigma: geodetic_massbal = pm.TruncatedNormal('geodetic_massbal', mu=mb_mod, # sigma=sigma, observed=observed, lower=max_allowed_specificMB) else: geodetic_massbal = pm.TruncatedNormal('geodetic_massbal', mu=mb_mod, sigma=sigma, observed=observed, lower=max_allowed_specificMB) # likelihood diff_geodetic_massbal = pm.Deterministic("diff_geodetic_massbal", geodetic_massbal - observed) # pot_max_melt = pm.Potential('pot_max_melt', aet.switch(geodetic_massbal < max_allowed_specificMB, -np.inf, 0) ) prior = pm.sample_prior_predictive(random_seed=random_seed, samples=1000) # , keep_size = True) if sampler == 'nuts': trace = pm.sample(10000, chains=4, tune=10000, target_accept=0.98, compute_convergence_checks=True, return_inferencedata=True) # #start={'pf':2.5, 'melt_f': 200}) elif sampler == 'jax': import pymc3.sampling_jax trace = pm.sampling_jax.sample_numpyro_nuts(20000, chains=4, tune=20000, target_accept=0.98) # , compute_convergence_checks= True) with model_T: burned_trace = trace.sel(draw=slice(5000, None)) az.summary(burned_trace.posterior) ppc = pm.sample_posterior_predictive(burned_trace, random_seed=random_seed, var_names=['geodetic_massbal', 'pf', 'melt_f', 'mb_mod', 'diff_geodetic_massbal'], keep_size=True) az.concat(burned_trace, az.from_dict(posterior_predictive=ppc, prior=prior), inplace=True) # with model_T: # slope_pf_new = [] # slope_melt_f_new = [] # for y in ys: # slope_pf, slope_melt_f = get_slope_pf_melt_f(gd_mb, h = h, w =w, ys = y) # slope_pf_new.append(slope_pf.mean()) # slope_melt_f_new.append(slope_melt_f.mean()) # if nosigma: # pm.set_data(new_data={'aet_slope_melt_fs': slope_melt_f_new, 'aet_slope_pfs':slope_pf_new, # 'observed':np.empty(len(ys))}) # , 'sigma':np.empty(len(ys))}) ## else: # pm.set_data(new_data={'aet_slope_melt_fs': slope_melt_f_new, 'aet_slope_pfs':slope_pf_new, # 'observed':np.empty(len(ys)), 'sigma':np.empty(len(ys))}) ## ppc_new = pm.sample_posterior_predictive(burned_trace, random_seed=random_seed, # var_names=['geodetic_massbal', 'pf', 'melt_f', 'mb_mod','diff_geodetic_massbal'], # keep_size = True) # predict_data = az.from_dict(posterior_predictive=ppc_new) return burned_trace, model_T # , predict_data # idata_kwargs={"density_dist_obs": False}
'full_width': True }}) profile # # Hierarchical Bayesian Modeling n_videos = len(df_videos) # + # define model and sample with pm.Model() as model: # prior to parameters alpha_plus = pm.Normal('alpha_plus', mu=-3, sd=2) beta_plus = pm.TruncatedNormal('beta_plus', mu=0, sd=1, lower=0) alpha_minus = pm.Normal('alpha_minus', mu=-3, sd=2) beta_minus = pm.TruncatedNormal('beta_minus', mu=0, sd=1, upper=0) # prior to fun fun = pm.Normal('fun', mu=0, sd=1, shape=n_videos) # play play = df_videos['視聴回数'] # +1 and -1 lambda_plus = pm.math.exp((alpha_plus + beta_plus * fun)) * play like = pm.Poisson('like', mu=lambda_plus, observed=df_videos['高評価件数']) lambda_minus = pm.math.exp((alpha_minus + beta_minus * fun)) * play dislike = pm.Poisson('dislike',
def build(self): with pm.Model() as env_model: # Generate region weights w_r = pm.MvNormal('w_r', mu=self.prior.loc_w_r, tau=self.prior.scale_w_r, shape=self.n_regions) # Generate Product weights #packed_L_p = pm.LKJCholeskyCov('packed_L_p', n=self.n_products, # eta=2., sd_dist=pm.HalfCauchy.dist(2.5)) #L_p = pm.expand_packed_triangular(self.n_products, packed_L_p) mu_p = pm.MvNormal("mu_p", mu=self.prior.loc_w_p, cov=np.eye(self.n_products), shape=self.n_products) #w_p = pm.MvNormal('w_p', mu=mu_p, chol=L_p, # shape=self.n_products) w_p = pm.MvNormal('w_p', mu=mu_p, cov=self.prior.scale_w_p, shape=self.n_products) # Generate previous sales weight loc_w_s = pm.HalfCauchy('loc_w_s', 1.0) scale_w_s = pm.HalfCauchy('scale_w_s', 2.5) w_s = pm.TruncatedNormal('w_s', mu=loc_w_s, sigma=scale_w_s, lower=0.0) # Generate temporal weights packed_L_t = pm.LKJCholeskyCov('packed_L_t', n=self.n_temporal_features, eta=2., sd_dist=pm.HalfCauchy.dist(2.5)) L_t = pm.expand_packed_triangular(self.n_temporal_features, packed_L_t) mu_t = pm.MvNormal("mu_t", mu=self.prior.loc_w_t, cov=self.prior.scale_w_t, shape=self.n_temporal_features) w_t = pm.MvNormal('w_t', mu=mu_t, chol=L_t, shape=self.n_temporal_features) lambda_c_t = pm.math.dot(self.X_temporal, w_t.T) bias_q_loc = pm.Normal('bias_q_loc', mu=0.0, sigma=1.0) bias_q_scale = pm.HalfCauchy('bias_q_scale', 5.0) bias_q = pm.Normal("bias_q", mu=bias_q_loc, sigma=bias_q_scale) if self.log_linear: lambda_q = pm.math.exp(bias_q + lambda_c_t[self.time_stamps] + pm.math.dot(self.X_region, w_r.T) + pm.math.dot(self.X_product, w_p.T) + w_s * self.X_lagged) else: lambda_q = bias_q + lambda_c_t[self.time_stamps] + pm.math.dot( self.X_region, w_r.T) + pm.math.dot( self.X_product, w_p.T) + w_s * self.X_lagged sigma_q_ij = pm.InverseGamma("sigma_q_ij", alpha=self.prior.loc_sigma_q_ij, beta=self.prior.scale_sigma_q_ij) q_ij = pm.TruncatedNormal('quantity_ij', mu=lambda_q, sigma=sigma_q_ij, lower=0.0, observed=self.y) return env_model
def pymc3_simple(indep, dep, img_dir_orig, degree=2, mindep=-1.0, maxdep=0.4, sampling=1000, tune=1000, uniform=True, extratext='', plot=True): img_dir = op.join(img_dir_orig, 'deg_%d' % (degree), extratext) mkpath(img_dir) ndim = len(indep) limlist = [] for indepi in indep: per = np.percentile(indepi, [1.0, 99.0]) limlist.append(per) lower, upper = min(mindep, np.amin(dep)), max( maxdep, np.amax(dep)) # Limits for dependent variable x = np.empty( (0, degree + 1)) # To set up grid on which true dust parameter n will be defined for lim in limlist: x = np.append(x, np.linspace(lim[0], lim[-1], degree + 1)[None, :], axis=0) xx = np.meshgrid(*x) #N-D Grid for polynomial computations a_poly_T = get_a_polynd( xx ).T #Array related to grid that will be used in least-squares computation aTinv = np.linalg.inv(a_poly_T) rc = -1.0 #Rcond parameter set to -1 for keeping all entries of result to machine precision, regardless of rank issues # 2-D array that will be multiplied by coefficients to calculate the dust parameter at the observed independent variable values term = calc_poly_tt(indep, degree) # breakpoint() with pm.Model() as model: # Priors on the parameters ngrid (n over the grid) and sigma (related to width of relation) if uniform: ngrid = pm.Uniform("ngrid", lower=lower - 1.0e-5, upper=upper + 1.0e-5, shape=xx[0].size, testval=np.random.uniform( lower, upper, xx[0].size)) else: ngrid = pm.TruncatedNormal("ngrid", mu=0.3, sigma=1.0, lower=lower - 1.0e-5, upper=upper + 1.0e-5, shape=xx[0].size, testval=np.random.uniform( lower, upper / 2.0, xx[0].size)) sigma = pm.HalfNormal("sigma", sigma=1) # Compute the expected n at each sample coefs = tt.dot(aTinv, ngrid) mu = tt.tensordot(coefs, term, axes=1) # Likelihood (sampling distribution) of observations dep_obs = pm.Normal("dep_obs", mu=mu, sigma=sigma, observed=dep) map_estimate = pm.find_MAP() print(map_estimate) trace = pm.sample(draws=sampling, tune=tune, init='adapt_full', target_accept=0.9, return_inferencedata=True) if plot: az.plot_trace(trace) plt.savefig(op.join(img_dir, "polyND%s_trace_pm_simp.png" % (extratext)), bbox_inches='tight', dpi=300) print(az.summary(trace, round_to=2)) return trace, xx, map_estimate
nburn = 100 # number of "burn-in points" (which we'll discard) #nburn = 100 # number of "burn-in points" (which we'll discard) def lognorm_coeffs(loc, scale): return np.log(loc**2 / np.sqrt(loc**2 + scale**2)), np.log(1 + scale**2 / loc**2) prior_names = ['Ro', 'I_init', 'd'] # use PyMC3 to sampler from log-likelihood with pm.Model() as pmodel: #sigma = pm.Normal('sigma',0.00001) # sigma is the "noise" in the observations that we assume sigma = 0.000005 Ro = pm.TruncatedNormal('Ro', 2, 1, lower=0) # discrete uniform seems to have a bug (does not respect bounds) # therefore we use continous uniform and round it to full numbers # date_start = pm.Uniform('date_start',50,75) # date_start = tt.round(date_start) I_init = pm.Lognormal('I_init', *lognorm_coeffs(1e-5, 1e-5)) d = pm.Lognormal('d', *lognorm_coeffs(0.01, 0.01)) # convert params to tensor theta = tt.as_tensor_variable([Ro, I_init, d]) # create our Op logl = LogLike(evaluate_model_log, data_obs_dimless['D'].values, sigma) # use a DensityDist (use a lamdba function to "call" the Op) pm.DensityDist('likelihood', lambda v: logl(v),
def __init__(self, consts, prior_mu, obs): self.consts = consts self.prior_mu = prior_mu self.obs = obs self.model = pm.Model() with self.model: BoundedNormal = pm.Bound(pm.Normal, lower=0.0) eta = pm.Normal('eta', mu=self.prior_mu['eta'], sd=1.0, shape=self.consts['nn']) amplitude = pm.TruncatedNormal('amplitude', mu=self.prior_mu['amplitude'], sd=1.0, lower=0) offset = pm.TruncatedNormal('offset', mu=self.prior_mu['offset'], sd=1.0) K = pm.TruncatedNormal('K', mu=self.prior_mu['K'], sd=1., lower=0.0) eps = pm.TruncatedNormal('eps', mu=.0, sd=1.0, lower=0.0) sig = pm.TruncatedNormal('sig', mu=.0, sd=1.0, lower=0.0) x_init = pm.Normal('x_init', mu=self.prior_mu['x_init'], sd=1., shape=self.consts['nn']) z_init = pm.Normal('z_init', mu=self.prior_mu['z_init'], sd=1., shape=self.consts['nn']) # Cast constants in the model as tensors using theano shared variables time_step = theano.shared(self.consts['time_step'], 'time_step') SC = theano.shared(self.consts['SC'], 'SC') I1 = theano.shared(self.consts['I1'], 'I1') tau0 = theano.shared(self.consts['tau0'], 'tau0') output, updates = theano.scan( fn=step_ode, outputs_info=[x_init, z_init], non_sequences=[time_step, SC, K, eta, I1, tau0], n_steps=self.consts['nt']) x_sym = output[0] z_sym = output[1] x = pm.Normal('x', mu=x_sym, sd=tt.sqrt(time_step) * sig, shape=(self.consts['nt'], self.consts['nn'])) z = pm.Normal('z', mu=z_sym, sd=tt.sqrt(time_step) * sig, shape=(self.consts['nt'], self.consts['nn'])) xhat = pm.Deterministic('xhat', amplitude * x + offset) xs = pm.Normal('xs', mu=xhat, sd=eps, shape=(self.consts['nt'], self.consts['nn']), observed=self.obs['xs'])
gal_separate_fit_params = pd.Series([]) with tqdm([arm for arm in galaxy]) as bar: for i, arm in enumerate(bar): gal_separate_fit_params.loc[i] = sg.fit_log_spiral(*arm) gal_separate_fit_params = gal_separate_fit_params.apply( lambda v: pd.Series(v, index=('pa', 'c'))) print(gal_separate_fit_params.describe()) with pm.Model() as model: # model r = a * exp(tan(phi) * t) as log(r) = b * t + c, # but have a uniform prior on phi rather than the gradient! gal_pa_mu = pm.TruncatedNormal( 'pa', mu=15, sd=10, lower=0, upper=45, testval=10, ) gal_pa_sd = pm.HalfCauchy('pa_sd', beta=10, testval=0.1) arm_c = pm.Uniform('c', lower=-1, upper=0, shape=n_arms, testval=gal_separate_fit_params['c'].values / 10) * 10 sigma = pm.HalfCauchy('sigma100', beta=5, testval=1) / 100 # we want this: # arm_pa = pm.TruncatedNormal( # 'arm_pa', # mu=gal_pa_mu, sd=gal_pa_sd,
def main(input_dir, config_file, output_dir, dataset, model_type, tau, n_samples, n_tune, target_accept, n_cores, seed, init): prepare_output(output_dir) config = load_config(config_file, dataset) fit_range = config['fit_range'] path = os.path.join(input_dir, dataset) observations = load_data(path, config) e_true_bins = config['e_true_bins'] e_reco_bins = config['e_reco_bins'] # exposure_ratio = observations[0].alpha # from IPython import embed; embed() on_data, off_data, excess, exposure_ratio = get_observed_counts( observations, fit_range=fit_range, bins=e_reco_bins) print(f'Exposure ratio {exposure_ratio}') # from IPython import embed; embed() # print(f'On Data {on_data.shape}\n') # display_data(on_data) # print(f'\n\n Off Data {off_data.shape}\n') # display_data(off_data) print(f'Excess {excess.shape} \n') idx = np.searchsorted(e_reco_bins.to_value(u.TeV), fit_range.to_value(u.TeV)) lo, up = idx[0], idx[1] + 1 indices = np.argwhere(excess > 5) display_data(excess, mark_indices=indices, low_index=lo, high_index=up) print('--' * 30) print(f'Unfolding data for: {dataset.upper()}. ') # print(f'IRF with {len( config['e_true_bins'] ) - 1, len( config['e_reco_bins'] ) - 1}') print( f'Using {len(on_data)} bins with { on_data.sum()} counts in on region and {off_data.sum()} counts in off region.' ) area_scaling = 1 print(observations[0].aeff.data.data.to_value(u.km**2).astype(np.float32) * area_scaling) model = pm.Model(theano_config={'compute_test_value': 'ignore'}) with model: # mu_b = pm.TruncatedNormal('mu_b', shape=len(off_data), sd=5, mu=off_data, lower=0.01) # expected_counts = pm.Lognormal('expected_counts', shape=len(config['e_true_bins']) - 1, testval=10, sd=1) expected_counts = pm.TruncatedNormal('expected_counts', shape=len(e_true_bins) - 1, testval=0.5, mu=2, sd=50, lower=0.0001) # expected_counts = pm.HalfFlat('expected_counts', shape=len(e_true_bins) - 1, testval=10) # c = expected_counts / area_scaling mu_s = forward_fold(expected_counts, observations, fit_range=fit_range, area_scaling=area_scaling) if model_type == 'wstat': print('Building profiled likelihood model') mu_b = pm.Deterministic( 'mu_b', calc_mu_b(mu_s, on_data, off_data, exposure_ratio)) else: print('Building full likelihood model') mu_b = pm.HalfFlat('mu_b', shape=len(off_data)) # mu_b = pm.Lognormal('mu_b', shape=len(off_data), sd=5) pm.Poisson('background', mu=mu_b + 1E-5, observed=off_data) pm.Poisson('signal', mu=mu_s + exposure_ratio * mu_b + 1E-5, observed=on_data) print('--' * 30) print('Model debug information:') for RV in model.basic_RVs: print(RV.name, RV.logp(model.test_point)) print('--' * 30) print('Sampling likelihood:') with model: trace = pm.sample(n_samples, cores=n_cores, tune=n_tune, init=init, seed=[seed] * n_cores) trace_output = os.path.join(output_dir, 'traces') print(f'Saving traces to {trace_output}') with model: pm.save_trace(trace, trace_output, overwrite=True) print('--' * 30) print('Plotting result') # print(area_scaling) fig, [ax1, ax2] = plt.subplots(2, 1, figsize=(10, 7), sharex=True, gridspec_kw={'height_ratios': [3, 1]}) plot_unfolding_result(trace, bins=e_true_bins, area_scaling=area_scaling, fit_range=fit_range, ax=ax1) plot_excees(excess, bins=config['e_reco_bins'], ax=ax2) plt.savefig(os.path.join(output_dir, 'result.pdf')) print('--' * 30) print('Plotting Diagnostics') print(pm.summary(trace).round(2)) # plt.figure() # pm.traceplot(trace) # plt.savefig(os.path.join(output_dir, 'traces.pdf')) plt.figure() pm.energyplot(trace) plt.savefig(os.path.join(output_dir, 'energy.pdf')) # try: # plt.figure() # pm.autocorrplot(trace, burn=n_tune) # plt.savefig(os.path.join(output_dir, 'autocorr.pdf')) # except: # print('Could not plot auttocorrelation') plt.figure() pm.forestplot(trace) plt.savefig(os.path.join(output_dir, 'forest.pdf')) p = os.path.join(output_dir, 'num_samples.txt') with open(p, "w") as text_file: text_file.write(f'\\num{{{n_samples}}}') p = os.path.join(output_dir, 'num_chains.txt') with open(p, "w") as text_file: text_file.write(f'\\num{{{n_cores}}}') p = os.path.join(output_dir, 'num_tune.txt') with open(p, "w") as text_file: text_file.write(f'\\num{{{n_tune}}}')
def ParamPriorModel(param): # param_name_ = param[0] prior_def_ = param[3] # prior_def, definition for the prior probability # # [ XA.PriorFunc_????, arg1, arg2, arg3, ... ] prior_type_ = prior_def_[0] arg1_ = prior_def_[1] arg2_ = prior_def_[2] # # XA.PriorFunc_Unknown = -1 # XA.PriorFunc_Uniform = 0 # arg1 = lower, arg2 = upper # XA.PriorFunc_Norm = 1 # arg1 = mean, arg2 = sd # XA.PriorFunc_Gamma = 2 # arg1 = alpha, arg2 = beta # XA.PriorFunc_Beta = 3 # arg1 = alpha, arg2 = beta # XA.PriorFunc_TruncatedNorm = 4 # arg1 = mean, arg2 = sd, arg3 = lower, arg4 = upper # XA.PriorFunc_TruncatedNorm_sd_ratio = 5 # arg1 = mean, arg2 = sd, arg3 = ratio # # Making data for prior # if (prior_type_ == PriorFunc_Uniform): # print('%-10s: Uniform( lower=%g, upper=%g )' % (param_name_, arg1_, arg2_)) return pm.Uniform(param_name_, lower=arg1_, upper=arg2_) # elif (prior_type_ == PriorFunc_Norm): # print('%-10s: Normal( mu=%g, sd=%g )' % (param_name_, arg1_, arg2_)) return pm.Normal(param_name_, mu=arg1_, sd=arg2_) # elif (prior_type_ == PriorFunc_Gamma): # print('%-10s: Gamma( alpha=%g, beta=%g )' % (param_name_, arg1_, arg2_)) return pm.Gamma(param_name_, alpha=arg1_, beta=arg2_) # elif (prior_type_ == PriorFunc_Beta): # print('%-10s: Beta( alpha=%g, beta=%g )' % (param_name_, arg1_, arg2_)) return pm.Beta(param_name_, alpha=arg1_, beta=arg2_) # elif (prior_type_ == PriorFunc_TruncatedNorm): # arg3_ = prior_def_[3] arg4_ = prior_def_[4] # print('%-10s: TruncatedNormal( mu=%g, sd=%g, lower=%g, upper=%g )' % (param_name_, arg1_, arg2_, arg3_, arg4_)) return pm.TruncatedNormal(param_name_, mu=arg1_, sd=arg2_, lower=arg3_, upper=arg4_) # elif (prior_type_ == PriorFunc_TruncatedNorm_sd_ratio): # arg3_ = prior_def_[3] lower_ = arg1_ - arg3_ * arg2_ upper_ = arg1_ + arg3_ * arg2_ # print('%-10s: TruncatedNormal( mu=%g, sd=%g, lower=%g, upper=%g )' % (param_name_, arg1_, arg2_, lower_, upper_)) return pm.TruncatedNormal(param_name_, mu=arg1_, sd=arg2_, lower=lower_, upper=upper_)
def fit_profile_pymc3(hmcmod, prof, nmcmc=1000, tune=500, find_map=True, fitlow=0., fithigh=1e10): if hmcmod.start is None or hmcmod.sd is None: print( 'Missing prior definition, cannot continue; please provide both "start" and "sd" parameters' ) return npar = hmcmod.npar reg = np.where(np.logical_and(prof.bins >= fitlow, prof.bins <= fithigh)) sb = prof.profile[reg] esb = prof.eprof[reg] rad = prof.bins[reg] erad = prof.ebins[reg] counts = prof.counts[reg] area = prof.area[reg] exposure = prof.effexp[reg] bkgcounts = prof.bkgcounts[reg] if prof.psfmat is not None: psfmat = np.transpose(prof.psfmat) else: psfmat = np.eye(prof.nbin) hmc_model = pm.Model() with hmc_model: # Set up model parameters allpmod = [] numrf = None for i in range(npar): name = hmcmod.parnames[i] if not hmcmod.fix[i]: print( 'Setting Gaussian prior for parameter %s with center %g and standard deviation %g' % (name, hmcmod.start[i], hmcmod.sd[i])) if hmcmod.limits is not None: lim = hmcmod.limits[i] modpar = pm.TruncatedNormal(name, mu=hmcmod.start[i], sd=hmcmod.sd[i], lower=lim[0], upper=lim[1]) else: modpar = pm.Normal(name, mu=hmcmod.start[i], sd=hmcmod.sd[i]) else: print('Parameter %s is fixed' % (name)) modpar = pm.ConstantDist(name, hmcmod.start[i]) if name == 'rf': numrf = modpar.random() else: allpmod.append(modpar) pmod = pm.math.stack(allpmod, axis=0) if numrf is not None: modcounts = hmcmod.model(rad, *pmod, rf=numrf) * area * exposure else: modcounts = hmcmod.model(rad, *pmod) * area * exposure pred = pm.math.dot(psfmat, modcounts) + bkgcounts count_obs = pm.Poisson('counts', mu=pred, observed=counts) # counts likelihood tinit = time.time() print('Running MCMC...') with hmc_model: if find_map: start = pm.find_MAP() trace = pm.sample(nmcmc, start=start, tune=tune) else: trace = pm.sample(nmcmc, tune=tune) print('Done.') tend = time.time() print(' Total computing time is: ', (tend - tinit) / 60., ' minutes') hmcmod.trace = trace
def train(self, df_train, first_feature): self.first_feature = first_feature #get rid of identifiers and team record info index = list(df_train.columns).index(first_feature) features = df_train.iloc[:, index:] features = remove_stats(features, ['w', 'l', 'gp', 'min']) #get rid of irrelevant quarter features features = get_quarter_features(features, self.period) for f in self.remove_features: features = remove_stats(features, [f]) for f in self.restrict_features: features = restrict_stats(features, [f]) print("feature classes", self.feature_classes) #choose features here if self.feature_classes != 'all': features = restrict_stats(features, self.feature_classes) self.feature_cols = list(features.columns) if self.normalize: self.features_prenorm = features mm_scaler = MinMaxScaler() features = mm_scaler.fit_transform(features) features = pd.DataFrame(data=features, columns=self.feature_cols) if self.period == 0: Y = df_train['pts_a'] + df_train['pts_h'] elif self.period == 5: Y = df_train['pts_qtr1_a'] + df_train['pts_qtr2_a'] + df_train[ 'pts_qtr1_h'] + df_train['pts_qtr2_h'] elif self.period == 6: Y = df_train['pts_qtr3_a'] + df_train['pts_qtr4_a'] + df_train[ 'pts_qtr3_h'] + df_train['pts_qtr4_h'] else: Y = df_train[f'pts_qtr{self.period}_a'] + df_train[ f'pts_qtr{self.period}_h'] if self.model_type == 'Lasso' or self.model_type == 'Ridge': self.reg.fit(features, Y) else: x = features.values model_split = self.model_type.split('-') cat = model_split[0] prior = model_split[1] self.prior = prior self.cat = cat if prior == 'basic': if cat == 'bayes': print("x shape", x.shape) self.x_shared = theano.shared(x) self.y_shared = theano.shared(Y.values) print("Y shape", Y.values.shape) self.basic_model = pm.Model() with self.basic_model: # Priors for unknown model parameters alpha = pm.Normal('alpha', mu=0, sigma=10) beta = pm.Normal('beta', mu=0, sigma=1, shape=x.shape[1]) sigma = pm.HalfNormal('sigma', sigma=1) if cat == 'MAP': mu = alpha + pm.math.dot(x, beta) Y_obs = pm.Normal('Y_obs', mu=mu, sigma=sigma, observed=Y) elif cat == 'bayes': mu = alpha + pm.math.dot(self.x_shared, beta) Y_obs = pm.Normal('Y_obs', mu=mu, sigma=sigma, observed=self.y_shared) self.trace = pm.sample(self.trace_samp, step=pm.NUTS(), chains=self.chains, cores=self.cores, tune=self.burn_in) elif cat == 'bayes' and prior == 'normal': print("x shape", x.shape) self.x_shared = theano.shared(x) self.y_shared = theano.shared(Y.values) print("Y shape", Y.values.shape) self.basic_model = pm.Model() with self.basic_model: alpha = pm.Normal('alpha', mu=0, sigma=10) beta_def = pm.Normal('beta_def', mu=-.25, sigma=.25, shape=8) beta_off = pm.Normal('beta_off', mu=.25, sigma=.25, shape=8) beta_pace = pm.Normal('beta_pace', mu=.25, sigma=.25, shape=8) sigma = pm.HalfNormal('sigma', sigma=1) mu = alpha for i in ['off', 'def', 'pace']: if i == 'off': off_col_list = [j * 3 for j in range(8)] x_off = self.x_shared[:, off_col_list] mu += theano.tensor.dot(x_off, beta_off) elif i == 'def': def_col_list = [j * 3 + 1 for j in range(8)] x_def = self.x_shared[:, def_col_list] mu += theano.tensor.dot(x_def, beta_def) elif i == 'pace': pace_col_list = [j * 3 + 2 for j in range(8)] x_pace = self.x_shared[:, pace_col_list] mu += theano.tensor.dot(x_pace, beta_pace) # Likelihood (sampling distribution) of observations Y_obs = pm.Normal('Y_obs', mu=mu, sigma=sigma, observed=self.y_shared) self.trace = pm.sample(self.trace_samp, step=pm.Slice(), chains=self.chains, cores=self.cores, tune=self.burn_in) elif cat == 'MAP': cols = features.columns print('building model with prior:', prior) self.prior_model = pm.Model() for i in range(len(cols)): print(i, cols[i]) with self.prior_model: # Priors for unknown model parameters alpha = pm.Normal('alpha', mu=0, sigma=10) if prior == 'normal': beta_def = pm.Normal('beta_def', mu=-.25, sigma=.25, shape=8) beta_off = pm.Normal('beta_off', mu=.25, sigma=.25, shape=8) beta_pace = pm.Normal('beta_pace', mu=.25, sigma=.25, shape=8) if prior == 'uniform': beta_def = pm.Uniform('beta_def', upper=0, lower=-.5, shape=8) beta_off = pm.Uniform('beta_off', upper=.5, lower=0, shape=8) beta_pace = pm.Uniform('beta_pace', upper=.5, lower=0, shape=8) if prior == 'truncnormal': beta_def = pm.TruncatedNormal('beta_def', mu=-.25, sigma=.25, upper=0, shape=8) beta_off = pm.TruncatedNormal('beta_off', mu=.25, sigma=.25, lower=0, shape=8) beta_pace = pm.TruncatedNormal('beta_pace', mu=.25, sigma=.25, lower=0, shape=8) sigma = pm.HalfNormal('sigma', sigma=1) # Expected value of outcome mu = alpha for i in ['off', 'def', 'pace']: if i == 'off': self.off_col_list = [j * 3 for j in range(8)] x = features.iloc[:, self.off_col_list].values mu += pm.math.dot(x, beta_off) elif i == 'def': self.def_col_list = [j * 3 + 1 for j in range(8)] x = features.iloc[:, self.def_col_list].values print("X SHAPE", x.shape) exit() mu += pm.math.dot(x, beta_def) elif i == 'pace': self.pace_col_list = [j * 3 + 2 for j in range(8)] x = features.iloc[:, self.pace_col_list].values mu += pm.math.dot(x, beta_pace) # Likelihood (sampling distribution) of observations Y_obs = pm.Normal('Y_obs', mu=mu, sigma=sigma, observed=Y) elif cat == 'GP': train_x = torch.from_numpy(x).double() train_y = torch.from_numpy(Y.values).double() self.likelihood = gpytorch.likelihoods.GaussianLikelihood() if prior == 'RBF': kernel = gpytorch.kernels.RBFKernel() elif prior == 'Exponential': kernel = gpytorch.kernels.MaternKernel(nu=0.5) self.gp_model = GPModelSKI(train_x, train_y, self.likelihood, kernel) # Find optimal model hyperparameters self.gp_model.double() self.gp_model.train() self.likelihood.train() # Use the adam optimizer optimizer = torch.optim.Adam( [{ 'params': self.gp_model.parameters() }], lr=0.1) # "Loss" for GPs - the marginal log likelihood mll = gpytorch.mlls.ExactMarginalLogLikelihood( self.likelihood, self.gp_model) print('training gp model...') def gp_train(training_iter): for i in range(training_iter): optimizer.zero_grad() output = self.gp_model(train_x) loss = -mll(output, train_y) loss.backward() print('Iter %d/%d - Loss: %.3f' % (i + 1, training_iter, loss.item()), end='\r') optimizer.step() print('Iter %d/%d - Loss: %.3f' % (training_iter, training_iter, loss.item())) with gpytorch.settings.use_toeplitz(False): gp_train(500)
def get_model(): conf = bayes_workshop.conf.get_conf() (cols, data) = bayes_workshop.data.get_data() # from Lee i_subjects = (6, 8, 14, 17, 5, 2) modality = "visual" n_subj = len(i_subjects) i_trials = np.logical_and( np.isin(data[:, cols.index("i_subj")], i_subjects), data[:, cols.index("i_modality")] == conf.modalities.index(modality)) data = data[i_trials, :] i_subj = scipy.stats.rankdata(data[:, cols.index("i_subj")], method="dense") - 1 responses = data[:, cols.index("target_longer")] cmp_dur = data[:, cols.index("target_duration")] with pm.Model() as model: alpha_mu = pm.Normal("alpha_mu", mu=conf.standard_ms, sd=50.0, testval=conf.standard_ms) alpha_sd = pm.Uniform("alpha_sd", lower=0.01, upper=100.0, testval=5.0) alphas_offset = pm.Normal("alphas_offset", mu=0.0, sd=1.0, shape=n_subj) alphas = pm.Deterministic("alphas", alpha_mu + alpha_sd * alphas_offset) beta_mu = pm.TruncatedNormal("beta_mu", mu=0.0, sd=100.0, lower=0.0, upper=10e6, testval=100.0) beta_sd = pm.Uniform("beta_sd", lower=0.01, upper=100.0, testval=50.0) betas = pm.TruncatedNormal("betas", mu=beta_mu, sd=beta_sd, lower=0.0, upper=10e6, shape=n_subj, testval=100.0) theta = bayes_workshop.utils.logistic(x=cmp_dur, alpha=alphas[i_subj], beta=betas[i_subj]) obs = pm.Bernoulli("obs", p=theta, observed=responses) return model
def build_prior_model(prior, features, x, y): cols = features.columns print('building model with prior:', prior) prior_model = pm.Model() for i in range(len(cols)): print(i, cols[i]) with prior_model: # Priors for unknown model parameters alpha = pm.Normal('alpha', mu=0, sigma=10) if prior == 'normal': beta_def = pm.Normal('beta_def', mu=-.25, sigma=.25, shape=8) beta_off = pm.Normal('beta_off', mu=.25, sigma=.25, shape=8) beta_pace = pm.Normal('beta_pace', mu=.25, sigma=.25, shape=8) if prior == 'uniform': beta_def = pm.Uniform('beta_def', upper=0, lower=-.5, shape=8) beta_off = pm.Uniform('beta_off', upper=.5, lower=0, shape=8) beta_pace = pm.Uniform('beta_pace', upper=.5, lower=0, shape=8) if prior == 'truncnormal': beta_def = pm.TruncatedNormal('beta_def', mu=-.25, sigma=.25, upper=0, shape=8) beta_off = pm.TruncatedNormal('beta_off', mu=.25, sigma=.25, lower=0, shape=8) beta_pace = pm.TruncatedNormal('beta_pace', mu=.25, sigma=.25, lower=0, shape=8) sigma = pm.HalfNormal('sigma', sigma=1) # Expected value of outcome mu = alpha for i in ['off', 'def', 'pace']: if i == 'off': off_col_list = [j * 3 for j in range(8)] x = features.iloc[:, off_col_list].values mu += pm.math.dot(x, beta_off) elif i == 'def': def_col_list = [j * 3 + 1 for j in range(8)] x = features.iloc[:, def_col_list].values mu += pm.math.dot(x, beta_def) elif i == 'pace': pace_col_list = [j * 3 + 2 for j in range(8)] x = features.iloc[:, pace_col_list].values mu += pm.math.dot(x, beta_pace) # Likelihood (sampling distribution) of observations Y_obs = pm.Normal('Y_obs', mu=mu, sigma=sigma, observed=y) return prior_model, off_col_list, def_col_list, pace_col_list
true_solution_numpy = to_numpy(true_solution) # perturb state solution and create synthetic measurements noise_level = 0.05 MAX = np.linalg.norm(true_solution_numpy) noise = np.random.normal(scale=noise_level * MAX, size=true_solution_numpy.size) noisy_solution = true_solution_numpy + noise theano_fem = create_fenics_theano_op(templates)(solve_fenics) with pm.Model() as fit_diffusion: sigma = pm.InverseGamma("sigma", alpha=3.0, beta=0.5) kappa0 = pm.TruncatedNormal( "kappa0", mu=1.0, sigma=0.5, lower=1e-5, upper=2.0, shape=(1, )) # truncated(Normal(1.0, 0.5), 1e-5, 2) kappa1 = pm.TruncatedNormal( "kappa1", mu=0.7, sigma=0.5, lower=1e-5, upper=2.0, shape=(1, )) # truncated(Normal(0.7, 0.5), 1e-5, 2) predicted_solution = pm.Deterministic("pred_sol", theano_fem(kappa0, kappa1)) d = pm.Normal("d", mu=predicted_solution, sd=sigma, observed=noisy_solution) def test_run_sample():
def bayes_dummy_model_ref_std(uniform, max_allowed_specificMB=None, gd=None, sampler='nuts', ys=np.arange(1979, 2019, 1), gd_mb=None, h=None, w=None, use_two_msm=True, nosigma=False, nosigmastd=False, first_ppc=True, pd_calib_opt=None, pd_geodetic_comp=None, random_seed=42, y0=None, y1=None): # test slope_pfs = [] slope_melt_fs = [] for y in ys: slope_pf, slope_melt_f = get_slope_pf_melt_f(gd_mb, h=h, w=w, ys=y) slope_pfs.append(slope_pf.mean()) slope_melt_fs.append(slope_melt_f.mean()) with pm.Model() as model_T: if uniform: melt_f = pm.Uniform("melt_f", lower=10, upper=1000) pf = pm.Uniform('pf', lower=0.1, upper=10) else: pf = pm.TruncatedNormal('pf', mu=pd_calib_opt['pf_opt'][ pd_calib_opt.reg == 11.0].dropna().mean(), sigma=pd_calib_opt['pf_opt'][ pd_calib_opt.reg == 11.0].dropna().std(), lower=0.5, upper=10) melt_f = pm.TruncatedNormal('melt_f', mu=pd_calib_opt['melt_f_opt_pf'][ pd_calib_opt.reg == 11.0].dropna().mean(), sigma=pd_calib_opt['melt_f_opt_pf'][ pd_calib_opt.reg == 11.0].dropna().std(), lower=10, upper=1000) ## if use_two_msm: # should not use the stuff before 2000 aet_slope_melt_fs_two = pm.Data('aet_slope_melt_fs_two', [np.array(slope_melt_fs)[ (ys >= 2000) & ( ys <= 2009)].mean(), np.array(slope_melt_fs)[ ys >= 2010].mean()]) aet_slope_pfs_two = pm.Data('aet_slope_pfs_two', ([np.array(slope_pfs)[(ys >= 2000) & ( ys <= 2009)].mean(), np.array(slope_pfs)[ ys >= 2010].mean()])) else: aet_slope_melt_fs_two = pm.Data('aet_slope_melt_fs_two', [np.array(slope_melt_fs)[ ys >= 2000].mean()]) aet_slope_pfs_two = pm.Data('aet_slope_pfs_two', [np.array(slope_pfs)[ ys >= 2000].mean()]) aet_mbs_two = aet_slope_pfs_two * pf + aet_slope_melt_fs_two * melt_f # make a deterministic out of it to save it also in the traces mb_mod = pm.Deterministic('mb_mod', aet_mbs_two) # std # need to put slope_melt_fs and slope_pfs into []??? aet_slope_melt_fs = pm.Data('aet_slope_melt_fs', slope_melt_fs) # pd.DataFrame(slope_melt_fs, columns=['slope_melt_fs'])['slope_melt_fs']) aet_slope_pfs = pm.Data('aet_slope_pfs', slope_pfs) # pd.DataFrame(slope_pfs, columns=['slope_pfs'])['slope_pfs']) aet_mbs = aet_slope_pfs * pf + aet_slope_melt_fs * melt_f mod_std = pm.Deterministic('mod_std', aet_mbs.std()) if use_two_msm: sigma = pm.Data('sigma', pd_geodetic_comp.loc[gd.rgi_id][ ['err_dmdtda_2000_2010', 'err_dmdtda_2010_2020']].values * 1000) observed = pm.Data('observed', pd_geodetic_comp.loc[gd.rgi_id][ ['dmdtda_2000_2010', 'dmdtda_2010_2020']].values * 1000) if nosigma == False: geodetic_massbal = pm.Normal('geodetic_massbal', mu=mb_mod, sigma=sigma, # standard devia observed=observed) # likelihood else: geodetic_massbal = pm.Normal('geodetic_massbal', mu=mb_mod, observed=observed) # likelihood # diff_geodetic_massbal = pm.Deterministic("diff_geodetic_massbal", # geodetic_massbal - observed) else: # sigma and observed need to have dim 1 (not zero), --> [value] sigma = pm.Data('sigma', [ pd_geodetic_comp.loc[gd.rgi_id]['err_dmdtda'] * 1000]) observed = pm.Data('observed', [ pd_geodetic_comp.loc[gd.rgi_id]['dmdtda'] * 1000]) if nosigma == False: # likelihood geodetic_massbal = pm.TruncatedNormal('geodetic_massbal', mu=mb_mod, sigma=sigma, # standard devia observed=observed, lower=max_allowed_specificMB) else: geodetic_massbal = pm.TruncatedNormal('geodetic_massbal', mu=mb_mod, observed=observed, lower=max_allowed_specificMB) # likelihood # constrained already by using TruncatedNormal geodetic massbalance ... # pot_max_melt = pm.Potential('pot_max_melt', aet.switch( # geodetic_massbal < max_allowed_specificMB, -np.inf, 0)) diff_geodetic_massbal = pm.Deterministic("diff_geodetic_massbal", geodetic_massbal - observed) # pot_max_melt = pm.Potential('pot_max_melt', aet.switch(geodetic_massbal < max_allowed_specificMB, -np.inf, 0) ) # std # sigma = pm.Data('sigma', 100) # how large are the uncertainties of the direct glaciological method !!! ref_df = gd.get_ref_mb_data(y0=y0, y1=y1) sigma_std = aet.constant((ref_df[ 'ANNUAL_BALANCE'].values / 10).std()) # how large are the uncertainties of the direct glaciological method !!! observed_std = aet.constant(ref_df['ANNUAL_BALANCE'].values.std()) # std should always be above zero if nosigmastd: glaciological_std = pm.TruncatedNormal('glaciological_std', mu=mod_std, # sigma=sigma_std, observed=observed_std, lower=0.001) # likelihood else: glaciological_std = pm.TruncatedNormal('glaciological_std', mu=mod_std, sigma=sigma_std, observed=observed_std, lower=0.001) # likelihood quot_std = pm.Deterministic("quot_std", glaciological_std / observed_std) # pot_std = pm.Potential('pot_std', aet.switch(mod_std <= 0, -np.inf, 0) ) prior = pm.sample_prior_predictive(random_seed=random_seed, samples=1000) # , keep_size = True) with model_T: # sampling if sampler == 'nuts': trace = pm.sample(25000, chains=3, tune=25000, target_accept=0.99, compute_convergence_checks=True, return_inferencedata=True) # #start={'pf':2.5, 'melt_f': 200}) elif sampler == 'jax': import pymc3.sampling_jax trace = pm.sampling_jax.sample_numpyro_nuts(20000, chains=4, tune=20000, target_accept=0.98) # , compute_convergence_checks= True) burned_trace = trace.sel(draw=slice(5000, None)) burned_trace.posterior['draw'] = np.arange(0, len(burned_trace.posterior.draw)) burned_trace.log_likelihood['draw'] = np.arange(0, len(burned_trace.posterior.draw)) burned_trace.sample_stats['draw'] = np.arange(0, len(burned_trace.posterior.draw)) if first_ppc: print(az.summary(burned_trace.posterior)) ppc = pm.sample_posterior_predictive(burned_trace, random_seed=random_seed, var_names=['geodetic_massbal', 'glaciological_std', 'pf', 'melt_f', 'mb_mod', 'diff_geodetic_massbal', 'quot_std'], keep_size=True) az.concat(burned_trace, az.from_dict(posterior_predictive=ppc, prior=prior), inplace=True) with model_T: slope_pf_new = [] slope_melt_f_new = [] for y in ys: slope_pf, slope_melt_f = get_slope_pf_melt_f(gd_mb, h=h, w=w, ys=y) slope_pf_new.append(slope_pf.mean()) slope_melt_f_new.append(slope_melt_f.mean()) pm.set_data(new_data={'aet_slope_melt_fs_two': slope_melt_f_new, 'aet_slope_pfs_two': slope_pf_new, 'observed': np.empty(len(ys)), 'sigma': np.empty(len(ys))}) ppc_new = pm.sample_posterior_predictive(burned_trace, random_seed=random_seed, var_names=['geodetic_massbal', 'pf', 'melt_f', 'mb_mod', 'diff_geodetic_massbal'], keep_size=True) predict_data = az.from_dict(posterior_predictive=ppc_new) return burned_trace, model_T, predict_data
# ax.plot(energy, y, label=label, lw=0.5, color='orange') ax.plot(energy, gaussian_filter1d(y, sigma=12, mode='nearest'), color=color, label=label, ls='--') # Plot pymc fit spectral fit results together with the fitted SED spectrum from the naima model # build a dummy model. this is weird. i know. wtf pymc? model = pm.Model(theano_config={'compute_test_value': 'ignore'}) with model: amplitude = pm.TruncatedNormal('amplitude', mu=4, sd=1, lower=0.05, testval=0.21) alpha = pm.TruncatedNormal('alpha', mu=2.5, sd=1, lower=0.05, testval=0.21) beta = pm.TruncatedNormal('beta', mu=0.5, sd=0.5, lower=0.001, testval=0.1) mu_s = pm.Deterministic('mu_s', alpha + beta) # dummy function to load traces. mu_b = pm.TruncatedNormal('mu_b', lower=0, shape=2, mu=[1, 2], sd=5) # model has to be on stack to load traces. why? who the f knows telescopes = ['magic', 'fact', 'veritas', 'hess'] for tel in telescopes: config = load_config(tel, config_file='./configs/pymc/data_conf.yaml') trace = pm.load_trace(f'./build/pymc_results/fit/{tel}/traces')
def __init__(self, light_curve, rotation_period, n_spots, contrast, t0, latitude_cutoff=10, partition_lon=True): pm.gp.mean.Mean.__init__(self) if contrast is None: contrast = pm.TruncatedNormal("contrast", lower=0.01, upper=0.99, testval=0.4, mu=0.5, sigma=0.5) self.contrast = contrast self.f0 = pm.TruncatedNormal("f0", mu=0, sigma=1, testval=0, lower=-1, upper=2) self.eq_period = pm.TruncatedNormal("P_eq", lower=0.8 * rotation_period, upper=1.2 * rotation_period, mu=rotation_period, sigma=0.2 * rotation_period, testval=rotation_period) self.ln_shear = pm.Uniform("ln_shear", lower=-5, upper=np.log(0.8), testval=np.log(0.1)) self.comp_inclination = pm.Uniform("comp_inc", lower=0, upper=np.pi / 2, testval=np.radians(1)) if partition_lon: lon_lims = 2 * np.pi * np.arange(n_spots + 1) / n_spots lower = lon_lims[:-1] upper = lon_lims[1:] testval = np.mean([lower, upper], axis=0) else: lower = 0 upper = 2 * np.pi testval = 2 * np.pi * np.arange(n_spots) / n_spots + 0.01 self.lon = pm.Uniform("lon", lower=lower, upper=upper, shape=(1, n_spots), testval=testval) self.lat = pm.Uniform("lat", lower=np.radians(latitude_cutoff), upper=np.radians(180 - latitude_cutoff), shape=(1, n_spots), testval=np.pi / 2) eps = 1e-5 # Small but non-zero number BoundedHalfNormal = pm.Bound(pm.HalfNormal, lower=eps, upper=0.8) self.rspot = BoundedHalfNormal("R_spot", sigma=0.2, shape=(1, n_spots), testval=0.3) self.spot_period = self.eq_period / ( 1 - pm.math.exp(self.ln_shear) * pm.math.sin(self.lat - np.pi / 2)**2) self.sin_lat = pm.math.sin(self.lat) self.cos_lat = pm.math.cos(self.lat) self.sin_c_inc = pm.math.sin(self.comp_inclination) self.cos_c_inc = pm.math.cos(self.comp_inclination) self.t0 = t0
total = pd.DataFrame( dict(death_rate=np.r_[rural, urban], group=np.r_[['rural'] * len(rural), ['urban'] * len(urban)])) # In[60]: mu_total = total.death_rate.mean() std_total = total.death_rate.std() # In[103]: with pm.Model() as model: rural_mean = pm.TruncatedNormal('rural_mean', mu=mu_total, sd=std_total, lower=0, upper=1000) urban_mean = pm.TruncatedNormal('urban_mean', mu=mu_total, sd=std_total, lower=0, upper=1000) # In[104]: std_low = 0 std_high = 10 with model: rural_std = pm.Uniform('rural_std', lower=std_low, upper=std_high)