Пример #1
0
 def sample_mu(self, j, k, scale=5.0):
     current = self.mus[j,k]
     proposal = np.random.normal(current, scale)
     current_logp = np.log(laplace.pdf(current, scale=self.gamma_f))
     proposal_logp = np.log(laplace.pdf(proposal, scale=self.gamma_f))
     # current_logp = -1 * ((current * current) / (2.0 * self.sigmas[j,k]))
     # proposal_logp = -1 * ((proposal * proposal) / (2.0 * self.sigmas[j,k]))
     theta_olds = []
     for obj in self.mixlist:
         if obj["ready"][j] == False:
             self._calc_theta(obj, j)
         k2 = obj["assignments"][j]
         current_logp += obj["logthetas"][j,k2]
         theta_olds.append(obj["logthetas"][j].copy())
     self.mus[j,k] = proposal
     for obj in self.mixlist:
         self._calc_theta(obj, j)
         k2 = obj["assignments"][j]
         proposal_logp += obj["logthetas"][j,k2]
     if current_logp > proposal_logp and rand_partition_log([current_logp, proposal_logp]) == 0:
         # rejected, undoing changes
         self.mus[j,k] = current
         for obj, theta_old in zip(self.mixlist, theta_olds):
             obj["logthetas"][j] = theta_old
         return False
     else:
         # accepted
         return True
Пример #2
0
 def sample_eta(self, obj, k, scale=5.0):
     current = obj["etas"][k]
     proposal = np.random.normal(current, scale)
     current_logp = np.log(laplace.pdf(current, scale=self.gamma_c))
     proposal_logp = np.log(laplace.pdf(proposal, scale=self.gamma_c))
     # current_logp = -1 * ((current * current) / (2.0 * obj["taus"][k]))
     # proposal_logp = -1 * ((proposal * proposal) / (2.0 * obj["taus"][k]))
     for j in xrange(self.dims):
         if obj["ready"][j] == False:
             self._calc_theta(obj, j)
         k2 = obj["assignments"][j]
         current_logp += obj["logthetas"][j,k2]
     theta_old = obj["logthetas"].copy()
     obj["etas"][k] = proposal
     for j in xrange(self.dims):
         self._calc_theta(obj, j)
         k2 = obj["assignments"][j]
         proposal_logp += obj["logthetas"][j,k2]
     if current_logp > proposal_logp and rand_partition_log([current_logp, proposal_logp]) == 0:
         # rejected, undoing changes
         obj["etas"][k] = current
         # do not entirely override obj["logthetas"] because it is pointed from elsewhere
         for j in xrange(self.dims):
             obj["logthetas"][j] = theta_old[j]
         return False
     else:
         # accepted
         return True
