Пример #1
0
    def resample(self):
        al, o = np.log(self.alpha_0), self.obs_distn
        self.z = ma.masked_array(self.z, mask=np.zeros(self.z.shape))
        model = self.model

        for n in np.random.permutation(self.data.shape[0]):
            # mask out n
            self.z.mask[n] = True

            # form the scores and sample them
            ks = list(model._get_occupied())
            scores = np.array(
                [
                    np.log(model._get_counts(k)) + o.log_predictive(self.data[n], model._get_data_withlabel(k))
                    for k in ks
                ]
                + [al + o.log_marginal_likelihood(self.data[n])]
            )

            idx = sample_discrete_from_log(scores)
            if idx == scores.shape[0] - 1:
                self.z[n] = self._new_label(ks)
            else:
                self.z[n] = ks[idx]

            # sample
            # note: the mask gets fixed by assigning into the array
            self.z[n] = sample_discrete_from_log(np.array(scores))
Пример #2
0
    def _resample_xi_discrete(self, augmented_data_list, xi_max=20):
        from pybasicbayes.util.stats import sample_discrete_from_log
        from pyglm.internals.negbin import nb_likelihood_xi

        # Resample xi with uniform prior over discrete set
        # p(\xi | \psi, s) \propto p(\xi) * p(s | \xi, \psi)
        lp_xis = np.zeros((self.N, xi_max))
        for d in augmented_data_list:
            psi = self.activation.compute_psi(d)
            for n in xrange(self.N):
                Sn   = d["S"][:,n].copy()
                psin = psi[:,n].copy()
                pn   = logistic(psin)
                pn   = np.clip(pn, 1e-32, 1-1e-32)

                xis = np.arange(1, xi_max+1).astype(np.float)
                lp_xi = np.zeros(xi_max)
                nb_likelihood_xi(Sn, pn, xis, lp_xi)
                lp_xis[n] += lp_xi

                # lp_xi2 = (gammaln(Sn[:,None]+xis[None,:]) - gammaln(xis[None,:])).sum(0)
                # lp_xi2 += (xis[None,:] * np.log(1-pn)[:,None]).sum(0)
                #
                # assert np.allclose(lp_xi, lp_xi2)

        for n in xrange(self.N):
            self.xi[0,n] = xis[sample_discrete_from_log(lp_xis[n])]
Пример #3
0
    def _resample_xi_discrete(self, augmented_data_list, xi_max=20):
        from pybasicbayes.util.stats import sample_discrete_from_log
        from pyglm.internals.negbin import nb_likelihood_xi

        # Resample xi with uniform prior over discrete set
        # p(\xi | \psi, s) \propto p(\xi) * p(s | \xi, \psi)
        lp_xis = np.zeros((self.N, xi_max))
        for d in augmented_data_list:
            psi = self.activation.compute_psi(d)
            for n in xrange(self.N):
                Sn = d["S"][:, n].copy()
                psin = psi[:, n].copy()
                pn = logistic(psin)
                pn = np.clip(pn, 1e-32, 1 - 1e-32)

                xis = np.arange(1, xi_max + 1).astype(np.float)
                lp_xi = np.zeros(xi_max)
                nb_likelihood_xi(Sn, pn, xis, lp_xi)
                lp_xis[n] += lp_xi

                # lp_xi2 = (gammaln(Sn[:,None]+xis[None,:]) - gammaln(xis[None,:])).sum(0)
                # lp_xi2 += (xis[None,:] * np.log(1-pn)[:,None]).sum(0)
                #
                # assert np.allclose(lp_xi, lp_xi2)

        for n in xrange(self.N):
            self.xi[0, n] = xis[sample_discrete_from_log(lp_xis[n])]
