Beispiel #1
0
    def test_logitnormal_moments(self):
        # global parameters for computing lognormals
        gh_loc, gh_weights = hermgauss(4)

        # log normal parameters
        lognorm_means = np.random.random((5, 3)) # should work for arrays now
        lognorm_infos = np.random.random((5, 3))**2 + 1
        alpha = 2 # dp parameter

        # draw samples
        num_draws = 10**5
        samples = np.random.normal(lognorm_means,
                        1/np.sqrt(lognorm_infos), size = (num_draws, 5, 3))
        logit_norm_samples = sp.special.expit(samples)

        # test lognormal means
        np_test.assert_allclose(
            np.mean(logit_norm_samples, axis = 0),
            ef.get_e_logitnormal(
                lognorm_means, lognorm_infos, gh_loc, gh_weights),
            atol = 3 * np.std(logit_norm_samples) / np.sqrt(num_draws))

        # test Elog(x) and Elog(1-x)
        log_logistic_norm = np.mean(np.log(logit_norm_samples), axis = 0)
        log_1m_logistic_norm = np.mean(np.log(1 - logit_norm_samples), axis = 0)

        tol1 = 3 * np.std(np.log(logit_norm_samples))/ np.sqrt(num_draws)
        tol2 = 3 * np.std(np.log(1 - logit_norm_samples))/ np.sqrt(num_draws)

        np_test.assert_allclose(
            log_logistic_norm,
            ef.get_e_log_logitnormal(
                lognorm_means, lognorm_infos, gh_loc, gh_weights)[0],
            atol = tol1)

        np_test.assert_allclose(
            log_1m_logistic_norm,
            ef.get_e_log_logitnormal(
                        lognorm_means, lognorm_infos, gh_loc, gh_weights)[1],
            atol = tol2)

        # test prior
        prior_samples = np.mean((alpha - 1) *
                            np.log(1 - logit_norm_samples), axis = 0)
        tol3 = 3 * np.std((alpha - 1) * np.log(1 - logit_norm_samples)) \
                    /np.sqrt(num_draws)
        np_test.assert_allclose(
            prior_samples,
            ef.get_e_dp_prior_logitnorm_approx(
                        alpha, lognorm_means, lognorm_infos, gh_loc, gh_weights),
            atol = tol3)

        x = np.random.normal(0, 1e2, size = 10)
        def e_log_v(x):
            return np.sum(ef.get_e_log_logitnormal(\
                        x[0:5], np.abs(x[5:10]), gh_loc, gh_weights)[0])
        check_grads(e_log_v, order=2)(x)
def get_stick_breaking_entropy(stick_propn_mean, stick_propn_info,
                                gh_loc, gh_weights):
    # return the entropy of logitnormal distriibution on the sticks whose
    # logit has mean stick_propn_mean and information stick_propn_info
    # Integration is done on the real line with respect to the Lesbegue measure

    # integration is done numerical with Gauss Hermite quadrature.
    # gh_loc and gh_weights specifiy the location and weights of the
    # quadrature points

    # we seek E[log q(V)], where q is the density of a logit-normal, and
    # V ~ logit-normal. Let W := logit(V), so W ~ Normal. Hence,
    # E[log q(W)]; we can then decompose log q(x) into the terms of a normal
    # distribution and the jacobian term. The expectation of the normal term
    # evaluates to the normal entropy, and we add the jacobian term to it.
    # The jacobian term is 1/(x(1-x)), so we simply add -EV - E(1-V) to the normal
    # entropy.

    assert np.all(gh_weights > 0)

    assert stick_propn_mean.shape == stick_propn_info.shape
    assert np.all(stick_propn_info) > 0

    e_log_v, e_log_1mv =\
        ef.get_e_log_logitnormal(
            lognorm_means = stick_propn_mean,
            lognorm_infos = stick_propn_info,
            gh_loc = gh_loc,
            gh_weights = gh_weights)

    return np.sum(ef.univariate_normal_entropy(stick_propn_info)) + \
                    np.sum(e_log_v + e_log_1mv)
def get_e_logitnorm_dp_prior(stick_propn_mean, stick_propn_info, alpha,
                                gh_loc, gh_weights):
    # expected log prior for the stick breaking proportions under the
    # logitnormal variational distribution

    # integration is done numerical with Gauss Hermite quadrature.
    # gh_loc and gh_weights specifiy the location and weights of the
    # quadrature points

    assert np.all(gh_weights > 0)

    assert stick_propn_mean.shape == stick_propn_info.shape
    assert np.all(stick_propn_info) > 0

    e_log_v, e_log_1mv = \
        ef.get_e_log_logitnormal(
            lognorm_means = stick_propn_mean,
            lognorm_infos = stick_propn_info,
            gh_loc = gh_loc,
            gh_weights = gh_weights)

    return (alpha - 1) * np.sum(e_log_1mv)
def get_e_log_cluster_probabilities(stick_propn_mean, stick_propn_info,
                                        gh_loc, gh_weights):

    # the expected log mixture weights
    # stick_propn_mean is of shape ... x k_approx

    assert np.all(gh_weights > 0)

    assert stick_propn_mean.shape == stick_propn_info.shape
    if len(stick_propn_mean.shape) == 1:
        stick_propn_mean = stick_propn_mean[None, :]
        stick_propn_info = stick_propn_info[None, :]

    assert np.all(stick_propn_info) > 0

    e_log_v, e_log_1mv = \
        ef.get_e_log_logitnormal(
            lognorm_means = stick_propn_mean,
            lognorm_infos = stick_propn_info,
            gh_loc = gh_loc,
            gh_weights = gh_weights)

    return get_e_log_cluster_probabilities_from_e_log_stick(e_log_v, e_log_1mv)
Beispiel #5
0
 def e_log_v(x):
     return np.sum(ef.get_e_log_logitnormal(\
                 x[0:5], np.abs(x[5:10]), gh_loc, gh_weights)[0])