Пример #3
0
    def sample_z(self, l, k, itemp=1.0):
        assert(not self.bias or not k == 0)
        z_old = self.zmat[k,l]
        logprob0, logprob1 = 0.0, 0.0
        if not self.only_alphas:
            vcount = np.bincount(self.zmat[k,self.vnet[l]], minlength=2)
            logprob0 += self.vks[k] * vcount[0]
            logprob1 += self.vks[k] * vcount[1]
            hcount = np.bincount(self.zmat[k,self.hnet[l]], minlength=2)
            logprob0 += self.hks[k] * hcount[0]
            logprob1 += self.hks[k] * hcount[1]
        logprob1 += self.alphas[k]

        theta_new = np.empty_like(self.theta[l,:])
        theta_tilde_new = np.copy(self.theta_tilde[l,:])
        if z_old == False:
            # proposal: 1
            theta_tilde_new += self.wmat[k,:]
            logprob_old, logprob_new = logprob0, logprob1
        else:
            # proposal: 0
            theta_tilde_new -= self.wmat[k,:]
            logprob_old, logprob_new = logprob1, logprob0
        for p in range(self.P):
            j_start, T = self.p2jT[p]
            x = self.mat[l,p]
            if self.flist[p]["type"] == "cat":
                logprob_old += np.log(self.theta[l,j_start+x] + 1E-20)
                e_theta_tilde = np.exp(theta_tilde_new[j_start:j_start+T] - theta_tilde_new[j_start:j_start+T].max())
                theta_new[j_start:j_start+T] = e_theta_tilde / e_theta_tilde.sum()
                logprob_new += np.log(theta_new[j_start+x] + 1E-20)
            elif self.flist[p]["type"] == "bin":
                logprob_old += np.log((self.theta[l,j_start] if x == 1 else (1.0 - self.theta[l,j_start])) + 1E-20)
                theta_new[j_start] = 0.5 * np.tanh(0.5 * theta_tilde_new[j_start]) + 0.5
                logprob_new += np.log((theta_new[j_start] if x == 1 else (1.0 - theta_new[j_start])) + 1E-20)
            elif self.flist[p]["type"] == "count":
                logprob_old += x * np.log(self.theta[l,j_start] + 1E-20)
                theta_new[j_start] = np.fmax(theta_tilde_new[j_start], 0) + np.log1p(np.exp(-np.fabs(theta_tilde_new[j_start])))
                logprob_new += x * np.log(theta_new[j_start] + 1E-20)
            else:
                raise NotImplementedError
        if itemp != 1.0:
            logprob_old *= itemp
            logprob_new *= itemp
        accepted = np.bool_(rand_partition_log((logprob_old, logprob_new)))
        if accepted:
            if z_old == False:
                # 0 -> 1
                self.zmat[k,l] = True
            else:
                # 1 -> 0
                self.zmat[k,l] = False
            self.theta_tilde[l,:] = theta_tilde_new
            self.theta[l,:] = theta_new
            return True
        else:
            return False
Пример #4
0
    def sample_zx(self, l, k, itemp=1.0):
        assert (not self.bias or not k == 0)
        z_old = self.zmat[k, l]
        logprob0, logprob1 = 0.0, 0.0
        if not self.only_alphas:
            idxs, weights = self.hnet.js[l]
            vals = self.zmat[k, idxs]
            logprob0 += self.hks[k] * ((vals == 0) * weights).sum()
            logprob1 += self.hks[k] * ((vals == 1) * weights).sum()
        logprob1 += self.alphas[k]

        theta_new = np.empty_like(self.theta[l, :])
        theta_tilde_new = np.copy(self.theta_tilde[l, :])
        if z_old == False:
            # proposal: 1
            theta_tilde_new += self.wmat[k, :]
            logprob_old, logprob_new = logprob0, logprob1
        else:
            # proposal: 0
            theta_tilde_new -= self.wmat[k, :]
            logprob_old, logprob_new = logprob1, logprob0
        xs_new = self.mat[l, :].copy()
        for p, (x, is_missing) in enumerate(zip(self.mat[l, :],
                                                self.mvs[l, :])):
            j_start, T = self.p2jT[p]
            e_theta_tilde = np.exp(theta_tilde_new[j_start:j_start + T] -
                                   theta_tilde_new[j_start:j_start + T].max())
            theta_new[j_start:j_start +
                      T] = e_theta_tilde / e_theta_tilde.sum()
            if is_missing:
                xs_new[p] = np.random.choice(T,
                                             p=theta_new[j_start:j_start + T])
            else:
                logprob_old += np.log(self.theta[l, j_start + x] + 1E-20)
                logprob_new += np.log(theta_new[j_start + xs_new[p]] + 1E-20)
        if itemp != 1.0:
            logprob_old *= itemp
            logprob_new *= itemp
        accepted = np.bool_(rand_partition_log((logprob_old, logprob_new)))
        if accepted:
            if z_old == False:
                # 0 -> 1
                self.zmat[k, l] = True
            else:
                # 1 -> 0
                self.zmat[k, l] = False
            self.theta_tilde[l, :] = theta_tilde_new
            self.theta[l, :] = theta_new
            changed = (self.mat[l, :] != xs_new).sum()
            self.mat[l, :] = xs_new
            return True, changed, self.mvs[l, :].sum()
        else:
            return False, 0, self.mvs[l, :].sum()