Пример #4
0
    def resample_c(self, network):
        """
        Resample block assignments given the weighted adjacency matrix
        and the impulse response fits (if used)
        """
        if self.C == 1:
            return

        A = network.A
        W = network.W

        # Sample each assignment in order
        for n1 in xrange(self.N):
            # Compute unnormalized log probs of each connection
            lp = np.zeros(self.C)

            # Prior from m
            lp += np.log(self.m)

            # Likelihood from network
            for cn1 in xrange(self.C):

                # Compute probability for each incoming and outgoing
                for n2 in xrange(self.N):
                    cn2 = self.c[n2]

                    if n2 != n1:
                        # p(A[k,k'] | c)
                        lp[cn1] += Bernoulli(self.p[cn1, cn2])\
                                        .log_probability(A[n1,n2]).sum()

                        # p(A[k',k] | c)
                        lp[cn1] += Bernoulli(self.p[cn2, cn1])\
                                        .log_probability(A[n2,n1]).sum()

                        # p(W[k,k'] | c)
                        lp[cn1] += (
                            A[n1, n2] *
                            self.weight_models[cn1][cn2].log_likelihood(
                                W[n1, n2, :])).sum()

                        lp[cn1] += (
                            A[n2, n1] *
                            self.weight_models[cn2][cn1].log_likelihood(
                                W[n2, n1, :])).sum()
                    else:
                        # Self connection
                        lp[cn1] += Bernoulli(self.p[cn1, cn1])\
                                        .log_probability(A[n1,n1]).sum()

                        lp[cn1] += (
                            A[n1, n1] *
                            self.weight_models[cn1][cn1].log_likelihood(
                                W[n1, n1, :])).sum()

            # Resample from lp
            self.c[n1] = sample_discrete_from_log(lp)
Пример #5
0
    def _resample_c(self):
        from pybasicbayes.util.stats import sample_discrete_from_log
        kappa, omega = self.kappa, self.omega
        mu = kappa / omega
        sigmasq = 1./omega
        for n in xrange(self.N):
            lps = np.zeros(self.C)
            for i in xrange(self.C):
                lps[i] += np.sum(-0.5 * (self.psis[:,i] - mu[:,n])**2 / sigmasq[:,n])

            self.c[n] = sample_discrete_from_log(lps)
Пример #6
0
    def _resample_c(self):
        from pybasicbayes.util.stats import sample_discrete_from_log
        kappa, omega = self.kappa, self.omega
        mu = kappa / omega
        sigmasq = 1. / omega
        for n in xrange(self.N):
            lps = np.zeros(self.C)
            for i in xrange(self.C):
                lps[i] += np.sum(-0.5 * (self.psis[:, i] - mu[:, n])**2 /
                                 sigmasq[:, n])

            self.c[n] = sample_discrete_from_log(lps)
    def resample_c(self, network):
        """
        Resample block assignments given the weighted adjacency matrix
        and the impulse response fits (if used)
        """
        if self.C == 1:
            return

        A = network.A
        W = network.W

        # Sample each assignment in order
        for n1 in xrange(self.N):
            # Compute unnormalized log probs of each connection
            lp = np.zeros(self.C)

            # Prior from m
            lp += np.log(self.m)

            # Likelihood from network
            for cn1 in xrange(self.C):

                # Compute probability for each incoming and outgoing
                for n2 in xrange(self.N):
                    cn2 = self.c[n2]

                    if n2 != n1:
                        # p(A[k,k'] | c)
                        lp[cn1] += Bernoulli(self.p[cn1, cn2])\
                                        .log_probability(A[n1,n2]).sum()

                        # p(A[k',k] | c)
                        lp[cn1] += Bernoulli(self.p[cn2, cn1])\
                                        .log_probability(A[n2,n1]).sum()

                        # p(W[k,k'] | c)
                        lp[cn1] += (A[n1,n2] * self.weight_models[cn1][cn2]
                                   .log_likelihood(W[n1,n2,:])).sum()

                        lp[cn1] += (A[n2, n1] * self.weight_models[cn2][cn1]
                                   .log_likelihood(W[n2,n1,:])).sum()
                    else:
                        # Self connection
                        lp[cn1] += Bernoulli(self.p[cn1, cn1])\
                                        .log_probability(A[n1,n1]).sum()

                        lp[cn1] += (A[n1, n1] * self.weight_models[cn1][cn1]
                                       .log_likelihood(W[n1,n1,:])).sum()

            # Resample from lp
            self.c[n1] = sample_discrete_from_log(lp)
Пример #8
0
    def resample(self):
        al, o = np.log(self.alpha_0), self.obs_distn
        self.z = ma.masked_array(self.z, mask=np.zeros(self.z.shape))
        model = self.model

        for n in np.random.permutation(self.data.shape[0]):
            # mask out n
            self.z.mask[n] = True

            # form the scores and sample them
            ks = list(model._get_occupied())
            scores = np.array([
                np.log(model._get_counts(k))+ o.log_predictive(self.data[n],model._get_data_withlabel(k)) \
                        for k in ks] + [al + o.log_marginal_likelihood(self.data[n])])

            idx = sample_discrete_from_log(scores)
            if idx == scores.shape[0] - 1:
                self.z[n] = self._new_label(ks)
            else:
                self.z[n] = ks[idx]

            # sample
            # note: the mask gets fixed by assigning into the array
            self.z[n] = sample_discrete_from_log(np.array(scores))
