def info_trans_params(self): # Add the potential from the transitions trans_distn, omega = self.trans_distn, self.trans_omegas prev_state = one_hot(self.stateseq[:-1], self.num_states) next_state = one_hot(self.stateseq[1:], self.num_states) A = trans_distn.A[:, :self.num_states] C = trans_distn.A[:, self.num_states:self.num_states + self.D_latent] # D = trans_distn.A[:, self.num_states+self.D_latent:] b = trans_distn.b CCT = np.array([np.outer(cp, cp) for cp in C]). \ reshape((trans_distn.D_out, self.D_latent ** 2)) J_node = np.dot(omega, CCT) kappa = trans_distn.kappa_func(next_state[:, :-1]) h_node = kappa.dot(C) h_node -= (omega * b.T).dot(C) h_node -= (omega * prev_state.dot(A.T)).dot(C) # h_node[:-1] -= (omega * self.inputs.dot(D.T)).dot(C) # Restore J_node to its original shape J_node = J_node.reshape((self.T - 1, self.D_latent, self.D_latent)) return J_node, h_node
def joint_log_probability(self, logpi, W, stateseqs, covseqs): K, D = self.num_states, self.covariate_dim # Compute the objective ll = 0 for z, x in zip(stateseqs, covseqs): T = z.size assert x.ndim == 2 and x.shape[0] == T - 1 z_prev = one_hot(z[:-1], K) z_next = one_hot(z[1:], K) # Numerator tmp = anp.dot(z_prev, logpi) + anp.dot(x, W) ll += anp.sum(tmp * z_next) # Denominator Z = amisc.logsumexp(tmp, axis=1) ll -= anp.sum(Z) return ll
def resample_transition_auxiliary_variables(self): # Resample the auxiliary variable for the transition matrix trans_distn = self.trans_distn prev_state = one_hot(self.stateseq[:-1], self.num_states) next_state = one_hot(self.stateseq[1:], self.num_states) A = trans_distn.A[:, :self.num_states] C = trans_distn.A[:, self.num_states:self.num_states + self.D_latent] # D = trans_distn.A[:, self.num_states+self.D_latent:] b = trans_distn.b psi = prev_state.dot(A.T) \ + self.covariates.dot(C.T) \ + b.T \ # + self.inputs.dot(D.T) \ b_pg = trans_distn.b_func(next_state[:,:-1]) import pypolyagamma as ppg ppg.pgdrawvpar(self.ppgs, b_pg.ravel(), psi.ravel(), self.trans_omegas.ravel())
def align_lags(stateseq, covseq): prev_state = one_hot(stateseq[:-1], self.num_states) next_state = one_hot(stateseq[1:], self.num_states) return np.column_stack([prev_state, covseq]), next_state
def initialize_with_logistic_regression(self, zs, xs, initialize=False): from sklearn.linear_model.logistic import LogisticRegression if not hasattr(self, '_lr'): self._lr = LogisticRegression(verbose=False, multi_class="multinomial", solver="lbfgs", warm_start=True, max_iter=10) lr = self._lr # Make the covariates K, D = self.num_states, self.covariate_dim # Split zs into prevs and nexts zps = zs[:-1] if isinstance(zs, np.ndarray) else np.concatenate( [z[:-1] for z in zs], axis=0) zns = zs[1:] if isinstance(zs, np.ndarray) else np.concatenate( [z[1:] for z in zs], axis=0) xps = xs[:-1] if isinstance(xs, np.ndarray) else np.concatenate( [x[:-1] for x in xs], axis=0) assert zps.shape[0] == xps.shape[0] assert zps.ndim == 1 and zps.dtype == np.int32 and zps.min( ) >= 0 and zps.max() < K assert zns.ndim == 1 and zns.dtype == np.int32 and zns.min( ) >= 0 and zns.max() < K assert xps.ndim == 2 and xps.shape[1] == D used = np.bincount(zns, minlength=K) > 0 K_used = np.sum(used) lr_X = np.column_stack((one_hot(zps, K), xps)) lr_y = zns # The logistic regression solver fails if we only have one class represented # In this case, set the regression weights to zero and set logpi to have # high probability of the visited class if K_used == 1: self.W = np.zeros((D, K)) self.log_pi = np.zeros((K, K)) self.log_pi[:, used] = 3.0 else: lr.fit(lr_X, lr_y) # Now convert the logistic regression into weights if K_used > 2: self.W = np.zeros((D, K)) self.W[:, used] = lr.coef_[:, K:].T self.logpi = np.zeros((K, K)) self.logpi[:, used] = lr.coef_[:, :K].T self.logpi[:, used] += lr.intercept_[None, :] self.logpi[:, ~used] += -100. elif K_used == 2: # LogisticRegression object only represents one # set of weights for binary problems self.W = np.zeros((D, K)) self.W[:, 1] = lr.coef_[0, K:] self.logpi = np.zeros((K, K)) self.logpi[:, 1] = lr.coef_[0, :K].T self.logpi[:, 1] += lr.intercept_
def align_lags(stateseq, covseq): prev_state = np.zeros((stateseq.shape[0] - 1, self.num_states)) next_state = one_hot(stateseq[1:], self.num_states) return np.column_stack([prev_state, covseq]), next_state