Пример #5
0
 def sample_node_state_root(self, node, k):
     assert (not node.is_state_frozen)
     oldv = node.state[k]
     ctmc = self.ctmcs[k]
     logprobs = np.log(np.maximum(ctmc.get_stationary_probs(), 1E-10))
     for child in node.children:
         time = node.date - child.date
         mat = ctmc.get_transition_probs(time)
         logprobs += np.log(
             np.maximum(mat[:, child.state[k].astype(np.int32)], 1E-10))
     newv = rand_partition_log(logprobs)
     node.state[k] = newv
     return not (oldv == newv)
Пример #6
0
 def sample_z(self, l, p):
     k = self.Z[l, p]
     v = self.mat[l, p]
     self.doclist[l].remove(k)
     self.voclist[p][k].remove(v)
     logproblist = np.log(self.doclist[l].problist())
     for k2 in range(self.K):
         logproblist[k2] += np.log(self.voclist[p][k2].prob(v))
     k2 = rand_partition_log(logproblist)
     self.Z[l, p] = k2
     self.doclist[l].add(k2)
     self.voclist[p][k2].add(v)
     return False if k == k2 else True
Пример #7
0
 def sample_x(self, l):
     assert (self.mvs is not None and self.mvs[l])
     x_old = self.vec[l]
     logprobs = np.zeros(self.size, dtype=np.float32)
     if not self.only_alphas:
         if not self.drop_vs:
             logprobs += self.v * np.bincount(self.vec[self.vnet[l]],
                                              minlength=self.size)
         if not self.drop_hs:
             logprobs += self.h * np.bincount(self.vec[self.hnet[l]],
                                              minlength=self.size)
     logprobs += self.alphas
     self.vec[l] = rand_partition_log(logprobs)
     return False if self.vec[l] == x_old else True
Пример #8
0
    def sample_node_state_tree(self, node, k):
        # forward-filtering, backward-sampling
        def _forward(node):
            Ln = np.zeros(D)
            for child in node.children:
                # Lc[s_j]
                Lc = _forward(child)
                time = node.date - child.date
                lmat = np.log(
                    np.maximum(ctmc.get_transition_probs(time), 1E-10))
                for d in range(D):
                    Ln[d] += logsumexp(lmat[d, :] + Lc)
                tscores[child] = lmat
            if node.is_state_frozen:
                for d in range(D):
                    if node.state[k] != d:
                        Ln[d] = -np.inf
            nscores[node] = Ln
            return Ln

        def _backward(node):
            changed, total = 0, 0
            if not node.is_state_frozen:
                total += 1
                pval = node.parent.state[k].astype(np.int32)
                logprobs = nscores[node] + tscores[node][pval, :]
                newv = rand_partition_log(logprobs)
                if node.state[k] != newv:
                    changed += 1
                node.state[k] = newv
            for child in node.children:
                _changed, _total = _backward(child)
                changed += _changed
                total += _total
            return changed, total

        ctmc = self.ctmcs[k]
        D = ctmc.D
        nscores, tscores = {}, {}
        Ln = _forward(node)
        Ln += np.log(np.maximum(ctmc.get_stationary_probs(), 1E-10))
        changed, total = 0, 1
        newv = rand_partition_log(Ln)
        if node.state[k] != newv:
            changed += 1
        for child in node.children:
            _changed, _total = _backward(child)
            changed += _changed
            total += _total
        return changed, total
Пример #9
0
 def sample_x(self, l):
     assert (self.mvs is not None and self.mvs[l])
     x_old = self.vec[l]
     logprobs = np.zeros(self.size, dtype=np.float32)
     if not self.only_alphas:
         if not self.drop_hs:
             idxs, weights = self.hnet.js[l]
             vals = np.zeros(self.size, dtype=np.float32)
             for j, v in enumerate(self.vec[idxs]):
                 vals[v] += weights[j]
             logprobs += self.h * vals
     logprobs += self.alphas
     self.vec[l] = rand_partition_log(logprobs)
     return False if self.vec[l] == x_old else True