Пример #9
0
    def resample_c(self, A):
        """
        Resample block assignments given the weighted adjacency matrix
        and the impulse response fits (if used)
        """
        from pybasicbayes.util.stats import sample_discrete_from_log

        if self.C == 1:
            return

        # Sample each assignment in order
        for n1 in xrange(self.N):
            # Compute unnormalized log probs of each connection
            lp = np.zeros(self.C)

            # Prior from m
            lp += np.log(self.m)

            # Likelihood from network
            for cn1 in xrange(self.C):

                # Compute probability for each incoming and outgoing
                for n2 in xrange(self.N):
                    cn2 = self.c[n2]

                    if n2 == n1:
                        # If we are special casing the self connections then
                        # we can just continue if n1==n2 since its weight has
                        # no bearing on the cluster assignment
                        if self.special_case_self_conns:
                            continue
                        else:
                            lp[cn1] += A[n1,n1] * np.log(self.p[cn1,cn1]) + \
                                       (1-A[n1,n1]) * np.log(1-self.p[cn1,cn1])

                    else:
                        # p(An1,n2] | c)
                        lp[cn1] += A[n1,n2] * np.log(self.p[cn1,cn2]) + \
                                   (1-A[n1,n2]) * np.log(1-self.p[cn1,cn2])

                        # p(A[n2,n1] | c)
                        lp[cn1] += A[n2,n1] * np.log(self.p[cn2,cn1]) + \
                                   (1-A[n2,n1]) * np.log(1-self.p[cn2,cn1])

            # Resample from lp
            self.c[n1] = sample_discrete_from_log(lp)
Пример #10
0
    def resample_c(self, A):
        """
        Resample block assignments given the weighted adjacency matrix
        and the impulse response fits (if used)
        """
        from pybasicbayes.util.stats import sample_discrete_from_log

        if self.C == 1:
            return

        # Sample each assignment in order
        for n1 in xrange(self.N):
            # Compute unnormalized log probs of each connection
            lp = np.zeros(self.C)

            # Prior from m
            lp += np.log(self.m)

            # Likelihood from network
            for cn1 in xrange(self.C):

                # Compute probability for each incoming and outgoing
                for n2 in xrange(self.N):
                    cn2 = self.c[n2]

                    if n2 == n1:
                        # If we are special casing the self connections then
                        # we can just continue if n1==n2 since its weight has
                        # no bearing on the cluster assignment
                        if self.special_case_self_conns:
                            continue
                        else:
                            lp[cn1] += A[n1,n1] * np.log(self.p[cn1,cn1]) + \
                                       (1-A[n1,n1]) * np.log(1-self.p[cn1,cn1])

                    else:
                        # p(An1,n2] | c)
                        lp[cn1] += A[n1,n2] * np.log(self.p[cn1,cn2]) + \
                                   (1-A[n1,n2]) * np.log(1-self.p[cn1,cn2])

                        # p(A[n2,n1] | c)
                        lp[cn1] += A[n2,n1] * np.log(self.p[cn2,cn1]) + \
                                   (1-A[n2,n1]) * np.log(1-self.p[cn2,cn1])

            # Resample from lp
            self.c[n1] = sample_discrete_from_log(lp)
Пример #11
0
 def resample_logseriesaug(self,data=[],niter=20):
     # an alternative algorithm, kind of opaque and no advantages...
     if getdatasize(data) == 0:
         self.p = np.random.beta(self.alpha_0,self.beta_0)
         self.r = np.random.gamma(self.k_0,self.theta_0)
     else:
         data = flattendata(data)
         N = data.shape[0]
         logF = self.logF
         L_i = np.zeros(N)
         data_nz = data[data > 0]
         for itr in range(niter):
             logR = np.arange(1,logF.shape[1]+1)*np.log(self.r) + logF
             L_i[data > 0] = sample_discrete_from_log(logR[data_nz-1,:data_nz.max()],axis=1)+1
             self.r = np.random.gamma(self.k_0 + L_i.sum(), 1/(1/self.theta_0 - np.log(1-self.p)*N))
             self.p = np.random.beta(self.alpha_0 + data.sum(), self.beta_0 + N*self.r)
     return self
