Ejemplo n.º 1
0
 def entropy(self):
     """
     Returns the entropy of the variational distribution as a tuple
     """
     return (
       -sum(_safe_x_log_x(q_zd).sum() for q_zd in self.q_z),
       self.q_alpha.H,
       self.q_beta.H,
       self.q_gamma.H,
       self.q_pi_bar.H.sum(),
       self.q_tau.H,
     )
Ejemplo n.º 2
0
    def _log_likelihood(self):
        """
        Returns the variational bound on the log likelihood.
        """
        LL = [] # build a list of all the different terms in the LL

        # n_d term
        term = (gammaln(self.q_alpha.E) - gammaln(self.q_alpha.E + self.n_d)).sum()
        assert numpy.isfinite(term)
        LL.append(term)

        # n_dk term
        G_alpha_pi = self.q_alpha.G * self.G_pi
        f = lambda n: gammaln(G_alpha_pi + n) - gammaln(G_alpha_pi)
        f2 = lambda n: polygamma(1, (G_alpha_pi + n))
        term = _approx_f_n(f, f2, self.counts.P_plus_n_dk, self.counts.E_plus_n_dk, self.counts.V_plus_n_dk).sum()
        assert numpy.isfinite(term)
        LL.append(term)

        # n_k term
        f = lambda n: gammaln(self.q_beta.G + n) - gammaln(self.q_beta.G)
        f2 = lambda n: polygamma(1, (self.q_beta.G + n))
        term = - _approx_f_n(f, f2, self.counts.P_plus_n_k, self.counts.E_plus_n_k, self.counts.V_plus_n_k).sum()
        assert numpy.isfinite(term)
        LL.append(term)

        # n_kw term
        G_beta_tau = self.q_beta.G * self.q_tau.G
        f = lambda n: gammaln(G_beta_tau + n) - gammaln(G_beta_tau)
        f2 = lambda n: polygamma(1, (G_beta_tau + n))
        term = _approx_f_n(f, f2, self.counts.P_plus_n_kw, self.counts.E_plus_n_kw, self.counts.V_plus_n_kw).sum()
        assert numpy.isfinite(term)
        LL.append(term)

        # KL(q(alpha)||p(alpha)) term
        a_bar = self.a_alpha + self.E_s_dk.sum()
        b_bar = self.b_alpha - self.E_log_eta.sum()
        term = - _gamma_KL(a_bar, b_bar, self.a_alpha, self.b_alpha)
        assert numpy.isfinite(term)
        LL.append(term)

        # KL(q(z)||p(z)) term
        term = sum(- _safe_x_log_x(q_zd).sum() for q_zd in self.q_z)
        LL.append(term)
        assert numpy.isfinite(term)

        # KL(q(beta)||p(beta)) term
        a_bar = self.a_beta + self.E_t_kw.sum()
        b_bar = self.b_beta - self.E_log_xi.sum()
        term = - _gamma_KL(a_bar, b_bar, self.a_beta, self.b_beta)
        assert numpy.isfinite(term)
        LL.append(term)

        # KL(q(pi)||p(pi)) term
        E_s_k = self.E_s_dk.sum(axis=0)
        assert E_s_k.shape == (self.K,)
        E_s_greater_k = _greater_than(E_s_k)
#        term = - (
#            gammaln(1. + self.q_gamma.E + E_s_k + E_s_greater_k)
#            - numpy.log(self.q_gamma.E)
#            - gammaln(1. + E_s_k)
#            - gammaln(self.q_gamma.E + E_s_greater_k)
#            + E_s_k * numpy.log(self.q_pi_bar.G)
#            + E_s_greater_k * numpy.log(self.q_1_minus_pi_bar.G)
#        ).sum()
        term = - (
            (
                gammaln(1. + self.q_gamma.E + E_s_k + E_s_greater_k)
                - numpy.log(self.q_gamma.E)
                - gammaln(1. + E_s_k)
                - gammaln(self.q_gamma.E + E_s_greater_k)
            )
            * self.q_pi_bar.G ** E_s_k
            * self.q_1_minus_pi_bar.G ** E_s_greater_k
        ).sum()
        #assert numpy.allclose(term, _beta_KL(self.q_pi_bar.a, self.q_pi_bar.b, 1., self.q_gamma.E))
        #term = _beta_KL(self.q_pi_bar.a, self.q_pi_bar.b, 1., self.q_gamma.G).sum()
        assert numpy.isfinite(term)
        LL.append(term)

        # KL(q(tau)||p(tau)) term
        a_bar = self.q_tau.a + self.E_t_kw.sum(axis=0)
        term = - _dirichlet_KL(a_bar, self.q_tau.a)
        assert numpy.isfinite(term)
        LL.append(term)

        return LL