Пример #10
0
 def _backward(node):
     changed, total = 0, 0
     if not node.is_state_frozen:
         total += 1
         pval = node.parent.state[k].astype(np.int32)
         logprobs = nscores[node] + tscores[node][pval, :]
         newv = rand_partition_log(logprobs)
         if node.state[k] != newv:
             changed += 1
         node.state[k] = newv
     for child in node.children:
         _changed, _total = _backward(child)
         changed += _changed
         total += _total
     return changed, total
Пример #11
0
    def sample_z(self, l, k, itemp=1.0):
        assert (not self.bias or not k == 0)
        z_old = self.zmat[k, l]
        logprob0, logprob1 = 0.0, 0.0
        if not self.only_alphas:
            idxs, weights = self.hnet.js[l]
            vals = self.zmat[k, idxs]
            logprob0 += self.hks[k] * ((vals == 0) * weights).sum()
            logprob1 += self.hks[k] * ((vals == 1) * weights).sum()
        logprob1 += self.alphas[k]

        theta_new = np.empty_like(self.theta[l, :])
        theta_tilde_new = np.copy(self.theta_tilde[l, :])
        if z_old == False:
            # proposal: 1
            theta_tilde_new += self.wmat[k, :]
            logprob_old, logprob_new = logprob0, logprob1
        else:
            # proposal: 0
            theta_tilde_new -= self.wmat[k, :]
            logprob_old, logprob_new = logprob1, logprob0
        for p in range(self.P):
            j_start, T = self.p2jT[p]
            x = self.mat[l, p]
            logprob_old += np.log(self.theta[l, j_start + x] + 1E-20)
            e_theta_tilde = np.exp(theta_tilde_new[j_start:j_start + T] -
                                   theta_tilde_new[j_start:j_start + T].max())
            theta_new[j_start:j_start +
                      T] = e_theta_tilde / e_theta_tilde.sum()
            logprob_new += np.log(theta_new[j_start + x] + 1E-20)
        if itemp != 1.0:
            logprob_old *= itemp
            logprob_new *= itemp
        accepted = np.bool_(rand_partition_log((logprob_old, logprob_new)))
        if accepted:
            if z_old == False:
                # 0 -> 1
                self.zmat[k, l] = True
            else:
                # 1 -> 0
                self.zmat[k, l] = False
            self.theta_tilde[l, :] = theta_tilde_new
            self.theta[l, :] = theta_new
            return True
        else:
            return False
Пример #12
0
 def sample_tied_h(self):
     logr = 0.0
     oldval = self.h
     P_SIGMA = 0.5
     rate = np.random.lognormal(mean=0.0, sigma=P_SIGMA)
     irate = 1.0 / rate
     newval = rate * oldval
     lograte = np.log(rate)
     logirate = np.log(irate)
     # P(theta') / P(theta)
     # logr += gamma.logpdf(newval, self.gamma_shape, scale=self.gamma_scale) \
     #         - gamma.logpdf(oldval, self.gamma_shape, scale=self.gamma_scale)
     logr += (self.als[0].gamma_shape - 1.0) * (np.log(newval) - np.log(oldval)) \
             - (newval - oldval) / self.als[0].gamma_scale
     # q(theta|theta', x) / q(theta'|theta, x)
     logr += (lograte * lograte - logirate * logirate) / (
         2.0 * P_SIGMA * P_SIGMA) + lograte - logirate
     h = newval
     for al in self.als:
         a = al.alphas
         net = al.hnet
         vec = al.vec.copy()
         llist = np.arange(al.L)
         np.random.shuffle(llist)
         for l in llist:
             logprobs = np.zeros(al.size, dtype=np.float32)
             idxs, weights = al.hnet.js[l]
             vals = np.zeros(al.size, dtype=np.float32)
             for j, v in enumerate(al.vec[idxs]):
                 vals[v] += weights[j]
             logprobs += h * vals
             logprobs += a
             vec[l] = rand_partition_log(logprobs)
         oldsum = al._neighbor_sum(al.vec)
         newsum = al._neighbor_sum(vec)
         logr += (oldval - newval) * (newsum - oldsum)
     if logr >= 0 or np.log(np.random.rand()) < logr:
         # accept
         self.h = newval
         for al in self.als:
             al.h = newval
         return True
     else:
         return False