Пример #12
0
 def resample_logseriesaug(self,data=[],niter=20):
     # an alternative algorithm, kind of opaque and no advantages...
     if getdatasize(data) == 0:
         self.p = np.random.beta(self.alpha_0,self.beta_0)
         self.r = np.random.gamma(self.k_0,self.theta_0)
     else:
         data = flattendata(data)
         N = data.shape[0]
         logF = self.logF
         L_i = np.zeros(N)
         data_nz = data[data > 0]
         for itr in range(niter):
             logR = np.arange(1,logF.shape[1]+1)*np.log(self.r) + logF
             L_i[data > 0] = sample_discrete_from_log(logR[data_nz-1,:data_nz.max()],axis=1)+1
             self.r = np.random.gamma(self.k_0 + L_i.sum(), 1/(1/self.theta_0 - np.log(1-self.p)*N))
             self.p = np.random.beta(self.alpha_0 + data.sum(), self.beta_0 + N*self.r)
     return self
Пример #13
0
    def resample(self, data):
        if not isinstance(data, list):
            assert isinstance(data, tuple) and len(data) == 2, \
                "datas must be an (x,y) tuple or a list of such tuples"
            data = [data]

        # Compute the log likelihood under each mixture component and
        # assign datapoints accordingly
        zs = []
        for xy in data:
            lls = np.array([r.log_likelihood(xy) for r in self.regressions])
            from pybasicbayes.util.stats import sample_discrete_from_log
            zs.append(sample_discrete_from_log(lls, axis=0))

        # Sample each mixture component with its assigned data
        for m in range(self.M):
            data_m = [(x[z == m], y[z == m]) for (x, y), z in zip(data, zs)]
            self.regressions[m].resample(data_m)
Пример #14
0
    def resample(self, data):
        if not isinstance(data, list):
            assert isinstance(data, tuple) and len(data) == 2, \
                "datas must be an (x,y) tuple or a list of such tuples"
            data = [data]

        # Compute the log likelihood under each mixture component and
        # assign datapoints accordingly
        zs = []
        for xy in data:
            lls = np.array([r.log_likelihood(xy) for r in self.regressions])
            from pybasicbayes.util.stats import sample_discrete_from_log
            zs.append(sample_discrete_from_log(lls, axis=0))

        # Sample each mixture component with its assigned data
        for m in range(self.M):
            data_m = [(x[z == m], y[z == m]) for (x, y), z in zip(data, zs)]
            self.regressions[m].resample(data_m)
Пример #15
0
    def resample_c(self, A, W):
        """
        Resample block assignments given the weighted adjacency matrix
        and the impulse response fits (if used)
        """
        if self.C == 1:
            return

        # Sample each assignment in order
        for k in range(self.K):
            # Compute unnormalized log probs of each connection
            lp = np.zeros(self.C)

            # Prior from m
            lp += np.log(self.m)

            # Likelihood from network
            for ck in range(self.C):
                c_temp = self.c.copy().astype(np.int)
                c_temp[k] = ck

                # p(A[k,k'] | c)
                lp[ck] += Bernoulli(self.p[ck, c_temp])\
                                .log_probability(A[k,:]).sum()

                # p(A[k',k] | c)
                lp[ck] += Bernoulli(self.p[c_temp, ck])\
                                .log_probability(A[:, k]).sum()

                # p(W[k,k'] | c)
                lp[ck] += (A[k,:] * Gamma(self.kappa, self.v[ck, c_temp])\
                                .log_probability(W[k,:])).sum()

                # p(W[k,k'] | c)
                lp[ck] += (A[:, k] * Gamma(self.kappa, self.v[c_temp, ck])\
                                .log_probability(W[:, k])).sum()

                # TODO: Subtract of self connection since we double counted

                # TODO: Get probability of impulse responses g

            # Resample from lp
            self.c[k] = sample_discrete_from_log(lp)
