Example #1
0
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)
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
         '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:]
Example #6
0
    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
Example #7
0
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