Пример #13
0
 def sample_autologistic(self, t_type, k):
     logr = 0.0
     if t_type == self.S_Z_A:
         oldval = self.alphas[k]
         pivot = min((self.zmat[k].sum() + 0.01) / self.L, 0.99)
         pivot = np.log(pivot / (1.0 - pivot))
         oldmean = (oldval + pivot) / 2.0
         oldscale = max(abs(oldval - pivot), 0.001)
         newval = np.random.normal(loc=oldmean, scale=oldscale)
         newmean = (newval + pivot) / 2.0
         newscale = max(abs(newval - pivot), 0.001)
         # q(theta|theta', x) / q(theta'|theta, x)
         logr += -((oldval - newmean) ** 2) / (2.0 * newscale * newscale) - np.log(newscale) \
                 + ((newval - oldmean) ** 2) / (2.0 * oldscale * oldscale) + np.log(oldscale)
         # P(theta') / P(theta)
         logr += (oldval * oldval - newval * newval) / (
             2.0 * self.norm_sigma * self.norm_sigma)
         # skip: q(theta|theta', x) / q(theta'|theta, x) for symmetric proposal
         h, a = self.hks[k], newval
     else:
         assert (not self.only_alphas)
         assert (not (t_type == self.S_Z_H and self.drop_hs))
         oldval = self.hks[k]
         P_SIGMA = 0.5
         rate = np.random.lognormal(mean=0.0, sigma=P_SIGMA)
         irate = 1.0 / rate
         newval = rate * oldval
         lograte = np.log(rate)
         logirate = np.log(irate)
         # P(theta') / P(theta)
         logr += (self.gamma_shape - 1.0) * (np.log(newval) - np.log(oldval)) \
                 - (newval - oldval) / self.gamma_scale
         # q(theta|theta', x) / q(theta'|theta, x)
         logr += (lograte * lograte - logirate * logirate) / (
             2.0 * P_SIGMA * P_SIGMA) + lograte - logirate
         h, a = newval, self.alphas[k]
         net = self.hnet
     zvect = self.zmat[k].copy()
     llist = np.arange(self.L)
     np.random.shuffle(llist)
     for l in llist:
         logprob0, logprob1 = (0.0, 0.0)
         if not self.only_alphas:
             idxs, weights = self.hnet.js[l]
             vals = self.zmat[k, idxs]
             logprob0 += h * ((vals == 0) * weights).sum()
             logprob1 += h * ((vals == 1) * weights).sum()
         logprob1 += a
         zvect[l] = rand_partition_log([logprob0, logprob1])
     if t_type == self.S_Z_A:
         logr += (oldval - newval) * (zvect.sum() - self.zmat[k].sum())
         if logr >= 0 or np.log(np.random.rand()) < logr:
             # accept
             self.alphas[k] = newval
             return True
         else:
             return False
     else:
         oldsum = self._neighbor_sum(self.zmat[k])
         newsum = self._neighbor_sum(zvect)
         logr += (oldval - newval) * (newsum - oldsum)
         if logr >= 0 or np.log(np.random.rand()) < logr:
             # accept
             self.hks[k] = newval
             return True
         else:
             return False