Пример #16
0
    def resample_c(self, A, W):
        """
        Resample block assignments given the weighted adjacency matrix
        and the impulse response fits (if used)
        """
        if self.C == 1:
            return

        # Sample each assignment in order
        for k in range(self.K):
            # Compute unnormalized log probs of each connection
            lp = np.zeros(self.C)

            # Prior from m
            lp += np.log(self.m)

            # Likelihood from network
            for ck in range(self.C):
                c_temp = self.c.copy().astype(np.int)
                c_temp[k] = ck

                # p(A[k,k'] | c)
                lp[ck] += Bernoulli(self.p[ck, c_temp])\
                                .log_probability(A[k,:]).sum()

                # p(A[k',k] | c)
                lp[ck] += Bernoulli(self.p[c_temp, ck])\
                                .log_probability(A[:,k]).sum()

                # p(W[k,k'] | c)
                lp[ck] += (A[k,:] * Gamma(self.kappa, self.v[ck, c_temp])\
                                .log_probability(W[k,:])).sum()

                # p(W[k,k'] | c)
                lp[ck] += (A[:,k] * Gamma(self.kappa, self.v[c_temp, ck])\
                                .log_probability(W[:,k])).sum()

                # TODO: Subtract of self connection since we double counted

                # TODO: Get probability of impulse responses g

            # Resample from lp
            self.c[k] = sample_discrete_from_log(lp)
Пример #17
0
    def _collapsed_resample_a(self, J_prior, h_prior, J_post, h_post):
        """
        """
        N, B, rho = self.N, self.B, self.rho
        perm = npr.permutation(self.N)

        ml_prev = self._marginal_likelihood(J_prior, h_prior, J_post, h_post)
        for n in perm:
            # TODO: Check if rho is deterministic

            # Compute the marginal prob with and without A[m,n]
            lps = np.zeros(2)
            # We already have the marginal likelihood for the current value of a[m]
            # We just need to add the prior
            v_prev = int(self.a[n])
            lps[v_prev] += ml_prev
            lps[v_prev] += v_prev * np.log(
                rho[n]) + (1 - v_prev) * np.log(1 - rho[n])

            # Now compute the posterior stats for 1-v
            v_new = 1 - v_prev
            self.a[n] = v_new

            ml_new = self._marginal_likelihood(J_prior, h_prior, J_post,
                                               h_post)

            lps[v_new] += ml_new
            lps[v_new] += v_new * np.log(
                rho[n]) + (1 - v_new) * np.log(1 - rho[n])

            # Sample from the marginal probability
            # max_lps = max(lps[0], lps[1])
            # se_lps = np.sum(np.exp(lps-max_lps))
            # lse_lps = np.log(se_lps) + max_lps
            # ps = np.exp(lps - lse_lps)
            # v_smpl = npr.rand() < ps[1]
            v_smpl = sample_discrete_from_log(lps)
            self.a[n] = v_smpl

            # Cache the posterior stats and update the matrix objects
            if v_smpl != v_prev:
                ml_prev = ml_new
Пример #18
0
    def resample(self, data):
        if not isinstance(data, list):
            assert isinstance(data, tuple) and len(data) == 2, \
                "datas must be an (x,y) tuple or a list of such tuples"
            data = [data]

        # Compute the log likelihood under each mixture component and
        # assign datapoints accordingly
        zs = []
        for x, y in data:
            # If we've only been given the first K-1 dimensions of y,
            # concatenate with the last one
            assert y.ndim == 2 and x.shape[0] == y.shape[0]
            if y.shape[1] == self.K - 1:
                y = np.column_stack((y, self.N - y.sum(1)))

            lls = []
            for m in range(self.M):
                # Undo the permutation
                # By definition, y_t ~ P pi_t where pi_t is a column vector
                # equivalently, y ~ pi P^T when y and pi are T x K (i.e. y_t and pi_t are row vectors)
                # To undo the permutation, right multiply by P = (P^T)^{-1}
                y_unperm = y.dot(self.Ps[m])
                ll_m = self.regressions[m].log_likelihood(
                    (x, y_unperm[:, :-1]))
                ll_m += np.log(self.weights[m])
                lls.append(ll_m)
            lls = np.array(lls)

            from pybasicbayes.util.stats import sample_discrete_from_log
            zs.append(sample_discrete_from_log(lls, axis=0))

        # Sample each mixture component with its assigned data
        for m in range(self.M):
            data_m = [(x[z == m], y[z == m]) for (x, y), z in zip(data, zs)]
            self.regressions[m].resample(data_m)

        # Sample mixture weights
        alpha_hat = self.alpha + sum(
            [np.bincount(z, minlength=self.M) for z in zs])
        self.weights = npr.dirichlet(alpha_hat)
