plt.subplot(2, 4, i+1) plt.scatter(x_m[j:k], y_m[j:k]) plt.xlabel('$x_{}$'.format(i), fontsize=16) plt.ylabel('$y$', fontsize=16, rotation=0) plt.xlim(6, 15) plt.ylim(7, 17) j += N k += N plt.tight_layout() plt.savefig('img417.png') x_centered = x_m - x_m.mean() with pm.Model() as unpooled_model: alpha_tmp = pm.Normal('alpha_tmp', mu=0, sd=10, shape=M) beta = pm.Normal('beta', mu=0, sd=10, shape=M) epsilon = pm.HalfCauchy('epsilon', 5) nu = pm.Exponential('nu', 1/30) ypred = pm.StudentT('y_pred', mu=alpha_tmp[idx] + beta[idx] * x_centered, sd=epsilon, nu=nu, observed=y_m) alpha = pm.Deterministic('alpha', alpha_tmp - beta * x_m.mean()) start = pm.find_MAP() step = pm.NUTS(scaling=start) trace_up = pm.sample(2000, step=step, start=start, njobs=1) varnames = ['alpha', 'beta', 'epsilon', 'nu'] pm.traceplot(trace_up, varnames) plt.savefig('img418.png')
# In[16]: np.array(float_df['weight']) # In[14]: # NOTE: the linear regression model we're trying to solve for is # given by: # y = b0 + b1(x) + error # where b0 is the intercept term, b1 is the slope, and error is # the error # model the intercept/slope terms of our model as # normal random variables with comically large variances with mc3.Model() as model: b0 = mc3.Normal('b0', 0, 0.0003) b1 = mc3.Normal('b1', 0, 0.0003) # model our error term as a uniform random variable err = mc3.Uniform('err', 0, 500) # "model" the observed x values as a normal random variable # in reality, because x is observed, it doesn't actually matter # how we choose to model x -- PyMC isn't going to change x's values x_weight = mc3.Normal('weight', 0, 0.0003, observed=np.array(float_df['weight'])) # this is the heart of our model: given our b0, b1 and our x observations, we want # to predict y
usecols=[1, 2], missing_values="NA", delimiter=",") challenger_data = challenger_data[~np.isnan(challenger_data[:, 1])] plt.figure() plt.scatter(challenger_data[:, 0], challenger_data[:, 1], s=75, color="k", alpha=0.5) # fitting sigmoid function temperature = challenger_data[:,0] D = challenger_data[:,1] def logistic(x, beta, alpha=0): return 1./(1. + np.exp(np.dot(beta, x) + alpha)) if __name__ == '__main__': # needs to be here bc some issues wit pm3(?) with pm.Model() as model: beta = pm.Normal('beta', mu=0., tau=0.001, testval=0.) alpha = pm.Normal('alpha', mu=0., tau=0.001, testval=0.) p = pm.Deterministic('p', 1./(1.+tt.exp(beta*temperature+alpha))) observed = pm.Bernoulli('bernoulli_obs', p, observed=D) # artificially generate credible data sets, from POSTERIOR (not the prior) simulated_data = pm.Bernoulli('simulated-data', p, shape=p.tag.test_value.shape) start = pm.find_MAP() step = pm.Metropolis(vars=[p]) trace = pm.sample(120000, step = step, start=start) burned_trace = trace[100000::2] # 100k burnin, 2 to break the autocorrelation (if any) alpha_samples = burned_trace["alpha"][:, None] beta_samples = burned_trace["beta"][:, None] simulations = burned_trace["bernoulli_sim"] plt.figure() plt.hist(alpha_samples, histtype='stepfilled', bins=35, alpha=0.85,
def test_draw_scalar_parameters(self): with pm.Model(): y = pm.Normal('y1', mu=0., sigma=1.) mu, tau = draw_values([y.distribution.mu, y.distribution.tau]) npt.assert_almost_equal(mu, 0) npt.assert_almost_equal(tau, 1)
kcal_per_g = df_milk['kcal.per.g'].values log_mass = np.log(df_milk['mass'].values) neocortex_perc = df_milk['neocortex.perc'].values fig, ax = plt.subplots(ncols=2) ax[0].plot(log_mass, kcal_per_g, 'b.') ax[1].plot(neocortex_perc, kcal_per_g, 'b.') ax[0].set_xlabel('log.mass') ax[1].set_xlabel('neocortex.perc') ax[0].set_ylabel('mass') plt.show() #%% # Model with single predictor 1 with pm.Model() as model_neocortex: a = pm.Normal('a', mu=0, sigma=100) bl = pm.Normal('bl', mu=0, sigma=1) sigma = pm.Uniform('sigma', lower=0, upper=1) mu = pm.Deterministic('mu', a + bl * neocortex_perc) h = pm.Normal('h', mu=mu, sigma=sigma, observed=kcal_per_g) trace_neocortex = pm.sample(cores=2) # Model with single predictor 2 with pm.Model() as model_log_mass: a = pm.Normal('a', mu=0, sigma=100) br = pm.Normal('br', mu=0, sigma=1) sigma = pm.Uniform('sigma', lower=0, upper=1) mu = pm.Deterministic('mu', a + br * log_mass) h = pm.Normal('h', mu=mu, sigma=sigma, observed=kcal_per_g) trace_log_mass = pm.sample(cores=2)
def gen_mod_bayes( símismo, líms_paráms, obs_x, obs_y, aprioris=None, binario=False, nv_jerarquía=None, í_datos=None, trsld_sub=False ): if pm is None: return ImportError(_('Hay que instalar PyMC3 para poder utilizar modelos bayesianos.')) def _gen_d_vars_pm(tmñ=(), fmt_nmbrs='{}'): egr = {} norm = {} for p, líms in líms_paráms.items(): nmbr = fmt_nmbrs.format(p) if aprioris is None: if líms[0] is líms[1] is None: final = pm.Normal(name=nmbr, mu=0, sd=100 ** 2, shape=tmñ) else: dist_norm = pm.Normal(name='transf' + nmbr, mu=0, sd=1, shape=tmñ) if líms[0] is None: final = pm.Deterministic(nmbr, líms[1] - pm.math.exp(dist_norm)) elif líms[1] is None: final = pm.Deterministic(nmbr, líms[0] + pm.math.exp(dist_norm)) else: final = pm.Deterministic( nmbr, (pm.math.tanh(dist_norm) / 2 + 0.5) * (líms[1] - líms[0]) + líms[0] ) norm[p] = dist_norm else: dist, prms = aprioris[p] if (líms[0] is not None or líms[1] is not None) and dist != pm.Uniform: acotada = pm.Bound(dist, lower=líms[0], upper=líms[1]) final = acotada(nmbr, shape=tmñ, **prms) else: if dist == pm.Uniform: prms['lower'] = max(prms['lower'], líms[0]) prms['upper'] = min(prms['upper'], líms[1]) final = dist(nmbr, shape=tmñ, **prms) egr[p] = final for p, v in egr.items(): if p not in norm: norm[p] = v return {'final': egr, 'norm': norm} def _gen_d_vars_pm_jer(): dists_base = _gen_d_vars_pm( tmñ=(1,), fmt_nmbrs='mu_{}_nv_0' if len(nv_jerarquía) else '{}' )['norm'] egr = {} for p, líms in líms_paráms.items(): mu_v = dists_base[p] if líms[0] is líms[1] is None: mu_sg = 2 else: mu_sg = 0.5 sg_v = pm.Gamma(name='sg_{}_nv_0'.format(p), mu=mu_sg, sd=0.2, shape=(1,)) for í, nv in enumerate(nv_jerarquía): tmñ_nv = len(nv) últ_niv = í == (len(nv_jerarquía) - 1) í_nv = í+1 nmbr_mu = p if últ_niv else 'mu_{}_nv_{}'.format(p, í_nv) nmbr_sg = 'sg_{}_nv_{}'.format(p, í_nv) nmbr_trsld = 'trlsd_{}_nv_{}'.format(p, í_nv) if False and (trsld_sub or últ_niv): trsld = pm.Normal(name=nmbr_trsld, mu=0, sd=1, shape=tmñ_nv) if líms[0] is líms[1] is None: mu_v = pm.Deterministic(nmbr_mu, mu_v[nv] + trsld * sg_v[nv]) else: mu_v = pm.Deterministic('transf' + nmbr_mu, mu_v[nv] + trsld * sg_v[nv]) if líms[0] is None: final = pm.Deterministic(nmbr_mu, líms[1] - pm.math.exp(mu_v)) elif líms[1] is None: final = pm.Deterministic(nmbr_mu, líms[0] + pm.math.exp(mu_v)) else: final = pm.Deterministic( nmbr_mu, (pm.math.tanh(mu_v) / 2 + 0.5) * (líms[1] - líms[0]) + líms[0] ) if últ_niv: mu_v = final else: if líms[0] is líms[1] is None: mu_v = pm.Normal(name=nmbr_mu, mu=mu_v[nv], sd=sg_v[nv], shape=tmñ_nv) else: mu_v = pm.Normal(name='transf' + nmbr_mu, mu=mu_v[nv], sd=sg_v[nv], shape=tmñ_nv) if líms[0] is None: final = pm.Deterministic(nmbr_mu, líms[1] - pm.math.exp(mu_v)) elif líms[1] is None: final = pm.Deterministic(nmbr_mu, líms[0] + pm.math.exp(mu_v)) else: final = pm.Deterministic( nmbr_mu, (pm.math.tanh(mu_v) / 2 + 0.5) * (líms[1] - líms[0]) + líms[0] ) if últ_niv: mu_v = final if not últ_niv: sg_v = pm.Gamma(name=nmbr_sg, mu=mu_sg, sd=0.2, shape=tmñ_nv) egr[p] = mu_v return egr modelo = pm.Model() with modelo: if nv_jerarquía is None: d_vars_pm = _gen_d_vars_pm()['final'] else: d_vars_pm = _gen_d_vars_pm_jer() mu = VstrAPyMC3( d_vars_pm=d_vars_pm, obs_x=obs_x, í_datos=í_datos, dialecto=símismo.dialecto ).convertir(símismo.árbol) if binario: pm.Bernoulli(name='Y_obs', logit_p=mu, observed=obs_y.values) else: sigma = pm.HalfNormal(name='sigma', sd=obs_y.values.std()) # theta = pm.Normal(name='theta', sd=1) # beta = pm.HalfNormal(name='beta', sd=1 / obs_y.values.std()) pm.Normal(name='Y_obs', mu=mu, sd=sigma, # * (beta*pm.math.abs_(mu) + 1), observed=obs_y.values) return modelo
b_left = np.random.uniform(size=N, low=.4, high=.5) b_right = np.random.uniform(size=N, low=.04, high=.05) leg_left = b_left * height + np.random.uniform(size=N, low=0, high=0.02) leg_right = b_right * height + np.random.uniform(size=N, low=0, high=0.02) fig, ax = plt.subplots(ncols=2) ax[0].plot(leg_right, height, 'b.') ax[1].plot(leg_left, height, 'b.') ax[0].set_xlabel('leg_right') ax[1].set_xlabel('leg_left') ax[0].set_ylabel('height') plt.show() # Model with single predictor 1 with pm.Model() as model_bl: a = pm.Normal('a', mu=10, sigma=100) bl = pm.Normal('bl', mu=2, sigma=10) sigma = pm.Uniform('sigma', lower=0, upper=10) mu = pm.Deterministic('mu', a + bl * leg_left) h = pm.Normal('h', mu=mu, sigma=sigma, observed=height) trace_bl = pm.sample(cores=2) # Model with single predictor 2 with pm.Model() as model_br: a = pm.Normal('a', mu=10, sigma=100) br = pm.Normal('br', mu=2, sigma=10) sigma = pm.Uniform('sigma', lower=0, upper=10) mu = pm.Deterministic('mu', a + br * leg_right) h = pm.Normal('h', mu=mu, sigma=sigma, observed=height) trace_br = pm.sample(cores=2)
def build_sho_model(x, y, var_method, test_freq=None, fmin=None, fmax=None, fixed_Q=None): """ Must specify either var or var_method Build PyMC3/exoplanet model for correlated noise using a sum of SHOTerms Parameters ---------- x : array-like independent variable data (e.g. time) y : array-like corresponding dependent variable data (e.g. empirical ACF or flux) var_method : string automatic method for selecting y data variance 'global' --> var = np.var(y) 'local' --> var = np.var(y - local_trend) 'fit' --> logvar is a free hyperparameter in the GP model test_freq : float (optional) an (ordinary, not angular) frequency to initialize the model fmin : float (optional) lower bound on (ordinary, not angular) frequency fmax : float (optional) upper bound on (ordinary, not angular) frequency fixed_Q : float (optional) a fixed value for Q Returns ------- model : a pymc3 model """ with pm.Model() as model: # amplitude parameter logSw4 = pm.Normal('logSw4', mu=np.log(np.var(y)), sd=15.0) # qualify factor if fixed_Q is not None: logQ = pm.Deterministic('logQ', T.log(fixed_Q)) else: logQ = pm.Uniform('logQ', lower=np.log(1 / np.sqrt(2)), upper=np.log(100)) # frequency; for Q > 0.7, the difference between standard and damped frequency is minimal if fmin is None and fmax is None: if test_freq is None: logw0 = pm.Normal('logw0', mu=0.0, sd=15.0) else: test_w0 = convert_frequency(2 * pi * test_freq[0], T.exp(logQ)) logw0 = pm.Normal('logw0', mu=np.log(test_w0), sd=np.log(1.1)) if fmin is not None or fmax is not None: if fmin is None: logwmin = None else: logwmin = np.log(2 * pi * fmin) if fmax is None: logwmax = None else: logwmax = np.log(2 * pi * fmax) if test_freq is None: logw0 = pm.Bound(pm.Normal, lower=logwmin, upper=logwmax)('logw0', mu=0.0, sd=15.0) else: test_w0 = convert_frequency(2 * pi * test_freq[0], T.exp(logQ)) logw0 = pm.Bound(pm.Normal, lower=logwmin, upper=logwmax)('logw0', mu=np.log(test_w0), sd=np.log(1.1)) # here's the kernel kernel = exo.gp.terms.SHOTerm(log_Sw4=logSw4, log_w0=logw0, log_Q=logQ) # set the variance if var_method == 'global': var = np.var(y) elif var_method == 'local': var = np.var(y - boxcar_smooth(y, 29)) elif var_method == 'fit': logvar = pm.Normal('logvar', mu=np.log(astropy.stats.mad_std(y)**2), sd=10.0) var = T.exp(logvar) else: raise ValueError( "Must specify var_method as 'global', 'local', or 'fit'") # set up the GP gp = exo.gp.GP(kernel, x, var * T.ones(len(x))) # add custom potential (log-prob fxn) with the GP likelihood pm.Potential('obs', gp.log_likelihood(y)) # track GP prediction gp_pred = pm.Deterministic('gp_pred', gp.predict()) return model
import os os.chdir('D:\Machine Learning\A-Data Prediction - House') data = pd.read_csv('radon.csv') county_names = data.county.unique() county_idx = data['county_code'].values data[['county', 'log_radon', 'floor']].head() #Hierarchical Model with pm.Model() as hierarchical_model: # Hyperpriors mu_a = pm.Normal('mu_alpha', mu=0., sd=1) sigma_a = pm.HalfCauchy('sigma_alpha', beta=1) mu_b = pm.Normal('mu_beta', mu=0., sd=1) sigma_b = pm.HalfCauchy('sigma_beta', beta=1) # Intercept for each county, distributed around group mean mu_a a = pm.Normal('alpha', mu=mu_a, sd=sigma_a, shape=len(data.county.unique())) # Intercept for each county, distributed around group mean mu_a b = pm.Normal('beta', mu=mu_b, sd=sigma_b, shape=len(data.county.unique())) # Model error eps = pm.HalfCauchy('eps', beta=1) # Expected value radon_est = a[county_idx] + b[county_idx] * data.floor.values
# with pm.Model(): # # a = pm.Normal(name="a") # trace = pm.sample(10000, tune=2000, chains=2) # pm.traceplot(trace, compact=True) # plt.savefig("test_00.png") # pm.autocorrplot(trace, "a") # plt.savefig("test_01.png") # with pm.Model(): # # a = pm.Normal(name="a") # M = pm.LKJCorr(name="C", n=4, eta=1) # trace = pm.sample(10000, tune=2000, chains=2) # pm.traceplot(trace, compact=True) # plt.savefig("test_10.png") # pm.autocorrplot(trace, "a") # plt.savefig("test_11.png") with pm.Model(): a = pm.Normal(name="a", shape=(1, 2)) pm.sample() # f = pm.HalfNormal.dist() # M = pm.LKJCholeskyCov(name="M", n=4, eta=1, sd_dist=f) # trace = pm.sample(10000, tune=2000, chains=2) # pm.traceplot(trace, compact=True) # plt.savefig("test_20.png") # pm.autocorrplot(trace, "a") # plt.savefig("test_21.png")
X = np.array(X) Y = np.array(Y) plt.plot(X) plt.plot(Y) plt.show() Z = Y / X plt.plot(Z) plt.show() with pm.Model() as example2: theta = pm.HalfNormal('theta', sd=1., testval=1.) coeff = pm.HalfNormal('coeff', sd=1., testval=1.) sigma = pm.Normal('sigma', sd=1., testval=1.) sde = lambda x, theta, distance: (theta * (coeff - x), sigma) ts.EulerMaruyama('y', 1.0, sde, [theta, coeff], shape=len(Z), testval=np.ones(len(Z)), observed=Z) trace = pm.sample(10000, tune=10000, nuts_kwargs=dict(target_accept=0.95)) pm.traceplot(trace, varnames=['theta', 'coeff']) plt.show() print "theta = ", np.mean(trace['theta'])
with model_1: # priors as specified in stan model # mu = pm.Uniform('mu', lower = -tt.inf, upper= np.inf) # sigma = pm.Uniform('sigma', lower = 0, upper= np.inf) # using vague priors works mu = pm.Uniform('mu', lower=light_speed.std() / 1000.0, upper=light_speed.std() * 1000.0) sigma = pm.Uniform('sigma', lower=light_speed.std() / 1000.0, upper=light_speed.std() * 1000.0) # define likelihood y_obs = pm.Normal('Y_obs', mu=mu, sd=sigma, observed=light_speed) # inference fitting the model # I have to use slice because the following command # trace = pm.sample(5000) # produce the error # ValueError: Cannot construct a ufunc with more than 32 operands # (requested number were: inputs = 51 and outputs = 1)valueerror def run(n=5000): with model_1: xstart = pm.find_MAP() xstep = pm.Slice() trace = pm.sample(5000,
p[2] + y[2]) - y[0] * (p[5] * p[3] + p[4] * y[2]) / (p[5] + y[2]) + ( -1) * (p[16] * y[0]) ydot[1] = p[16] * y[0] + y[1] * (p[8] * p[6] + p[7] * y[2]) / ( p[8] + y[2]) - y[1] * (p[11] * p[9] + p[10] * y[2]) / ( p[11] + y[2]) + (-1) * (p[18] * y[1]) + (-1) * (p[17] * y[1]) ydot[2] = p[18] * y[1] + y[2] * (p[14] * p[12] + p[13] * (y[0] + y[1])) / ( p[14] + y[0] + y[1]) + (-1) * (p[15] * y[2]) return ydot if __name__ == '__main__': with pm.Model() as pysb_model: sampled_params_list = list() sp_k_NE_div_0 = pm.Normal('sp_k_NE_div_0', mu=np.log10(.428), sigma=.25) sampled_params_list.append(sp_k_NE_div_0) sp_k_NE_div_x = pm.Normal('sp_k_NE_div_x', mu=np.log10(1.05), sigma=1) sampled_params_list.append(sp_k_NE_div_x) sp_KD_Kx_NE_div = pm.Normal('sp_KD_Kx_NE_div', mu=np.log10(1000), sigma=1) sampled_params_list.append(sp_KD_Kx_NE_div) sp_k_NE_die_0 = pm.Normal('sp_k_NE_die_0', mu=np.log10(0.365), sigma=.5) sampled_params_list.append(sp_k_NE_die_0) sp_k_NE_die_x = pm.Normal('sp_k_NE_die_x', mu=np.log10(0.95), sigma=1) sampled_params_list.append(sp_k_NE_die_x)
def test_discrete_continuous(self): with pm.Model() as model: a = pm.Poisson("a", 5) b = pm.HalfNormal("b", 10) y = pm.Normal("y", a, b, observed=[1, 2, 3, 4]) trace = pm.sample_smc()
def setup(self, step): self.n_steps = 10000 with pm.Model() as self.model: pm.Normal('x', mu=0, sd=1)
def MultiOutput_Bayesian_Calibration(n_y,DataComp,DataField,DataPred,output_folder): # This is data preprocessing part n = np.shape(DataField)[0] # number of measured data m = np.shape(DataComp)[0] # number of simulation data p = np.shape(DataField)[1] - n_y # number of input x q = np.shape(DataComp)[1] - p - n_y # number of calibration parameters t xc = DataComp[:,n_y:] # simulation input x + calibration parameters t xf = DataField[:,n_y:] # observed input yc = DataComp[:,:n_y] # simulation output yf = DataField[:,:n_y] # observed output x_pred = DataPred[:,n_y:] # design points for predictions y_true = DataPred[:,:n_y] # true measured value for design points for predictions n_pred = np.shape(x_pred)[0] # number of predictions N = n+m+n_pred # Put points xc, xf, and x_pred on [0,1] for i in range(p): x_min = min(min(xc[:,i]),min(xf[:,i])) x_max = max(max(xc[:,i]),max(xf[:,i])) xc[:,i] = (xc[:,i]-x_min)/(x_max-x_min) xf[:,i] = (xf[:,i]-x_min)/(x_max-x_min) x_pred[:,i] = (x_pred[:,i]-x_min)/(x_max-x_min) # Put calibration parameters t on domain [0,1] for i in range(p,(p+q)): t_min = min(xc[:,i]) t_max = max(xc[:,i]) xc[:,i] = (xc[:,i]-t_min)/(t_max-t_min) # store mean and std of yc for future scale back use yc_mean = np.zeros(n_y) yc_sd = np.zeros(n_y) # standardization of output yf and yc for i in range(n_y): yc_mean[i] = np.mean(yc[:,i]) yc_sd[i] = np.std(yc[:,i]) yc[:,i] = (yc[:,i]-yc_mean[i])/yc_sd[i] yf[:,i] = (yf[:,i]-yc_mean[i])/yc_sd[i] # This is modeling part with pm.Model() as model: # Claim prior part eta1 = pm.HalfCauchy("eta1", beta=5) # for eta of gaussian process lengthscale = pm.Gamma("lengthscale", alpha=2, beta=1, shape=(p+q)) # for lengthscale of gaussian process tf = pm.Beta("tf", alpha=2, beta=2, shape=q) # for calibration parameters sigma1 = pm.HalfCauchy('sigma1', beta=5) # for noise y_pred = pm.Normal('y_pred', 0, 1.5, shape=(n_pred,n_y)) # for y prediction # Setup prior of right cholesky matrix sd_dist = pm.HalfCauchy.dist(beta=2.5, shape=n_y) colchol_packed = pm.LKJCholeskyCov('colcholpacked', n=n_y, eta=2,sd_dist=sd_dist) colchol = pm.expand_packed_triangular(n_y, colchol_packed) # Concate data into a big matrix[[xf tf], [xc tc], [x_pred tf]] xf1 = tt.concatenate([xf, tt.fill(tt.zeros([n,q]), tf)], axis = 1) x_pred1 = tt.concatenate([x_pred, tt.fill(tt.zeros([n_pred,q]), tf)], axis = 1) X = tt.concatenate([xf1, xc, x_pred1], axis = 0) # Concate data into a big matrix[[yf], [yc], [y_pred]] y = tt.concatenate([yf, yc, y_pred], axis = 0) # Covariance funciton of gaussian process cov_z = eta1**2 * pm.gp.cov.ExpQuad((p+q), ls=lengthscale) # Gaussian process with covariance funciton of cov_z gp = MultiMarginal(cov_func = cov_z) # Bayesian inference matrix_shape = [n+m+n_pred,n_y] outcome = gp.marginal_likelihood("outcome", X=X, y=y, colchol=colchol, noise=sigma1, matrix_shape=matrix_shape) trace = pm.sample(250,cores=1) # This part is for data collection and visualization pm.summary(trace).to_csv(output_folder + '/trace_summary.csv') print(pm.summary(trace)) name_columns = [] n_columns = n_pred for i in range(n_columns): for j in range(n_y): name_columns.append('y'+str(j+1)+'_pred'+str(i+1)) y_prediction = pd.DataFrame(np.array(trace['y_pred']).reshape(500,n_pred*n_y),columns=name_columns) #Draw Picture of cvrmse_dist and calculate index for i in range(n_y): index = list(range(0+i,n_pred*n_y+i,n_y)) y_prediction1 = pd.DataFrame(y_prediction.iloc[:,index]) y_prediction1 = y_prediction1*yc_sd[i]+yc_mean[i] # Scale y_prediction back y_prediction1.to_csv(output_folder + '/y_pred'+str(i+1)+'.csv') # Store y_prediction # Calculate the distribution of cvrmse cvrmse = 100*np.sqrt(np.sum(np.square(y_prediction1-y_true[:,i]),axis=1)/n_pred)/np.mean(y_true[:,i]) # Calculate the index and store it into csv index_cal(y_prediction1,y_true[:,i]).to_csv(output_folder + '/index'+str(i+1)+'.csv') # Draw pictrue of cvrmse distribution of each y plt.subplot(n_y, 1, i+1) plt.hist(cvrmse) plt.savefig(output_folder + '/cvrmse_dist.pdf') plt.close() #Draw Picture of Prediction_Plot for i in range(n_y): index = list(range(0+i,n_pred*n_y+i,n_y)) y_prediction_mean = np.array(pm.summary(trace)['mean'][index])*yc_sd[i]+yc_mean[i] y_prediction_975 = np.array(pm.summary(trace)['hpd_97.5'][index])*yc_sd[i]+yc_mean[i] y_prediction_025 = np.array(pm.summary(trace)['hpd_2.5'][index])*yc_sd[i]+yc_mean[i] plt.subplot(n_y, 1, i+1) # estimated probability plt.scatter(x=range(n_pred), y=y_prediction_mean) # error bars on the estimate plt.vlines(range(n_pred), ymin=y_prediction_025, ymax=y_prediction_975) # actual outcomes plt.scatter(x=range(n_pred), y=y_true[:,i], marker='x') plt.xlabel('predictor') plt.ylabel('outcome') # This is just to print original cvrmse to test whether outcome good if i == 0: cvrmse = 100*np.sqrt(np.sum(np.square(y_prediction_mean-y_true[:,0]))/len(y_prediction_mean-y_true[:,0]))/np.mean(y_true[:,0]) print(cvrmse) plt.savefig(output_folder + '/Prediction_Plot.pdf') plt.close()
X = x_cov.merge(x_control, left_index=True, right_index=True) X = X.loc[y.index, :].copy() # standardize all def standardize(x): return (x-np.mean(x))/np.std(x) X = X.apply(standardize, axis=0) # mask NA X_masked = np.ma.masked_invalid(X) # model with pm.Model() as model: # priors intercept = pm.Normal('intercept', mu=0, sigma=100) beta = pm.Normal('beta', mu=0, sigma=100, shape=X_masked.shape[1]) alpha = pm.HalfCauchy('alpha', beta=5) # impute missing X chol, stds, corr = pm.LKJCholeskyCov('chol', n=X_masked.shape[1], eta=2, sd_dist=pm.Exponential.dist(1), compute_corr=True) cov = pm.Deterministic('cov', chol.dot(chol.T)) X_mu = pm.Normal('X_mu', mu=0, sigma=100, shape=X_masked.shape[1], testval=X_masked.mean(axis=0)) X_modeled = pm.MvNormal('X', mu=X_mu, chol=chol, observed=X_masked) # observation mu_ = intercept + tt.dot(X_modeled, beta) # likelihood mu = tt.exp(mu_) likelihood = pm.Gamma('y', alpha=alpha, beta=alpha/mu, observed=y)
# In[28]: reg # In[29]: with pm.Model() as model: # model specifications in PyMC3 # are wrapped in a with-statement # define priors alpha = pm.Normal('alpha', mu=0, sd=20) beta = pm.Normal('beta', mu=0, sd=20) sigma = pm.Uniform('sigma', lower=0, upper=10) # define linear regression y_est = alpha + beta * x # define likelihood likelihood = pm.Normal('y', mu=y_est, sd=sigma, observed=y) # inference start = pm.find_MAP() # find starting value by optimization step = pm.NUTS() # instantiate MCMC sampling algorithm trace = pm.sample(100, step, start=start, progressbar=False)
def _gen_d_vars_pm_jer(): dists_base = _gen_d_vars_pm( tmñ=(1,), fmt_nmbrs='mu_{}_nv_0' if len(nv_jerarquía) else '{}' )['norm'] egr = {} for p, líms in líms_paráms.items(): mu_v = dists_base[p] if líms[0] is líms[1] is None: mu_sg = 2 else: mu_sg = 0.5 sg_v = pm.Gamma(name='sg_{}_nv_0'.format(p), mu=mu_sg, sd=0.2, shape=(1,)) for í, nv in enumerate(nv_jerarquía): tmñ_nv = len(nv) últ_niv = í == (len(nv_jerarquía) - 1) í_nv = í+1 nmbr_mu = p if últ_niv else 'mu_{}_nv_{}'.format(p, í_nv) nmbr_sg = 'sg_{}_nv_{}'.format(p, í_nv) nmbr_trsld = 'trlsd_{}_nv_{}'.format(p, í_nv) if False and (trsld_sub or últ_niv): trsld = pm.Normal(name=nmbr_trsld, mu=0, sd=1, shape=tmñ_nv) if líms[0] is líms[1] is None: mu_v = pm.Deterministic(nmbr_mu, mu_v[nv] + trsld * sg_v[nv]) else: mu_v = pm.Deterministic('transf' + nmbr_mu, mu_v[nv] + trsld * sg_v[nv]) if líms[0] is None: final = pm.Deterministic(nmbr_mu, líms[1] - pm.math.exp(mu_v)) elif líms[1] is None: final = pm.Deterministic(nmbr_mu, líms[0] + pm.math.exp(mu_v)) else: final = pm.Deterministic( nmbr_mu, (pm.math.tanh(mu_v) / 2 + 0.5) * (líms[1] - líms[0]) + líms[0] ) if últ_niv: mu_v = final else: if líms[0] is líms[1] is None: mu_v = pm.Normal(name=nmbr_mu, mu=mu_v[nv], sd=sg_v[nv], shape=tmñ_nv) else: mu_v = pm.Normal(name='transf' + nmbr_mu, mu=mu_v[nv], sd=sg_v[nv], shape=tmñ_nv) if líms[0] is None: final = pm.Deterministic(nmbr_mu, líms[1] - pm.math.exp(mu_v)) elif líms[1] is None: final = pm.Deterministic(nmbr_mu, líms[0] + pm.math.exp(mu_v)) else: final = pm.Deterministic( nmbr_mu, (pm.math.tanh(mu_v) / 2 + 0.5) * (líms[1] - líms[0]) + líms[0] ) if últ_niv: mu_v = final if not últ_niv: sg_v = pm.Gamma(name=nmbr_sg, mu=mu_sg, sd=0.2, shape=tmñ_nv) egr[p] = mu_v return egr
def model(): with pm.Model() as model: x = pm.Normal('x', 0, 1) y = pm.Normal('y', x, 1, observed=2) z = pm.Normal('z', x + y, 1) return model
np.random.seed(123) size = 500 sigma = 5. mu = 13. samples = np.random.normal(mu, sigma, size) # Set censoring limits. high = 16. low = -1. # Truncate samples truncated = samples[(samples > low) & (samples < high)] # Omniscient model with pm.Model() as omniscient_model: mu = pm.Normal('mu', mu=0., sd=(high - low) / 2.) sigma = pm.HalfNormal('sigma', sd=(high - low) / 2.) observed = pm.Normal('observed', mu=mu, sd=sigma, observed=samples) # Imputed censored model # Keep tabs on left/right censoring n_right_censored = len(samples[samples >= high]) n_left_censored = len(samples[samples <= low]) n_observed = len(samples) - n_right_censored - n_left_censored with pm.Model() as imputed_censored_model: mu = pm.Normal('mu', mu=0., sd=(high - low) / 2.) sigma = pm.HalfNormal('sigma', sd=(high - low) / 2.) right_censored = pm.Bound(pm.Normal, lower=high)('right_censored', mu=mu, sd=sigma, shape=n_right_censored)
# generate some data t = np.linspace(0, 1, 20) y = alpha + beta * t + np.random.rand(len(t)) def sys_model(alpha, beta, t): return alpha + beta * t plt.figure() plt.scatter(t, y) line_model = pm.Model() with line_model: # Set up priors alpha = pm.Normal("alpha", mu=0, sigma=10) beta = pm.Normal("beta", mu=0, sigma=10) sigma = pm.HalfNormal("sigma", sigma=1) # System model mu = sys_model(alpha, beta, t) # Likelihood of observations Y = pm.Normal("y", mu=mu, sigma=sigma, observed=y) # Sampler to use step = pm.NUTS() trace = pm.sample(5000, chains=8, cores=4, step=step) map_estimate = pm.find_MAP(model=line_model) print("Map_estimate", map_estimate)
let's simulate some regression dataset and apply PyMC3 to infer the coefficients ''' import pandas as pd import numpy as np import pymc3 as pm if __name__ == "__main__": # ------------------------------------------------------------- # step 1: Create dataset using PyMC3 # y = 1 + 0.5 x # ------------------------------------------------------------- with pm.Model() as generate_model: alpha = pm.Uniform('alpha', lower = 0, upper = 100) x = pm.Normal('x', mu = 10, sd = 2) y = pm.Deterministic('y', alpha + 5 * x) gtrace = pm.sample(5000, step=pm.NUTS()) X = pd.DataFrame( columns = ['x','y'] ) X['x'] = gtrace['x'] X['y'] = gtrace['y'] n_samples = X.shape[0] fig, ax = plt.subplots(1,1, figsize = (12,6)) plt.hist(gtrace['x'], bins = 100, label = 'x', alpha= 0.8) plt.hist(gtrace['alpha'], bins = 100, label = 'alpha', alpha= 0.5) plt.hist(gtrace['y'], bins = 100, label = 'y', alpha= 1) plt.legend() plt.show()
def bayes_estimate_cell(k, adm, eadm, coh, ecoh, alph=False, atype='joint'): """ Function to estimate the parameters of the flexural model at a single cell location of the input grids. :type k: :class:`~numpy.ndarray` :param k: 1D array of wavenumbers :type adm: :class:`~numpy.ndarray` :param adm: 1D array of wavelet admittance :type eadm: :class:`~numpy.ndarray` :param eadm: 1D array of error on wavelet admittance :type coh: :class:`~numpy.ndarray` :param coh: 1D array of wavelet coherence :type ecoh: :class:`~numpy.ndarray` :param ecoh: 1D array of error on wavelet coherence :type alph: bool, optional :param alph: Whether or not to estimate parameter ``alpha`` :type atype: str, optional :param atype: Whether to use the admittance (`'admit'`), coherence (`'coh'`) or both (`'joint'`) :return: (tuple): Tuple containing: * ``trace`` : :class:`~pymc3.backends.base.MultiTrace` Posterior samples from the MCMC chains * ``summary`` : :class:`~pandas.core.frame.DataFrame` Summary statistics from Posterior distributions * ``map_estimate`` : dict Container for Maximum a Posteriori (MAP) estimates """ with pm.Model() as model: # k is an array - needs to be passed as distribution k_obs = pm.Normal('k', mu=k, sigma=1., observed=k) # Prior distributions Te = pm.Uniform('Te', lower=1., upper=250.) F = pm.Uniform('F', lower=0., upper=0.9999) if alph: # Prior distribution of `alpha` alpha = pm.Uniform('alpha', lower=0., upper=np.pi) admit_exp, coh_exp = real_xspec_functions_alpha( k_obs, Te, F, alpha) else: admit_exp, coh_exp = real_xspec_functions_noalpha(k_obs, Te, F) # Select type of analysis to perform if atype == 'admit': # Uncertainty as observed distribution sigma = pm.Normal('sigma', mu=eadm, sigma=1., \ observed=eadm) # Likelihood of observations admit_obs = pm.Normal('admit_obs', mu=admit_exp, \ sigma=sigma, observed=adm) elif atype == 'coh': # Uncertainty as observed distribution sigma = pm.Normal('sigma', mu=ecoh, sigma=1., \ observed=ecoh) # Likelihood of observations coh_obs = pm.Normal('coh_obs', mu=coh_exp, \ sigma=sigma, observed=coh) elif atype == 'joint': # Define uncertainty as concatenated arrays ejoint = np.array([eadm, ecoh]).flatten() # Define array of observations and expected values as concatenated arrays joint = np.array([adm, coh]).flatten() joint_exp = tt.flatten(tt.concatenate([admit_exp, coh_exp])) # Uncertainty as observed distribution sigma = pm.Normal('sigma', mu=ejoint, sigma=1., \ observed=ejoint) # Likelihood of observations joint_obs = pm.Normal('admit_coh_obs', mu=joint_exp, \ sigma=sigma, observed=joint) # Sample the Posterior distribution trace = pm.sample(cf.draws, tune=cf.tunes, cores=cf.cores) # Get Max a porteriori estimate map_estimate = pm.find_MAP() # Get Summary summary = pm.summary(trace) return trace, summary, map_estimate
# -*- coding: utf-8 -*- """ Created on Wed Jul 31 17:11:39 2019 @author: jpeacock """ import numpy as np import pymc3 as pm with pm.Model() as model: s1 = pm.Lognormal("s1", mu=0.01, sigma=0.1) m1 = pm.Normal("m1", mu=1.5, sigma=0.5) p1 = pm.Normal("p1", mu=0.8, sigma=0.2)
_, axes = plt.subplots(1,2,figsize=(8,4)) axes[0].plot(x,y,'C0.') axes[0].set_xlabel('x') axes[0].set_ylabel('y', rotation=0) axes[0].plot(x,y_real,'k') az.plot_kde(y, ax=axes[1]) axes[1].set_xlabel('y') plt.tight_layout() plt.show() # In[3]: with pm.Model() as model_g: α = pm.Normal('α', mu=0, sd=10) β = pm.Normal('β', mu=0, sd=1) ϵ = pm.HalfCauchy('ϵ', 5) μ = pm.Deterministic('μ', α+β*x) y_pred = pm.Normal('y_pred', mu=μ, sd=ϵ, observed=y) trace_g = pm.sample(2000, tune=1000) # Note the new object: `Deterministic`. With this we're telling pyMC3 that mu is defined using a formula, not a probablity distribution. # In[4]: az.plot_trace(trace_g, var_names=['α','β','ϵ'])
b_GC = 0 # direct influence of grandparents on children b_PC = 1 # direct influence of parents on children b_U = 2 # direct influence of neighborhood on parents and children U = 2 * bernoulli.rvs(p=0.5, loc=0, size=N) - 1 G = norm.rvs(loc=0, scale=1, size=N) P = norm.rvs(loc=b_GP * G + b_U * U, scale=1, size=N) C = norm.rvs(loc=b_GC * G + b_U * U + b_PC * P, scale=1, size=N) df = pd.DataFrame({'C': C, 'P': P, 'G': G, 'U': U}) with pm.Model() as m_6_11: a = pm.Normal('a', mu=0, sigma=0.25) b_GC = pm.Normal('b_GC', mu=0, sigma=0.5) b_PC = pm.Normal('b_PC', mu=1, sigma=0.5) sigma = pm.Exponential('sigma', lam=10) mu = a + b_GC * df['G'] + b_PC * df['P'] C = pm.Normal('C', mu=mu, sigma=sigma, observed=df['C']) trace_6_11 = pm.sample(2000, init='advi', tune=2000, return_inferencedata=False) print( '******************Summary for Trace 6.11*******************************') print(
[3.162, 3.162]]) x3_mu, x3_sd = np.array([[50, 60], [3.162, 3.162]]) with pm.Model() as dna_model: g1 = pm.Categorical('g1', p=g1_prob) g2_prob = theano.shared(g2_g1_prob) # make numpy-->theano g2_0 = g2_prob[g1] # select the prob array that "happened" thanks to parents g2 = pm.Categorical('g2', p=g2_0) g3_prob = theano.shared(g3_g1_prob) # make numpy-->theano g3_0 = g3_prob[g1] # select the prob array that "happened" thanks to parents g3 = pm.Categorical('g3', p=g3_0) x2 = pm.Normal('x2', mu=50 + 10*g2, tau=3.162) x3 = pm.Normal('x3', mu=50 + 10*g3, tau=3.162) with dna_model: trace = pm.sample(1) print(pm.summary(trace, varnames=['g1', 'g2', 'g3'], start=1))
def exp_shifted(sample_kwargs=None): clustering_data = pd.read_pickle( 'Data/exp_shifted/exp_shifted_clustering_means_std.pkl') clustering_data.index = range(len(clustering_data)) lin_gp_data = pd.read_csv('Data/exp_shifted/gplinshifted.csv') lin_gp_data.index = range(len(lin_gp_data)) rbf_gp_data = pd.read_csv('Data/exp_shifted/gprbfshifted.csv') rbf_gp_data.index = range(len(rbf_gp_data)) kalman_data = pd.read_pickle('Data/exp_shifted/kalmanshifted.pkl') kalman_data.index = range(len(kalman_data)) bayes_gp_data = pd.read_pickle('Data/exp_shifted/bayes_gp_exp_shifted.pkl') bayes_gp_data.index = range(len(bayes_gp_data)) raw_data = pd.read_csv('Data/exp_shifted/datashifted_withoffset.csv', header=0) # the GP-RBF can fail if subject always choose the same response. For simplicity, we are dropping those # subjects subjects_to_drop = set() for s in set(raw_data.id): if s not in set(rbf_gp_data.id): subjects_to_drop.add(s) for s in subjects_to_drop: clustering_data = clustering_data[ clustering_data['Subject'] != s].copy() lin_gp_data = lin_gp_data[lin_gp_data.id != s].copy() raw_data = raw_data[raw_data.id != s].copy() kalman_data = kalman_data[kalman_data.Subject != s].copy() bayes_gp_data = bayes_gp_data[bayes_gp_data['Subject'] != s].copy() # construct a sticky choice predictor. This is the same for all of the models x_sc = construct_sticky_choice(raw_data) # PYMC3 doesn't care about the actual subject numbers, so remap these to a sequential list subj_idx = construct_subj_idx(lin_gp_data) n_subj = len(set(subj_idx)) intercept = raw_data['int'].values # prep the predictor vectors x_mu_cls = np.array( [clustering_data.loc[:, 'mu_%d' % ii].values for ii in range(8)]).T x_sd_cls = np.array( [clustering_data.loc[:, 'std_%d' % ii].values for ii in range(8)]).T x_mu_lin = np.array([ lin_gp_data.loc[:, 'mu_%d' % ii].values + intercept for ii in range(8) ]).T x_sd_lin = np.array( [lin_gp_data.loc[:, 'std_%d' % ii].values for ii in range(8)]).T x_mu_kal = np.array([ kalman_data.loc[:, 'mu_%d' % ii].values + intercept for ii in range(8) ]).T x_sd_kal = np.array( [kalman_data.loc[:, 'std_%d' % ii].values for ii in range(8)]).T y = raw_data['arm'].values - 1 # convert to 0 indexing n, d = x_mu_cls.shape if sample_kwargs is None: sample_kwargs = dict(draws=2000, njobs=2, tune=2000, init='advi+adapt_diag') with pm.Model() as hier_rbf_clus: mu_1 = pm.Normal('mu_beta_rbf_mean', mu=0., sd=100.) mu_2 = pm.Normal('mu_beta_rbf_stdv', mu=0., sd=100.) mu_3 = pm.Normal('mu_beta_cls_mean', mu=0., sd=100.) mu_4 = pm.Normal('mu_beta_cls_stdv', mu=0., sd=100.) mu_5 = pm.Normal('mu_beta_stick', mu=0., sd=100.) sigma_1 = pm.HalfCauchy('sigma_rbf_means', beta=100) sigma_2 = pm.HalfCauchy('sigma_rbf_stdev', beta=100) sigma_3 = pm.HalfCauchy('sigma_cls_means', beta=100) sigma_4 = pm.HalfCauchy('sigma_cls_stdev', beta=100) sigma_5 = pm.HalfCauchy('sigma_stick', beta=100) b_1 = pm.Normal('beta_rbf_mu', mu=mu_1, sd=sigma_1, shape=n_subj) b_2 = pm.Normal('beta_rbf_std', mu=mu_2, sd=sigma_2, shape=n_subj) b_3 = pm.Normal('beta_cls_mu', mu=mu_3, sd=sigma_3, shape=n_subj) b_4 = pm.Normal('beta_cls_std', mu=mu_4, sd=sigma_4, shape=n_subj) b_5 = pm.Normal('beta_sc', mu=mu_5, sd=sigma_5, shape=n_subj) rho = \ tt.tile(tt.reshape(b_1[subj_idx], (n, 1)), d) * x_mu_rbf + \ tt.tile(tt.reshape(b_2[subj_idx], (n, 1)), d) * x_sd_rbf + \ tt.tile(tt.reshape(b_3[subj_idx], (n, 1)), d) * x_mu_cls + \ tt.tile(tt.reshape(b_4[subj_idx], (n, 1)), d) * x_sd_cls + \ tt.tile(tt.reshape(b_5[subj_idx], (n, 1)), d) * x_sc p_hat = softmax(rho) # Data likelihood yl = pm.Categorical('yl', p=p_hat, observed=y) # inference! trace_gprbf_cls = pm.sample(**sample_kwargs) ppc = pm.sample_ppc(trace_gprbf_cls, samples=500, model=hier_rbf_clus) for ii in range(500): sim_draws = raw_data.copy() sim_draws['arm_sim'] = ppc['yl'][ii, :] + 1 sim_draws.to_pickle('./Data/PPC/exp_shifted/sim_%d.pkl' % ii)
def _create_pymc3_model(self, pm_model, parent, ops): # we are a graph not a tree, so # if name already in pm_model return it # ode models can have multiple outputs, so make # sure to choose the right one if parent is not None: param = LogLikelihoodParameter.objects.get(parent=parent, child=self) # outputs for models are assumed to be unique and ordered # by parent id, outputs for the rest can be non-unique, so use # child_index in this case if self.form == self.Form.MODEL: parents = list(self.parents.order_by()) parent_index = parents.index(parent) else: parent_index = param.child_index else: parent_index = 0 name = self.name try: return ops[name][parent_index] except KeyError: pass values, times, subjects = self.get_data() outputs = list(self.outputs.order_by('child_index')) if len(outputs) == 0: n_distinct_outputs = 0 else: n_distinct_outputs = outputs[-1].child_index + 1 # the distributions need a shape, take this from the data # if no data then assume scalar if self.is_a_distribution(): length_by_index = [()] * n_distinct_outputs for output in outputs: length_by_index[output.child_index] = \ 1 if output.length is None else output.length total_length = sum(length_by_index) # set shape and check total length of outputs is < this shape if values is None: shape = () if total_length > 1: raise RuntimeError( 'log_likelihood {} is scalar but total length of ' 'outputs is {}'.format(self.name, total_length)) else: shape = (len(values), ) if total_length > shape[0]: raise RuntimeError( 'log_likelihood {} has data of length {} but total ' 'length of outputs is {}'.format( self.name, shape[0], total_length)) observed = values if self.observed else None # if its not random, just evaluate it, otherwise create the pymc3 op if not self.is_random(): value = self.sample() if isinstance(value, list): value = np.array(value) op = theano.shared(value) elif self.form == self.Form.NORMAL: mean, sigma = self.get_noise_log_likelihoods() mean = mean._create_pymc3_model(pm_model, self, ops) sigma = sigma._create_pymc3_model(pm_model, self, ops) op = pm.Normal(name, mean, sigma, observed=observed, shape=shape) elif self.form == self.Form.LOGNORMAL: mean, sigma = self.get_noise_log_likelihoods() mean = mean._create_pymc3_model(pm_model, self, ops) sigma = sigma._create_pymc3_model(pm_model, self, ops) op = pm.LogNormal(name, mean, sigma, observed=observed, shape=shape) elif self.form == self.Form.UNIFORM: lower, upper = self.get_noise_log_likelihoods() lower = lower._create_pymc3_model(pm_model, self, ops) upper = upper._create_pymc3_model(pm_model, self, ops) op = pm.Uniform(name, lower, upper, observed=observed, shape=shape) elif self.form == self.Form.MODEL: # ASSUMPTIONS / LIMITATIONS: - parents of models must be observed # random variables (e.g. can't have equation to, say, measure 2 * # model output - subject ids of output data, e.g. [0, 1, 2, 8, 10] # are the same subjects of input data, we only check that the # lengths of the subject vectors are the same output_names = [] times = [] subjects = [] all_subjects = set() for parent in parents: output = LogLikelihoodParameter.objects.get(parent=parent, child=self) _, this_times, this_subjects = parent.get_data() output_names.append(output.variable.qname) times.append(this_times) subjects.append(this_subjects) all_subjects.update(this_subjects) all_subjects = sorted(list(all_subjects)) n_subjects = len(all_subjects) # look at all parameters and check their length, if they are all # scalar values then we can just run 1 sim, if any are vector # values then each value is a different parameter for each subject, # so we need to run a sim for every subject all_params_scalar = all( [p.length is None for p in self.parameters.all()]) if all_params_scalar: subjects = None else: # transform subject ids into an index into all_subjects for i, this_subjects in enumerate(subjects): subjects[i] = np.searchsorted(all_subjects, this_subjects) forward_model, fitted_parameters = self.create_forward_model( output_names, times, subjects) forward_model_op = ODEop(name, forward_model) if fitted_parameters: # create child pymc3 models all_params = [ param.child._create_pymc3_model(pm_model, self, ops) for param in fitted_parameters ] # if any vector params, need to broadcast any scalars to # max_length and create a 2d tensor to pass to the model with # shape (n_params, max_length) if not all_params_scalar: max_length = max([ param.length if param.length is not None else 1 for param in fitted_parameters ]) if max_length != n_subjects: raise RuntimeError( 'Error: n_subjects given by params is ' 'different to n_subjects given by output data.') for index in range(len(all_params)): param = fitted_parameters[index] pymc3_param = all_params[index] if pymc3_param.ndim == 0: all_params[index] = theano.tensor.tile( pymc3_param, (max_length)) # now we stack them along axis 0 all_params = pm.math.stack(all_params, axis=0) else: all_params = [] op = forward_model_op(all_params) # make sure its a list if len(parents) == 1: op = [op] # track outputs of model so we can simulate op = [ pm.Deterministic(name + parent.name, output) for output, parent in zip(op, parents) ] elif self.form == self.Form.EQUATION: params = self.get_noise_log_likelihoods() pymc3_params = [] for param in params: param = param._create_pymc3_model(pm_model, self, ops) pymc3_params.append(param) lcls = { 'arg{}'.format(i): param for i, param in enumerate(pymc3_params) } op = eval(self.description, None, lcls) elif self.form == self.Form.FIXED: if self.biomarker_type is None: op = theano.shared(self.value) else: op = theano.shared(np.array(values)) else: raise RuntimeError('unrecognised form', self.form) # split the op into its distinct outputs if self.form == self.Form.MODEL: ops[name] = op elif n_distinct_outputs == 1: ops[name] = [op] else: indexed_list = [] current_index = 0 for length in length_by_index: indexed_list.append(op[current_index:current_index + length]) ops[name] = indexed_list # if no parent then we don't need to return anything if parent is None: return None return ops[name][parent_index]