Пример #14
0
 def sample_autologistic(self, t_type, k):
     logr = 0.0
     if t_type == self.S_A:
         oldval = self.alphas[k]
         newval = np.random.normal(loc=oldval, scale=0.01)
         # P(theta') / P(theta)
         logr += (oldval**2 - newval**2) / (2.0 * self.norm_sigma *
                                            self.norm_sigma)
         alphas = self.alphas.copy()
         alphas[k] = newval
         v, h, a = self.v, self.h, alphas
     else:
         assert (not self.only_alphas)
         assert (not (t_type == self.S_V and self.drop_vs))
         assert (not (t_type == self.S_H and self.drop_hs))
         if t_type == self.S_V:
             oldval = self.v
         else:
             oldval = self.h
         P_SIGMA = 0.5
         rate = np.random.lognormal(mean=0.0, sigma=P_SIGMA)
         irate = 1.0 / rate
         newval = rate * oldval
         lograte = np.log(rate)
         logirate = np.log(irate)
         # P(theta') / P(theta)
         # logr += gamma.logpdf(newval, self.gamma_shape, scale=self.gamma_scale) \
         #         - gamma.logpdf(oldval, self.gamma_shape, scale=self.gamma_scale)
         logr += (self.gamma_shape - 1.0) * (np.log(newval) - np.log(oldval)) \
                 - (newval - oldval) / self.gamma_scale
         # q(theta|theta', x) / q(theta'|theta, x)
         logr += (lograte * lograte - logirate * logirate) / (
             2.0 * P_SIGMA * P_SIGMA) + lograte - logirate
         if t_type == self.S_V:
             v, h, a = newval, self.h, self.alphas
             net = self.vnet
         else:
             v, h, a = self.v, newval, self.alphas
             net = self.hnet
     vec = self.vec.copy()
     llist = np.arange(self.L)
     np.random.shuffle(llist)
     for l in llist:
         logprobs = np.zeros(self.size, dtype=np.float32)
         if not self.only_alphas:
             if not self.drop_vs:
                 logprobs += v * np.bincount(self.vec[self.vnet[l]],
                                             minlength=self.size)
             if not self.drop_hs:
                 logprobs += h * np.bincount(self.vec[self.hnet[l]],
                                             minlength=self.size)
         logprobs += a
         vec[l] = rand_partition_log(logprobs)
     if t_type == self.S_A:
         logr += (oldval - newval) * ((vec == k).sum() -
                                      (self.vec == k).sum())
         if logr >= 0 or np.log(np.random.rand()) < logr:
             # accept
             self.alphas[k] = newval
             return True
         else:
             return False
     else:
         oldsum = self._neighbor_sum(self.vec, net)
         newsum = self._neighbor_sum(vec, net)
         logr += (oldval - newval) * (newsum - oldsum)
         if logr >= 0 or np.log(np.random.rand()) < logr:
             # accept
             if t_type == self.S_V:
                 self.v = newval
             else:
                 self.h = newval
             return True
         else:
             return False