Пример #19
0
    def resample(self, data):
        if not isinstance(data, list):
            assert isinstance(data, tuple) and len(data) == 2, \
                "datas must be an (x,y) tuple or a list of such tuples"
            data = [data]

        # Compute the log likelihood under each mixture component and
        # assign datapoints accordingly
        zs = []
        for x,y in data:
            # If we've only been given the first K-1 dimensions of y,
            # concatenate with the last one
            assert y.ndim == 2 and x.shape[0] == y.shape[0]
            if y.shape[1] == self.K - 1:
                y = np.column_stack((y, self.N - y.sum(1)))

            lls = []
            for m in range(self.M):
                # Undo the permutation
                # By definition, y_t ~ P pi_t where pi_t is a column vector
                # equivalently, y ~ pi P^T when y and pi are T x K (i.e. y_t and pi_t are row vectors)
                # To undo the permutation, right multiply by P = (P^T)^{-1}
                y_unperm = y.dot(self.Ps[m])
                ll_m = self.regressions[m].log_likelihood((x, y_unperm[:, :-1]))
                ll_m += np.log(self.weights[m])
                lls.append(ll_m)
            lls = np.array(lls)

            from pybasicbayes.util.stats import sample_discrete_from_log
            zs.append(sample_discrete_from_log(lls, axis=0))

        # Sample each mixture component with its assigned data
        for m in range(self.M):
            data_m = [(x[z==m], y[z==m]) for (x,y),z in zip(data, zs)]
            self.regressions[m].resample(data_m)

        # Sample mixture weights
        alpha_hat = self.alpha + sum([np.bincount(z, minlength=self.M) for z in zs])
        self.weights = npr.dirichlet(alpha_hat)
Пример #20
0
    def _collapsed_resample_a(self, J_prior, h_prior, J_post, h_post):
        """
        """
        N, B, rho = self.N, self.B, self.rho
        perm = npr.permutation(self.N)

        ml_prev = self._marginal_likelihood(J_prior, h_prior, J_post, h_post)
        for n in perm:
            # TODO: Check if rho is deterministic

            # Compute the marginal prob with and without A[m,n]
            lps = np.zeros(2)
            # We already have the marginal likelihood for the current value of a[m]
            # We just need to add the prior
            v_prev = int(self.a[n])
            lps[v_prev] += ml_prev
            lps[v_prev] += v_prev * np.log(rho[n]) + (1-v_prev) * np.log(1-rho[n])

            # Now compute the posterior stats for 1-v
            v_new = 1 - v_prev
            self.a[n] = v_new

            ml_new = self._marginal_likelihood(J_prior, h_prior, J_post, h_post)

            lps[v_new] += ml_new
            lps[v_new] += v_new * np.log(rho[n]) + (1-v_new) * np.log(1-rho[n])

            # Sample from the marginal probability
            # max_lps = max(lps[0], lps[1])
            # se_lps = np.sum(np.exp(lps-max_lps))
            # lse_lps = np.log(se_lps) + max_lps
            # ps = np.exp(lps - lse_lps)
            # v_smpl = npr.rand() < ps[1]
            v_smpl = sample_discrete_from_log(lps)
            self.a[n] = v_smpl

            # Cache the posterior stats and update the matrix objects
            if v_smpl != v_prev:
                ml_prev = ml_new
