def skew_normal_prog(): sample_b = poisson.rvs(lambda_b, size=2500) sample_u = poisson.rvs(mu=lambda_u, size=2500) a_b, loc_b, scale_b = stats.skewnorm.fit(sample_b) a_u, loc_u, scale_u = stats.skewnorm.fit(sample_u) basic_model = pm.Model() with basic_model: x1 = pm.SkewNormal('x1', mu=loc_b, sigma=scale_b, alpha=a_b) x2 = pm.SkewNormal('x2', mu=loc_b, sigma=scale_b, alpha=a_b) u = pm.SkewNormal('u', mu=loc_u, sigma=scale_u, alpha=a_u, observed=x1 + x2) with basic_model: trace = pm.sample(5000) #the two posterior mean are numerically slightly different #we average them skew_mean = np.mean(az.summary(trace)["mean"]) neg_x1 = np.mean(trace.get_values('x1') < 0) neg_x2 = np.mean(trace.get_values('x2') < 0) skew_prob = np.mean([neg_x1, neg_x2]) return (skew_mean, skew_prob)
def initialize_elasticity(N, name=None, b=0.01, alpha=5, sd=1, m_compartments=None, r_compartments=None): """ Initialize the elasticity matrix, adjusting priors to account for reaction stoichiometry. Uses `SkewNormal(mu=0, sd=sd, alpha=sign*alpha)` for reactions in which a metabolite participates, and a `Laplace(mu=0, b=b)` for off-target regulation. Also accepts compartments for metabolites and reactions. If given, metabolites are only given regulatory priors if they come from the same compartment as the reaction. Parameters ========== N : np.ndarray A (nm x nr) stoichiometric matrix for the given reactions and metabolites name : string A name to be used for the returned pymc3 probabilities b : float Hyperprior to use for the Laplace distributions on regulatory interactions alpha : float Hyperprior to use for the SkewNormal distributions. As alpha -> infinity, these priors begin to resemble half-normal distributions. sd : float Scale parameter for the SkewNormal distribution. m_compartments : list Compartments of metabolites. If None, use a densely connected regulatory prior. r_compartments : list Compartments of reactions Returns ======= E : pymc3 matrix constructed elasticity matrix """ if name is None: name = 'ex' if m_compartments is not None: assert r_compartments is not None, \ "reaction and metabolite compartments must both be given" regulation_array = np.array( [[a in b for a in m_compartments] for b in r_compartments]).flatten() else: # If compartment information is not given, assume all metabolites and # reactions are in the same compartment regulation_array = np.array([True] * (N.shape[0] * N.shape[1])) # Guess an elasticity matrix from the smallbone approximation e_guess = -N.T # Find where the guessed E matrix has zero entries e_flat = e_guess.flatten() nonzero_inds = np.where(e_flat != 0)[0] offtarget_inds = np.where(e_flat == 0)[0] e_sign = np.sign(e_flat[nonzero_inds]) # For the zero entries, determine whether regulation is feasible based on # the compartment comparison offtarget_reg = regulation_array[offtarget_inds] reg_inds = offtarget_inds[offtarget_reg] zero_inds = offtarget_inds[~offtarget_reg] num_nonzero = len(nonzero_inds) num_regulations = len(reg_inds) num_zeros = len(zero_inds) # Get an index vector that 'unrolls' a stacked [kinetic, capacity, zero] # vector into the correct order flat_indexer = np.hstack([nonzero_inds, reg_inds, zero_inds]).argsort() if alpha is not None: e_kin_entries = pm.SkewNormal( name + '_kinetic_entries', sd=sd, alpha=alpha, shape=num_nonzero, testval= 0.1 + np.abs(np.random.randn(num_nonzero))) else: e_kin_entries = pm.HalfNormal( name + '_kinetic_entries', sd=sd, shape=num_nonzero, testval= 0.1 + np.abs(np.random.randn(num_nonzero))) e_cap_entries = pm.Laplace( name + '_capacity_entries', mu=0, b=b, shape=num_regulations, testval=b * np.random.randn(num_regulations)) flat_e_entries = T.concatenate( [e_kin_entries * e_sign, # kinetic entries e_cap_entries, # capacity entries T.zeros(num_zeros)]) # different compartments E = flat_e_entries[flat_indexer].reshape(N.T.shape) return E
def nn_hbr(X, y, batch_effects, batch_effects_size, configs, trace=None): n_hidden = configs['nn_hidden_neuron_num'] n_layers = configs['nn_hidden_layers_num'] feature_num = X.shape[1] batch_effects_num = batch_effects.shape[1] all_idx = [] for i in range(batch_effects_num): all_idx.append(np.int16(np.unique(batch_effects[:, i]))) be_idx = list(product(*all_idx)) X = theano.shared(X) y = theano.shared(y) # Initialize random weights between each layer for the mu: init_1 = pm.floatX( np.random.randn(feature_num, n_hidden) * np.sqrt(1 / feature_num)) init_out = pm.floatX(np.random.randn(n_hidden) * np.sqrt(1 / n_hidden)) std_init_1 = pm.floatX(np.random.rand(feature_num, n_hidden)) std_init_out = pm.floatX(np.random.rand(n_hidden)) # And initialize random weights between each layer for sigma_noise: init_1_noise = pm.floatX( np.random.randn(feature_num, n_hidden) * np.sqrt(1 / feature_num)) init_out_noise = pm.floatX( np.random.randn(n_hidden) * np.sqrt(1 / n_hidden)) std_init_1_noise = pm.floatX(np.random.rand(feature_num, n_hidden)) std_init_out_noise = pm.floatX(np.random.rand(n_hidden)) # If there are two hidden layers, then initialize weights for the second layer: if n_layers == 2: init_2 = pm.floatX( np.random.randn(n_hidden, n_hidden) * np.sqrt(1 / n_hidden)) std_init_2 = pm.floatX(np.random.rand(n_hidden, n_hidden)) init_2_noise = pm.floatX( np.random.randn(n_hidden, n_hidden) * np.sqrt(1 / n_hidden)) std_init_2_noise = pm.floatX(np.random.rand(n_hidden, n_hidden)) with pm.Model() as model: if trace is not None: # Used when estimating/predicting on a new site weights_in_1_grp = from_posterior('w_in_1_grp', trace['w_in_1_grp'], distribution='normal') weights_in_1_grp_sd = from_posterior('w_in_1_grp_sd', trace['w_in_1_grp_sd'], distribution='hcauchy') if n_layers == 2: weights_1_2_grp = from_posterior('w_1_2_grp', trace['w_1_2_grp'], distribution='normal') weights_1_2_grp_sd = from_posterior('w_1_2_grp_sd', trace['w_1_2_grp_sd'], distribution='hcauchy') weights_2_out_grp = from_posterior('w_2_out_grp', trace['w_2_out_grp'], distribution='normal') weights_2_out_grp_sd = from_posterior('w_2_out_grp_sd', trace['w_2_out_grp_sd'], distribution='hcauchy') mu_prior_intercept = from_posterior('mu_prior_intercept', trace['mu_prior_intercept'], distribution=None) #sigma_prior_intercept = from_posterior('sigma_prior_intercept', trace['sigma_prior_intercept'], # distribution='hcauchy') else: # Group the mean distribution for input to the hidden layer: weights_in_1_grp = pm.Normal('w_in_1_grp', 0, sd=1, shape=(feature_num, n_hidden), testval=init_1) # Group standard deviation: weights_in_1_grp_sd = pm.HalfCauchy('w_in_1_grp_sd', 1., shape=(feature_num, n_hidden), testval=std_init_1) if n_layers == 2: # Group the mean distribution for hidden layer 1 to hidden layer 2: weights_1_2_grp = pm.Normal('w_1_2_grp', 0, sd=1, shape=(n_hidden, n_hidden), testval=init_2) # Group standard deviation: weights_1_2_grp_sd = pm.HalfCauchy('w_1_2_grp_sd', 1., shape=(n_hidden, n_hidden), testval=std_init_2) # Group the mean distribution for hidden to output: weights_2_out_grp = pm.Normal('w_2_out_grp', 0, sd=1, shape=(n_hidden, ), testval=init_out) # Group standard deviation: weights_2_out_grp_sd = pm.HalfCauchy('w_2_out_grp_sd', 1., shape=(n_hidden, ), testval=std_init_out) mu_prior_intercept = pm.Uniform('mu_prior_intercept', lower=-100, upper=100) #sigma_prior_intercept = pm.HalfCauchy('sigma_prior_intercept', 5) # Now create separate weights for each group, by doing # weights * group_sd + group_mean, we make sure the new weights are # coming from the (group_mean, group_sd) distribution. weights_in_1_raw = pm.Normal('w_in_1', 0, sd=1, shape=(batch_effects_size + [feature_num, n_hidden])) weights_in_1 = weights_in_1_raw * weights_in_1_grp_sd + weights_in_1_grp if n_layers == 2: weights_1_2_raw = pm.Normal('w_1_2', 0, sd=1, shape=(batch_effects_size + [n_hidden, n_hidden])) weights_1_2 = weights_1_2_raw * weights_1_2_grp_sd + weights_1_2_grp weights_2_out_raw = pm.Normal('w_2_out', 0, sd=1, shape=(batch_effects_size + [n_hidden])) weights_2_out = weights_2_out_raw * weights_2_out_grp_sd + weights_2_out_grp intercepts_offset = pm.Normal('intercepts_offset', mu=0, sd=1, shape=(batch_effects_size)) intercepts = pm.Deterministic('intercepts', intercepts_offset + mu_prior_intercept) # Build the neural network and estimate y_hat: y_hat = theano.tensor.zeros(y.shape) for be in be_idx: # Find the indices corresponding to 'group be': a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: act_1 = pm.math.tanh( theano.tensor.dot(X[idx, :], weights_in_1[be])) if n_layers == 2: act_2 = pm.math.tanh( theano.tensor.dot(act_1, weights_1_2[be])) y_hat = theano.tensor.set_subtensor( y_hat[idx, 0], intercepts[be] + theano.tensor.dot(act_2, weights_2_out[be])) else: y_hat = theano.tensor.set_subtensor( y_hat[idx, 0], intercepts[be] + theano.tensor.dot(act_1, weights_2_out[be])) # If we want to estimate varying noise terms across groups: if configs['random_noise']: if configs['hetero_noise']: if trace is not None: # # Used when estimating/predicting on a new site weights_in_1_grp_noise = from_posterior( 'w_in_1_grp_noise', trace['w_in_1_grp_noise'], distribution='normal') weights_in_1_grp_sd_noise = from_posterior( 'w_in_1_grp_sd_noise', trace['w_in_1_grp_sd_noise'], distribution='hcauchy') if n_layers == 2: weights_1_2_grp_noise = from_posterior( 'w_1_2_grp_noise', trace['w_1_2_grp_noise'], distribution='normal') weights_1_2_grp_sd_noise = from_posterior( 'w_1_2_grp_sd_noise', trace['w_1_2_grp_sd_noise'], distribution='hcauchy') weights_2_out_grp_noise = from_posterior( 'w_2_out_grp_noise', trace['w_2_out_grp_noise'], distribution='normal') weights_2_out_grp_sd_noise = from_posterior( 'w_2_out_grp_sd_noise', trace['w_2_out_grp_sd_noise'], distribution='hcauchy') else: # The input layer to the first hidden layer: weights_in_1_grp_noise = pm.Normal('w_in_1_grp_noise', 0, sd=1, shape=(feature_num, n_hidden), testval=init_1_noise) weights_in_1_grp_sd_noise = pm.HalfCauchy( 'w_in_1_grp_sd_noise', 1, shape=(feature_num, n_hidden), testval=std_init_1_noise) # The first hidden layer to second hidden layer: if n_layers == 2: weights_1_2_grp_noise = pm.Normal('w_1_2_grp_noise', 0, sd=1, shape=(n_hidden, n_hidden), testval=init_2_noise) weights_1_2_grp_sd_noise = pm.HalfCauchy( 'w_1_2_grp_sd_noise', 1, shape=(n_hidden, n_hidden), testval=std_init_2_noise) # The second hidden layer to output layer: weights_2_out_grp_noise = pm.Normal('w_2_out_grp_noise', 0, sd=1, shape=(n_hidden, ), testval=init_out_noise) weights_2_out_grp_sd_noise = pm.HalfCauchy( 'w_2_out_grp_sd_noise', 1, shape=(n_hidden, ), testval=std_init_out_noise) #mu_prior_intercept_noise = pm.HalfNormal('mu_prior_intercept_noise', sigma=1e3) #sigma_prior_intercept_noise = pm.HalfCauchy('sigma_prior_intercept_noise', 5) # Now create separate weights for each group: weights_in_1_raw_noise = pm.Normal( 'w_in_1_noise', 0, sd=1, shape=(batch_effects_size + [feature_num, n_hidden])) weights_in_1_noise = weights_in_1_raw_noise * weights_in_1_grp_sd_noise + weights_in_1_grp_noise if n_layers == 2: weights_1_2_raw_noise = pm.Normal( 'w_1_2_noise', 0, sd=1, shape=(batch_effects_size + [n_hidden, n_hidden])) weights_1_2_noise = weights_1_2_raw_noise * weights_1_2_grp_sd_noise + weights_1_2_grp_noise weights_2_out_raw_noise = pm.Normal('w_2_out_noise', 0, sd=1, shape=(batch_effects_size + [n_hidden])) weights_2_out_noise = weights_2_out_raw_noise * weights_2_out_grp_sd_noise + weights_2_out_grp_noise #intercepts_offset_noise = pm.Normal('intercepts_offset_noise', mu=0, sd=1, # shape=(batch_effects_size)) #intercepts_noise = pm.Deterministic('intercepts_noise', mu_prior_intercept_noise + # intercepts_offset_noise * sigma_prior_intercept_noise) # Build the neural network and estimate the sigma_y: sigma_y = theano.tensor.zeros(y.shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: act_1_noise = pm.math.sigmoid( theano.tensor.dot(X[idx, :], weights_in_1_noise[be])) if n_layers == 2: act_2_noise = pm.math.sigmoid( theano.tensor.dot(act_1_noise, weights_1_2_noise[be])) temp = pm.math.log1pexp( theano.tensor.dot( act_2_noise, weights_2_out_noise[be])) + 1e-5 else: temp = pm.math.log1pexp( theano.tensor.dot( act_1_noise, weights_2_out_noise[be])) + 1e-5 sigma_y = theano.tensor.set_subtensor( sigma_y[idx, 0], temp) else: # homoscedastic noise: sigma_noise = pm.Uniform('sigma_noise', lower=0, upper=100, shape=(batch_effects_size)) sigma_y = theano.tensor.zeros(y.shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: sigma_y = theano.tensor.set_subtensor( sigma_y[idx, 0], sigma_noise[be]) else: # do not allow for random noise terms across groups: sigma_noise = pm.Uniform('sigma_noise', lower=0, upper=100) sigma_y = theano.tensor.zeros(y.shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: sigma_y = theano.tensor.set_subtensor( sigma_y[idx, 0], sigma_noise) if configs['skewed_likelihood']: skewness = pm.Uniform('skewness', lower=-10, upper=10, shape=(batch_effects_size)) alpha = theano.tensor.zeros(y.shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: alpha = theano.tensor.set_subtensor( alpha[idx, 0], skewness[be]) else: alpha = 0 # symmetrical normal distribution y_like = pm.SkewNormal('y_like', mu=y_hat, sigma=sigma_y, alpha=alpha, observed=y) return model
def hbr(X, y, batch_effects, batch_effects_size, configs, trace=None): feature_num = X.shape[1] y_shape = y.shape batch_effects_num = batch_effects.shape[1] all_idx = [] for i in range(batch_effects_num): all_idx.append(np.int16(np.unique(batch_effects[:, i]))) be_idx = list(product(*all_idx)) X = theano.shared(X) y = theano.shared(y) with pm.Model() as model: # Priors if trace is not None: # Used for transferring the priors mu_prior_intercept = from_posterior('mu_prior_intercept', trace['mu_prior_intercept'], distribution=None) mu_prior_slope = from_posterior('mu_prior_slope', trace['mu_prior_slope'], distribution='normal') sigma_prior_slope = from_posterior('sigma_prior_slope', trace['sigma_prior_slope'], distribution='hcauchy') else: #mu_prior_intercept = pm.Normal('mu_prior_intercept', mu=0., sigma=1e3) mu_prior_intercept = pm.Uniform('mu_prior_intercept', lower=-100, upper=100) mu_prior_slope = pm.Normal('mu_prior_slope', mu=0., sigma=1e3, shape=(feature_num, )) sigma_prior_slope = pm.HalfCauchy('sigma_prior_slope', 5, shape=(feature_num, )) if configs['random_intercept']: intercepts_offset = pm.Normal('intercepts_offset', mu=0, sd=1, shape=(batch_effects_size)) else: intercepts_offset = pm.Normal('intercepts_offset', mu=0, sd=1) intercepts = pm.Deterministic('intercepts', mu_prior_intercept + intercepts_offset) if configs['random_slope']: # Random slopes slopes_offset = pm.Normal('slopes_offset', mu=0, sd=1, shape=(batch_effects_size + [feature_num])) else: slopes_offset = pm.Normal('slopes_offset', mu=0, sd=1) slopes = pm.Deterministic( 'slopes', mu_prior_slope + slopes_offset * sigma_prior_slope) y_hat = theano.tensor.zeros(y_shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: if (not configs['random_intercept'] and not configs['random_slope']): y_hat = theano.tensor.set_subtensor( y_hat[idx, 0], intercepts + theano.tensor.dot(X[idx, :], slopes)) elif (configs['random_intercept'] and not configs['random_slope']): y_hat = theano.tensor.set_subtensor( y_hat[idx, 0], intercepts[be] + theano.tensor.dot(X[idx, :], slopes)) elif (not configs['random_intercept'] and configs['random_slope']): y_hat = theano.tensor.set_subtensor( y_hat[idx, 0], intercepts + theano.tensor.dot(X[idx, :], slopes[be])) elif (configs['random_intercept'] and configs['random_slope']): y_hat = theano.tensor.set_subtensor( y_hat[idx, 0], intercepts[be] + theano.tensor.dot(X[idx, :], slopes[be])) if configs['random_noise']: if configs['hetero_noise']: # Priors if trace is not None: # Used for transferring the priors mu_prior_intercept_noise = from_posterior( 'mu_prior_intercept_noise', trace['mu_prior_intercept_noise'], distribution=None) #sigma_prior_intercept_noise = from_posterior('sigma_prior_intercept_noise', # trace['sigma_prior_intercept_noise'], # distribution='hcauchy') mu_prior_slope_noise = from_posterior( 'mu_prior_slope_noise', trace['mu_prior_slope_noise'], distribution='normal') sigma_prior_slope_noise = from_posterior( 'sigma_prior_slope_noise', trace['sigma_prior_slope_noise'], distribution='hcauchy') else: #mu_prior_intercept_noise = pm.HalfNormal('mu_prior_intercept_noise', # sigma=1e3) mu_prior_intercept_noise = pm.Uniform( 'mu_prior_intercept_noise', lower=0, upper=100) #sigma_prior_intercept_noise = pm.HalfCauchy('sigma_prior_intercept_noise', 5) mu_prior_slope_noise = pm.Normal('mu_prior_slope_noise', mu=0., sigma=1e3, shape=(feature_num, )) sigma_prior_slope_noise = pm.HalfCauchy( 'sigma_prior_slope_noise', 5, shape=(feature_num, )) if configs['random_intercept']: intercepts_noise_offset = pm.Normal( 'intercepts_noise_offset', sd=1, shape=(batch_effects_size)) else: intercepts_noise_offset = pm.Normal( 'intercepts_noise_offset', sd=1) intercepts_noise = pm.Deterministic( 'intercepts_noise', mu_prior_intercept_noise + intercepts_noise_offset) if configs['random_slope']: slopes_noise_offset = pm.Normal('slopes_noise_offset', mu=0, sd=1, shape=(batch_effects_size + [feature_num])) else: slopes_noise_offset = pm.Normal('slopes_noise_offset', mu=0, sd=1) slopes_noise = pm.Deterministic( 'slopes_noise', mu_prior_slope_noise + slopes_noise_offset * sigma_prior_slope_noise) sigma_noise = theano.tensor.zeros(y_shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: if (not configs['random_intercept'] and not configs['random_slope']): sigma_noise = theano.tensor.set_subtensor( sigma_noise[idx, 0], intercepts_noise + theano.tensor.dot(X[idx, :], slopes_noise)) elif (configs['random_intercept'] and not configs['random_slope']): sigma_noise = theano.tensor.set_subtensor( sigma_noise[idx, 0], intercepts_noise[be] + theano.tensor.dot(X[idx, :], slopes_noise)) elif (not configs['random_intercept'] and configs['random_slope']): sigma_noise = theano.tensor.set_subtensor( sigma_noise[idx, 0], intercepts_noise + theano.tensor.dot(X[idx, :], slopes_noise[be])) elif (configs['random_intercept'] and configs['random_slope']): sigma_noise = theano.tensor.set_subtensor( sigma_noise[idx, 0], intercepts_noise[be] + theano.tensor.dot(X[idx, :], slopes_noise[be])) sigma_y = pm.math.log1pexp(sigma_noise) + 1e-5 else: sigma_noise = pm.Uniform('sigma_noise', lower=0, upper=100, shape=(batch_effects_size)) sigma_y = theano.tensor.zeros(y_shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: sigma_y = theano.tensor.set_subtensor( sigma_y[idx, 0], sigma_noise[be]) else: sigma_noise = pm.Uniform('sigma_noise', lower=0, upper=100) sigma_y = theano.tensor.zeros(y_shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: sigma_y = theano.tensor.set_subtensor( sigma_y[idx, 0], sigma_noise) if configs['skewed_likelihood']: skewness = pm.Uniform('skewness', lower=-10, upper=10, shape=(batch_effects_size)) alpha = theano.tensor.zeros(y_shape) for be in be_idx: a = [] for i, b in enumerate(be): a.append(batch_effects[:, i] == b) idx = reduce(np.logical_and, a).nonzero() if idx[0].shape[0] != 0: alpha = theano.tensor.set_subtensor( alpha[idx, 0], skewness[be]) else: alpha = 0 y_like = pm.SkewNormal('y_like', mu=y_hat, sigma=sigma_y, alpha=alpha, observed=y) return model
'r-', lw=3, label='skewnorm pdf') # %% with pm.Model() as duration_model: # Three parameters to sample alpha_skew = pm.Normal('alpha_skew', mu=0, tau=0.5, testval=3.0) mu_ = pm.Normal('mu', mu=0, tau=0.5, testval=7.4) tau_ = pm.Normal('tau', mu=0, tau=0.5, testval=1.0) # Duration is a deterministic variable duration_ = pm.SkewNormal('duration', alpha=alpha_skew, mu=mu_, sd=1 / tau_, observed=duration) # Metropolis Hastings for sampling step = pm.Metropolis() # duration_trace = pm.sample(N_SAMPLES, step=step) duration_trace = pm.sample(N_SAMPLES, step=step, cores=1) # %% # Extract the most likely estimates from the sampling alpha_skew_samples = duration_trace['alpha_skew'][5000:] mu_samples = duration_trace['mu'][5000:] tau_samples = duration_trace['tau'][5000:]
def _build_gains_mu(self, is_author_is): self.dims.update({ 'gains_theta': ('algo', ), 'gains_eta': ('algo', ), 'author_is': ('algo', ), 'author_is_raw': ('algo', ), 'gains': ('algo', ), 'gains_raw': ('algo', ), }) shrinkage = self.params.pop('shrinkage') k = self.n_algos # Define shrinkage model on the long-term gains if shrinkage == 'exponential-mix': gains_sd = pm.HalfNormal('gains_sd', sd=0.2) pm.Deterministic('log_gains_sd', tt.log(gains_sd)) gains_theta = pm.Exponential('gains_theta', lam=1, shape=k) gains_eta = pm.Normal('gains_eta', shape=k) author_is = pm.Normal('author_is', shape=k) gains = gains_sd * gains_theta * gains_eta gains = pm.Deterministic('gains', gains) gains_all = gains[None, :] + author_is[None, :] * is_author_is elif shrinkage == 'exponential': gains_sd = pm.HalfNormal('gains_sd', sd=0.1) pm.Deterministic('log_gains_sd', tt.log(gains_sd)) gains_raw = pm.Laplace('gains_raw', mu=0, b=1, shape=k) author_is = pm.Normal('author_is', shape=k) gains = pm.Deterministic('gains', gains_sd * gains_raw) gains_all = gains[None, :] + author_is[None, :] * is_author_is elif shrinkage == 'student': gains_sd = pm.HalfNormal('gains_sd', sd=0.2) pm.Deterministic('log_gains_sd', tt.log(gains_sd)) gains_raw = pm.StudentT('gains_raw', nu=4, mu=0, sd=1, shape=k) author_is = pm.Normal('author_is', shape=k) gains = pm.Deterministic('gains', gains_sd * gains_raw) gains_all = gains[None, :] + author_is[None, :] * is_author_is elif shrinkage == 'normal': gains_sd = pm.HalfNormal('gains_sd', sd=0.1) pm.Deterministic('log_gains_sd', tt.log(gains_sd)) gains_mu = pm.Normal('gains_mu', mu=0.05, sd=0.1) gains_raw = pm.Normal('gains_raw', shape=k) author_is = pm.HalfNormal('author_is', shape=k, sd=0.1) gains = pm.Deterministic('gains', gains_sd * gains_raw + gains_mu) gains_all = gains[None, :] + author_is[None, :] * is_author_is elif shrinkage == 'skew-neg2-normal': gains_sd = pm.HalfNormal('gains_sd', sd=0.1) pm.Deterministic('log_gains_sd', tt.log(gains_sd)) gains_mu = pm.Normal('gains_mu', sd=0.1) gains_raw = pm.SkewNormal('gains_raw', sd=1, mu=0, alpha=-4, shape=k) author_is = pm.Normal('author_is', shape=k, sd=0.4, mu=0.0) gains = pm.Deterministic('gains', gains_sd * gains_raw + gains_mu) gains_all = ((1 - is_author_is) * gains[None, :] + author_is[None, :] * is_author_is) elif shrinkage == 'skew-normal': gains_sd = pm.HalfNormal('gains_sd', sd=0.1) pm.Deterministic('log_gains_sd', tt.log(gains_sd)) gains_alpha = pm.Normal('gains_alpha', sd=0.3) gains_mu = pm.Normal('gains_mu', mu=0.05, sd=0.1) gains_raw = pm.SkewNormal('gains_raw', sd=1, mu=0, alpha=gains_alpha, shape=k) author_is = pm.Normal('author_is', shape=k) gains = pm.Deterministic('gains', gains_sd * gains_raw + gains_mu) gains_all = gains[None, :] + author_is[None, :] * is_author_is elif shrinkage == 'trace-exponential': mu = self.params.pop('log_gains_sd_trace_mu') sd = self.params.pop('log_gains_sd_trace_sd') log_gains_sd = pm.Normal('log_gains_sd', mu=mu, sd=sd) gains_sd = pm.Deterministic('gains_sd', tt.exp(log_gains_sd)) gains_raw = pm.Laplace('gains_raw', mu=0, b=1, shape=k) author_is = pm.Normal('author_is', shape=k) gains = pm.Deterministic('gains', gains_sd * gains_raw) gains_all = gains[None, :] + author_is[None, :] * is_author_is elif shrinkage == 'trace-normal': mu = self.params.pop('log_gains_sd_trace_mu') sd = self.params.pop('log_gains_sd_trace_sd') log_gains_sd = pm.Normal('log_gains_sd', mu=mu, sd=sd) gains_sd = pm.Deterministic('gains_sd', tt.exp(log_gains_sd)) gains_raw = pm.Normal('gains_raw', shape=k) author_is = pm.Normal('author_is', shape=k) gains = pm.Deterministic('gains', gains_sd * gains_raw) gains_all = gains[None, :] + author_is[None, :] * is_author_is else: raise ValueError('Unknown gains model: %s' % shrinkage) return gains_all.T
def sleep_time_mode_use(): raw_data = pd.read_csv( 'D:/weChatFile/WeChat Files/wxid_fg4c7ci7wpud21/FileStorage/File/2021-04/sleep_wake.csv' ) raw_data['length'] = 8 - (raw_data['Sleep'] / 60) + (raw_data['Wake'] / 60) duration = raw_data['length'] # -----------------------------睡眠时间长度------------------------------------------------------------- figsize(10, 8) plt.hist(duration, bins=20, color='darkred') plt.xlabel('小时') plt.title('睡眠时间长度分布') plt.ylabel('观测值') plt.show() # ---------------------------右偏睡眠时间长度概率密度---------------------------------------- a = 3 fig, ax = plt.subplots(1, 1) x = np.linspace(6, 12, int(1e3)) figsize(10, 8) plt.hist(duration, bins=20, color='darkred', density=1, stacked=True) plt.xlabel('小时') plt.title('右偏的睡眠时间长度的概率密度(PDF)') plt.ylabel('观测值') plt.plot(x, stats.skewnorm.pdf(x, a, loc=7.4, scale=1), 'r-', lw=3, label='skewnorm pdf') plt.show() # ------------------------------睡眠长度概率模型-------------------------------------------------- with pm.Model() as duration_model: # 定义三个参数的先验概率分布其中我们增加了一个偏度参数alpha_skew alpha_skew = pm.Normal('alpha_skew', mu=0, tau=0.5, testval=3.0) mu_ = pm.Normal('mu', mu=0, tau=0.5, testval=7.4) tau_ = pm.Normal('tau', mu=0, tau=0.5, testval=1.0) # Duration 为一个确定性变量 duration_ = pm.SkewNormal('duration', alpha=alpha_skew, mu=mu_, sd=1 / tau_, observed=duration) # Metropolis Hastings 抽样 step = pm.Metropolis() duration_trace = pm.sample(N_SAMPLES, step=step) # --------------------抽取最有可能的估值参数--------------------------------------------------------- # 抽取最有可能的估值参数 alpha_skew_samples = duration_trace['alpha_skew'][1000:] mu_samples = duration_trace['mu'][1000:] tau_samples = duration_trace['tau'][1000:] alpha_skew_est = alpha_skew_samples.mean() mu_est = mu_samples.mean() tau_est = tau_samples.mean() # -----------------------睡眠长度后验分布长度可视化------------------------------------------------------- x = np.linspace(6, 12, 1000) y = stats.skewnorm.pdf(x, a=alpha_skew_est, loc=mu_est, scale=1 / tau_est) plt.plot(x, y, color='forestgreen') plt.fill_between(x, y, color='forestgreen', alpha=0.2) plt.xlabel('小时') plt.ylabel('概率') plt.title('睡眠时间长度的后验分布') plt.vlines(x=x[np.argmax(y)], ymin=0, ymax=y.max(), linestyles='--', linewidth=2, color='red', label='最可能的睡眠时间长度') plt.show() print('最可能的睡眠时间长度为 {:.2f} 小时.'.format(x[np.argmax(y)])) # -----------------------查询后验概率模型-------------------------------------------------------------- print('睡眠时间至少6.5小时的概率为:{:.2f}%.'.format(100 * (1 - stats.skewnorm.cdf( 6.5, a=alpha_skew_est, loc=mu_est, scale=1 / tau_est)))) print('睡眠时间至少8小时的概率为:{:.2f}%.'.format(100 * (1 - stats.skewnorm.cdf( 8.0, a=alpha_skew_est, loc=mu_est, scale=1 / tau_est)))) print('睡眠时间至少9小时的概率为:{:.2f}%.'.format(100 * (1 - stats.skewnorm.cdf( 9.0, a=alpha_skew_est, loc=mu_est, scale=1 / tau_est)))) # -------------------------可视化后验和数据------------------------------------------------------------------------------------- x = np.linspace(6, 12, 1000) y = stats.skewnorm.pdf(x, a=alpha_skew_est, loc=mu_est, scale=1 / tau_est) figsize(10, 8) # 绘制后验概率分布 plt.plot(x, y, color='forestgreen', label='Model', lw=3) plt.fill_between(x, y, color='forestgreen', alpha=0.2) # 绘制观测值直方图 plt.hist(duration, bins=10, color='red', alpha=0.8, label='观测值', density=1, stacked=True) plt.xlabel('小时') plt.ylabel('概率') plt.title('模型') plt.vlines(x=x[np.argmax(y)], ymin=0, ymax=y.max(), linestyles='--', linewidth=2, color='k', label='最可能的睡眠时间长度') plt.legend(prop={'size': 12}) plt.show()
def bayesian_regression_modeling(df, label_col, target_col, prior_distribution_list, draw_sample=1000, chains=2, scaling_opt=3): """ :param df: :param label_col: :param target_col: :param model_option: :param draw_sample: :param chains: :param alpha_1: :param alpha_2: :param lambda_1: :param lambda_2: :return: MCMC mean trace array, MCMC visualization img source """ # test: using scaling n_individuals = len(df) print("scale@@@@@",df) if scaling_opt == 1: df[df.columns] = StandardScaler().fit_transform(df[df.columns]) elif scaling_opt == 2: df[df.columns] = MinMaxScaler().fit_transform(df[df.columns]) elif scaling_opt == 3: df[df.columns] = df[df.columns] feature_list = df.columns feature_list = [i for i in feature_list if i != label_col] print(feature_list) print("Model datasett:BHJLK") print(df) # Using PyMC3 # formula = str(target_col)+' ~ '+' + '.join(['%s' % variable for variable in label_col]) # degree of freedom # nu = len(df[label_col].count(axis=1)) - len(df[label_col].count(axis=0)) # TODO: add student-T distribution as priors for each feature # get degree of freedom if len(df[label_col].count(axis=1)) >= len(df[label_col].count(axis=0)): nu = len(df[label_col].count(axis=1)) - len(df[label_col].count(axis=0)) else: nu = 0 print("Degree of Freedom:") print(nu) # with pm.Model() as normal_model: # start = time.time() # # # intercept = pm.StudentT('Intercept', nu=nu, mu=0, sigma=1) # # sigma = pm.HalfCauchy("sigma", beta=10, testval=1.) # # pass in a prior mean & coefficient list # # # family = pm.glm.families.Normal() # pm.GLM.from_formula(formula, data=df, family=family) # trace = pm.sample(draws=draw_sample, chains=chains, tune=500, random_seed=23) # end = time.time() # print("Time elasped: {} seconds.".format(end-start)) # print("DONE normal_trace") with pm.Model() as model: fea_list = [variable for variable in label_col] print(fea_list) pm_list = [] i = 0 for prior_dist in prior_distribution_list: # for j in range(len(fea_list)): for type,prior in prior_dist.items(): if type != "Target" and prior == "Normal": # print(fea_list[j]) pm_list.append(pm.Normal(str(fea_list[i]))) i += 1 elif type != "Target" and prior == "Student T": pm_list.append(pm.StudentT(str(fea_list[i]), nu=nu)) i += 1 elif type != "Target" and prior == "Skew Normal": pm_list.append(pm.SkewNormal(str(fea_list[i]))) i += 1 # for i, item in enumerate(prior_distribution_list):Skew Normal # setattr(sys.modules[__name__], 'beta{0}'.format(i), item) # hyper_sigma = pm.HalfNormal('hyper_sigma', sd=3) sigma = pm.HalfCauchy('sigma', beta=10, testval=1.) intercept = pm.Normal('Intercept', 0, sigma=20) # setting the distribution mean for the predictor mu = intercept print("MUUU") print(mu) for i in range(len(pm_list)): print("PM LIST i") print(pm_list[i]) print("DF[FEA_LIST]") print(df[fea_list[i]]) mu += pm_list[i] * df[fea_list[i]].to_numpy() #mu += pm_list[i] * np.ones(df[fea_list[i]].to_list()) print(df[fea_list[i]].to_numpy()) for prior_dist in prior_distribution_list: for type,prior in prior_dist.items(): if type == "Target" and prior == "Normal": print("Target Normal") likelihood = pm.Normal(str(target_col), mu=mu, sigma=sigma, observed=df[target_col]) elif type == "Target" and prior == "Student T": print("Target Student") likelihood = pm.StudentT(str(target_col), nu = nu , mu=mu, sd=sigma, shape = n_individuals) elif type == "Target" and prior == "Skew Normal": print("Target Skew") mu = pm.Uniform('lambda_bl', 0., draw_sample) likelihood = pm.SkewNormal(str(target_col),mu=mu, sigma=sigma,tau=None, alpha=1, sd=3) elif type == "Target" and prior == nan: print("Target Nan") likelihood = pm.Normal(str(target_col), mu=mu, sigma=sigma, observed=df[target_col]) #means = pm.StudentT('means', nu = nu, mu = hyper_mean, sd = hyper_sigma, shape = n_individuals) #SkewNormal(mu=0.0, sigma=None, tau=None, alpha=1, sd=None, *args, **kwargs) trace = pm.sample(draws=draw_sample, chains=chains, random_seed=23,progressbar=True) img_source = save_mat_fig(trace, gtype='traceplot') posterior_dist = save_mat_fig(trace, gtype='posterior') # return np.array([np.mean(trace[variable]) for variable in trace.varnames]), img_source, posterior_dist return trace, img_source, posterior_dist