Пример #15
0
 def sample_autologistic(self, t_type, k):
     logr = 0.0
     if t_type == self.S_Z_A:
         oldval = self.alphas[k]
         pivot = min((self.zmat[k].sum() + 0.01) / self.L, 0.99)
         pivot = np.log(pivot / (1.0 - pivot))
         oldmean = (oldval + pivot) / 2.0
         oldscale = max(abs(oldval - pivot), 0.001)
         newval = np.random.normal(loc=oldmean, scale=oldscale)
         newmean = (newval + pivot) / 2.0
         newscale = max(abs(newval - pivot), 0.001)
         # q(theta|theta', x) / q(theta'|theta, x)
         logr += -((oldval - newmean) ** 2) / (2.0 * newscale * newscale) - np.log(newscale) \
                 + ((newval - oldmean) ** 2) / (2.0 * oldscale * oldscale) + np.log(oldscale)
         # P(theta') / P(theta)
         logr += (oldval * oldval - newval * newval) / (2.0 * self.norm_sigma * self.norm_sigma)
         # skip: q(theta|theta', x) / q(theta'|theta, x) for symmetric proposal
         v, h, a = self.vks[k], self.hks[k], newval
     else:
         assert(not self.only_alphas)
         assert(not (t_type == self.S_Z_V and self.drop_vs))
         assert(not (t_type == self.S_Z_H and self.drop_hs))
         if t_type == self.S_Z_V:
             oldval = self.vks[k]
         else:
             oldval = self.hks[k]
         P_SIGMA = 0.5
         rate = np.random.lognormal(mean=0.0, sigma=P_SIGMA)
         irate = 1.0 / rate
         newval = rate * oldval
         lograte = np.log(rate)
         logirate = np.log(irate)
         # P(theta') / P(theta)
         # logr += gamma.logpdf(newval, self.gamma_shape, scale=self.gamma_scale) \
         #         - gamma.logpdf(oldval, self.gamma_shape, scale=self.gamma_scale)
         logr += (self.gamma_shape - 1.0) * (np.log(newval) - np.log(oldval)) \
                 - (newval - oldval) / self.gamma_scale
         # q(theta|theta', x) / q(theta'|theta, x)
         logr += (lograte * lograte - logirate * logirate) / (2.0 * P_SIGMA * P_SIGMA) + lograte - logirate
         if t_type == self.S_Z_V:
             v, h, a = newval, self.hks[k], self.alphas[k]
             net = self.vnet
         else:
             v, h, a = self.vks[k], newval, self.alphas[k]
             net = self.hnet
     zvect = self.zmat[k].copy()
     llist = np.arange(self.L)
     np.random.shuffle(llist)
     for l in llist:
         logprob0, logprob1 = (0.0, 0.0)
         if not self.only_alphas:
             vcount = np.bincount(zvect[self.vnet[l]], minlength=2)
             logprob0 += v * vcount[0]
             logprob1 += v * vcount[1]
             hcount = np.bincount(zvect[self.hnet[l]], minlength=2)
             logprob0 += h * hcount[0]
             logprob1 += h * hcount[1]
         logprob1 += a
         zvect[l] = rand_partition_log([logprob0, logprob1])
     # V_oldsum = self._neighbor_sum(self.zmat[k], self.vnet)
     # H_oldsum = self._neighbor_sum(self.zmat[k], self.hnet)
     # A_oldsum = self.zmat[k].sum()
     # V_newsum = self._neighbor_sum(zvect, self.vnet)
     # H_newsum = self._neighbor_sum(zvect, self.hnet)
     # A_newsum = zvect.sum()
     # logr += (self.vks[k] * V_newsum + self.hks[k] * H_newsum + self.alphas[k] * A_newsum) \
     #         + (v * V_oldsum + h * H_oldsum + a * A_oldsum) \
     #         - (self.vks[k] * V_oldsum + self.hks[k] * H_oldsum + self.alphas[k] * A_oldsum) \
     #         - (v * V_newsum + h * H_newsum + a * A_newsum)
     # logr += (self.vks[k] * (V_newsum - V_oldsum) + self.hks[k] * (H_newsum - H_oldsum) + self.alphas[k] * (A_newsum - A_oldsum)) \
     #         - (v * (V_newsum - V_oldsum) + h * (H_newsum - H_oldsum) + a * (A_newsum - A_oldsum))
     # logr += ((self.vks[k] - v) * (V_newsum - V_oldsum) + (self.hks[k] - h) * (H_newsum - H_oldsum) + (self.alphas[k] - a) * (A_newsum - A_oldsum))
     if t_type == self.S_Z_A:
         logr += (oldval - newval) * (zvect.sum() - self.zmat[k].sum())
         if logr >= 0 or np.log(np.random.rand()) < logr:
             # accept
             self.alphas[k] = newval
             return True
         else:
             return False
     else:
         oldsum = self._neighbor_sum(self.zmat[k], net)
         newsum = self._neighbor_sum(zvect, net)
         logr += (oldval - newval) * (newsum - oldsum)
         if logr >= 0 or np.log(np.random.rand()) < logr:
             # accept
             if t_type == self.S_Z_V:
                 self.vks[k] = newval
             else:
                 self.hks[k] = newval
             return True
         else:
             return False