Пример #21
0
    def resample_c(self, A, W):
        """
        Resample block assignments given the weighted adjacency matrix
        """
        from pybasicbayes.util.stats import sample_discrete_from_log

        if self.C == 1:
            return

        Abool = A.astype(np.bool)
        c_init = self.c.copy()

        def _evaluate_lkhd_slow(n1, cn1):
            ll = 0
            # Compute probability for each incoming and outgoing
            for n2 in xrange(self.N):
                cn2 = self.c[n2]

                # If we are special casing the self connections then
                # we can just continue if n1==n2 since its weight has
                # no bearing on the cluster assignment
                if n2 == n1:
                    # Self connection
                    if self.special_case_self_conns:
                        continue
                    ll += self._gaussians[cn1][cn1].log_likelihood(W[n1,n1]).sum()

                else:
                    # p(W[n1,n2] | c) and p(W[n2,n1] | c), only if there is a connection
                    if A[n1,n2]:
                        ll += self._gaussians[cn1][cn2].log_likelihood(W[n1,n2]).sum()
                    if A[n2,n1]:
                        ll += self._gaussians[cn2][cn1].log_likelihood(W[n2,n1]).sum()

            return ll

        def _evaluate_lkhd(n1, cn1):
            chat = self.c.copy()
            chat[n1] = cn1

            # Compute log lkhd for each pair of blocks
            ll = 0
            for c2 in xrange(self.C):
                # Outgoing connections
                out_mask = (chat == c2) & Abool[n1,:]
                if self.special_case_self_conns:
                    out_mask[n1] = False
                ll += self._gaussians[cn1][c2].log_likelihood(W[n1,out_mask]).sum()

                # Handle incoming connections
                # Exclude self connection since it would have been handle above
                in_mask = (chat == c2) & Abool[:,n1]
                in_mask[n1] = False
                ll += self._gaussians[c2][cn1].log_likelihood(W[in_mask,n1]).sum()

            return ll

        # Sample each assignment in order
        for n1 in xrange(self.N):
            # Compute unnormalized log probs of each connection
            lp = np.zeros(self.C)

            # Prior from m
            lp += np.log(self.m)

            # Likelihood from network
            for cn1 in xrange(self.C):
                ll = _evaluate_lkhd(n1, cn1)
                # ll_slow = _evaluate_lkhd_slow(n1, cn1)
                # assert np.allclose(ll,ll_slow)
                lp[cn1] += ll

            # Resample from lp
            self.c[n1] = sample_discrete_from_log(lp)
Пример #22
0
 def resample(self):
     scores = self._compute_scores()
     self.z, lognorms = sample_discrete_from_log(scores,axis=1,return_lognorms=True)
     self._normalizer = lognorms[~np.isnan(self.data).any(1)].sum()
Пример #23
0
 def resample(self):
     scores = self._compute_scores()
     self.z, lognorms = sample_discrete_from_log(scores,
                                                 axis=1,
                                                 return_lognorms=True)
     self._normalizer = lognorms[~np.isnan(self.data).any(1)].sum()
Пример #24
0
    def resample_c(self, A, W):
        """
        Resample block assignments given the weighted adjacency matrix
        """
        from pybasicbayes.util.stats import sample_discrete_from_log

        if self.C == 1:
            return

        Abool = A.astype(np.bool)
        c_init = self.c.copy()

        def _evaluate_lkhd_slow(n1, cn1):
            ll = 0
            # Compute probability for each incoming and outgoing
            for n2 in xrange(self.N):
                cn2 = self.c[n2]

                # If we are special casing the self connections then
                # we can just continue if n1==n2 since its weight has
                # no bearing on the cluster assignment
                if n2 == n1:
                    # Self connection
                    if self.special_case_self_conns:
                        continue
                    ll += self._gaussians[cn1][cn1].log_likelihood(
                        W[n1, n1]).sum()

                else:
                    # p(W[n1,n2] | c) and p(W[n2,n1] | c), only if there is a connection
                    if A[n1, n2]:
                        ll += self._gaussians[cn1][cn2].log_likelihood(
                            W[n1, n2]).sum()
                    if A[n2, n1]:
                        ll += self._gaussians[cn2][cn1].log_likelihood(
                            W[n2, n1]).sum()

            return ll

        def _evaluate_lkhd(n1, cn1):
            chat = self.c.copy()
            chat[n1] = cn1

            # Compute log lkhd for each pair of blocks
            ll = 0
            for c2 in xrange(self.C):
                # Outgoing connections
                out_mask = (chat == c2) & Abool[n1, :]
                if self.special_case_self_conns:
                    out_mask[n1] = False
                ll += self._gaussians[cn1][c2].log_likelihood(
                    W[n1, out_mask]).sum()

                # Handle incoming connections
                # Exclude self connection since it would have been handle above
                in_mask = (chat == c2) & Abool[:, n1]
                in_mask[n1] = False
                ll += self._gaussians[c2][cn1].log_likelihood(W[in_mask,
                                                                n1]).sum()

            return ll

        # Sample each assignment in order
        for n1 in xrange(self.N):
            # Compute unnormalized log probs of each connection
            lp = np.zeros(self.C)

            # Prior from m
            lp += np.log(self.m)

            # Likelihood from network
            for cn1 in xrange(self.C):
                ll = _evaluate_lkhd(n1, cn1)
                # ll_slow = _evaluate_lkhd_slow(n1, cn1)
                # assert np.allclose(ll,ll_slow)
                lp[cn1] += ll

            # Resample from lp
            self.c[n1] = sample_discrete_from_log(lp)