Пример #16
0
    def sample_zx(self, l, k, itemp=1.0):
        assert(not self.bias or not k == 0)
        z_old = self.zmat[k,l]
        logprob0, logprob1 = 0.0, 0.0
        if not self.only_alphas:
            vcount = np.bincount(self.zmat[k,self.vnet[l]], minlength=2)
            logprob0 += self.vks[k] * vcount[0]
            logprob1 += self.vks[k] * vcount[1]
            hcount = np.bincount(self.zmat[k,self.hnet[l]], minlength=2)
            logprob0 += self.hks[k] * hcount[0]
            logprob1 += self.hks[k] * hcount[1]
        logprob1 += self.alphas[k]

        theta_new = np.empty_like(self.theta[l,:])
        theta_tilde_new = np.copy(self.theta_tilde[l,:])
        if z_old == False:
            # proposal: 1
            theta_tilde_new += self.wmat[k,:]
            logprob_old, logprob_new = logprob0, logprob1
        else:
            # proposal: 0
            theta_tilde_new -= self.wmat[k,:]
            logprob_old, logprob_new = logprob1, logprob0
        xs_new = self.mat[l,:].copy()
        for p, (x, is_missing) in enumerate(zip(self.mat[l,:], self.mvs[l,:])):
            j_start, T = self.p2jT[p]
            if self.flist[p]["type"] == "cat":
                e_theta_tilde = np.exp(theta_tilde_new[j_start:j_start+T] - theta_tilde_new[j_start:j_start+T].max())
                theta_new[j_start:j_start+T] = e_theta_tilde / e_theta_tilde.sum()
                if is_missing:
                    xs_new[p] = np.random.choice(T, p=theta_new[j_start:j_start+T])
                else:
                    logprob_old += np.log(self.theta[l,j_start+x] + 1E-20)
                    logprob_new += np.log(theta_new[j_start+xs_new[p]] + 1E-20)
            elif self.flist[p]["type"] == "bin":
                theta_new[j_start] = 0.5 * np.tanh(0.5 * theta_tilde_new[j_start]) + 0.5
                if is_missing:
                    xs_new[p] = np.random.random() < theta_new[j_start]
                else:
                    logprob_old += np.log((self.theta[l,j_start] if x == 1 else (1.0 - self.theta[l,j_start])) + 1E-20)
                    logprob_new += np.log((theta_new[j_start] if xs_new[p] == 1 else (1.0 - theta_new[j_start])) + 1E-20)
            elif self.flist[p]["type"] == "count":
                theta_new[j_start] = np.fmax(theta_tilde_new[j_start], 0) + np.log1p(np.exp(-np.fabs(theta_tilde_new[j_start])))
                if is_missing:
                    xs_new[p] = np.random.poisson(lam=theta_new[j_start])
                else:
                    logprob_old += x * np.log(self.theta[l,j_start] + 1E-20)
                    logprob_new += xs_new[p] * np.log(theta_new[j_start] + 1E-20)
            else:
                raise NotImplementedError
        if itemp != 1.0:
            logprob_old *= itemp
            logprob_new *= itemp
        accepted = np.bool_(rand_partition_log((logprob_old, logprob_new)))
        if accepted:
            if z_old == False:
                # 0 -> 1
                self.zmat[k,l] = True
            else:
                # 1 -> 0
                self.zmat[k,l] = False
            self.theta_tilde[l,:] = theta_tilde_new
            self.theta[l,:] = theta_new
            changed = (self.mat[l,:] != xs_new).sum()
            self.mat[l,:] = xs_new
            return True, changed, self.mvs[l,:].sum()
        else:
            return False, 0, self.mvs[l,:].sum()