Пример #1
0
 def _update_trans(self, elngamma, elnxi, n_obs):
     for i in range(self.n_states):
         for j in range(self.n_states):
             numerator = -np.inf
             denominator = -np.inf
             for k in range(n_obs - 1):
                 numerator = elnsum(numerator, elnxi[i, j, k])
                 denominator = elnsum(denominator, elngamma[i, k])
             self.trans[i, j] = eexp(elnproduct(numerator, -denominator))
Пример #2
0
 def _update_emis(self, elngamma, obs_seq):
     for e in range(self.emis.shape[0]):
         for i in range(self.n_states):
             numerator = -np.inf
             denominator = -np.inf
             for k in range(len(obs_seq)):
                 if obs_seq[k] - 1 == e:
                     numerator = elnsum(numerator, elngamma[i, k])
                 denominator = elnsum(denominator, elngamma[i, k])
             self.emis[e, i] = eexp(elnproduct(numerator, -denominator))
Пример #3
0
    def viterbi_path(self):

        init = np.array([eln(val) for val in np.nditer(self.init)])
        trans = np.array([[eln(v) for v in np.nditer(axis)] for axis in np.nditer(self.trans)]).reshape(self.n_states, self.n_states)
        print(np.array([[eln(v) for v in np.nditer(axis)] for axis in np.nditer(self.emis)]))
        emis = np.array([[eln(v) for v in np.nditer(axis)] for axis in np.nditer(self.emis)]).reshape(self.emis.shape[1], self.emis.shape[0])

        best_states = []

        logprob = init
        for k in range(0, self.n_obs):
            trans_p = np.zeros([self.n_states, self.n_states])
            for i in range(self.n_states):
                for j in range(self.n_states):
                    trans_p[i, j] = elnsum(logprob[i], elnproduct(trans[i, j], emis[i, self.obs[k-1]]))
            # Get the indices of the max probs that give the best prior states.
            best_states.append(np.argmax(trans_p, axis=0))
            logprob = np.max(trans_p, axis=0)
        print(len(best_states))
        # Most likely final state.
        final_state = np.argmax(logprob)
        print(final_state)
        # Reconstruct path by backtracking through likeliest states.
        prior_state = final_state
        best_path = [prior_state + 1]
        for best in reversed(best_states):
            prior_state = best[prior_state]
            best_path.append(prior_state + 1)
        return list(reversed(best_path)), logprob[final_state]
Пример #4
0
    def _update_emis_eln(self, elngammas):
        """
        This function calculates the update of the transition probabilities as defined by the Berkeley notes references in the _m_step algorithm.

        The numerator is the eln_xi values summed across all sequences and across all time steps.
        The denominator is the eln_gamma values summed across all sequences and across all time steps.
        """
        for e in range(self.emis.shape[0]):
            for i in range(self.n_states):
                numerator = -np.inf
                denominator = -np.inf
                for idx, obs_seq in enumerate(self.sequences):
                    for k in range(0, len(obs_seq)):
                        if obs_seq[k] == e:
                            numerator = elnsum(numerator, elngammas[idx][i, k])
                        denominator = elnsum(denominator, elngammas[idx][i, k])
                self.emis[e, i] = eexp(elnproduct(numerator, -denominator))
Пример #5
0
    def _update_trans_eln(self, gammas, xis):
        """
        This function calculates the update of the transition probabilities as defined by the Berkeley notes references in the _m_step algorithm.

        The numerator is the eln_gamma values summed across all sequences and across all time steps.
        The denominator is the eln_gamma values summed across all sequences and across all time steps.
        """
        for i in range(self.n_states):
            for j in range(self.n_states):
                numerator = -np.inf
                denominator = -np.inf
                for idx, obs_seq in enumerate(self.sequences):
                    for k in range(1, len(obs_seq)):
                        numerator = elnsum(numerator, elnxis[idx][i, j, k - 1])
                        denominator = elnsum(denominator,
                                             elngammas[idx][i, k - 1])
                self.trans[i, j] = eexp(elnproduct(numerator, -denominator))
Пример #6
0
 def _update_init_eln(self, elngammas):
     """
     This function calculate the update value of the initial probabilities as defined by the Berkeley notes references in the _m_step algorithm. It is the average of the sum of probabilities of x_1 over all sequences. i.e. the expected frequency of state Si at time t = 1
     """
     for i in range(self.n_states):
         numerator = -np.inf
         denominator = 0
         for idx in range(len(self.sequences)):
             numerator = elnsum(numerator, elngammas[idx][i, 0])
             denominator = denominator + 1
         self.init[i] = eexp(numerator) / denominator
Пример #7
0
 def _generate_gamma(self, elnalpha, elnbeta):
     elngamma = np.zeros((self.n_states, self.n_obs + 1))
     gamma = np.zeros((self.n_states, self.n_obs + 1))
     for k in range(0, self.n_obs + 1):
         norm = -np.inf
         for i in range(self.n_states):
             elngamma[i, k] = elnproduct(elnalpha[i, k], elnbeta[i, k])
             norm = elnsum(norm, elngamma[i, k])
         for i in range(self.n_states):
             elngamma[i, k] = elnproduct(elngamma[i, k], -norm)
             gamma[i, k] = eexp(elngamma[i, k])
     return elngamma, gamma
Пример #8
0
 def forward_backward_eln(self):
     logalphas = self._forward_iter_eln()
     logbetas = self._backward_iter_eln()
     print(logalphas.shape)
     print(logbetas.shape)
     probs = np.zeros((self.n_states, self.n_obs + 1))
     for k in range(0, self.n_obs + 1):
         norm = -np.inf
         for i in range(self.n_states):
             probs[i, k] = elnproduct(logalphas[i, k], logbetas[i, k])
             norm = elnsum(norm, probs[i, k])
         for i in range(self.n_states):
             probs[i, k] = elnproduct(probs[i, k], -norm)
     # for i in range(self.n_obs):
     #     print(sum([p for p in list(probs[:, i]) if p != -np.inf]))
     return probs, logalphas, logbetas
Пример #9
0
 def _backward_iter_eln(self):
     elnbeta = np.zeros((self.n_states, self.n_obs + 1))
     # base case
     elnbeta[:, -1] = 0
     # recursive case
     for k in range(self.n_obs, 0, -1):
         for i in range(self.n_states):
             beta = -np.inf
             for j in range(self.n_states):
                 beta = elnsum(
                     beta,
                     elnproduct(
                         eln(self.trans.transpose()[i, j]),
                         elnproduct(eln(self.emis[self.obs[k - 1], j]),
                                    elnbeta[j, k])))
             elnbeta[i, k - 1] = beta
     return elnbeta
Пример #10
0
    def _forward_iter_eln(self):
        elnalpha = np.zeros((self.n_states, self.n_obs + 1))

        # base case
        elnalpha[:, 0] = [eln(x) for x in self.init]
        # recursive case
        for k in range(1, self.n_obs + 1):
            for j in range(self.n_states):
                logalpha = -np.inf
                for i in range(self.n_states):
                    logalpha = elnsum(
                        logalpha,
                        elnproduct(elnalpha[i, k - 1],
                                   eln(self.trans.transpose()[i, j])))
                elnalpha[j, k] = elnproduct(logalpha,
                                            eln(self.emis[self.obs[k - 1], j]))
        return elnalpha
Пример #11
0
 def _backward_iter_eln(self):
     logbetas = np.zeros((self.n_states, self.n_obs + 1))
     # base case
     logbetas[:, -1] = 0
     print(logbetas.transpose)
     # recursive case
     for k in range(self.n_obs, 0, -1):
         for i in range(self.n_states):
             logbeta = -np.inf
             for j in range(self.n_states):
                 logbeta = elnsum(
                     logbeta,
                     elnproduct(
                         eln(self.trans.transpose()[i, j]),
                         elnproduct(eln(self.emis[self.obs[k - 1], j]),
                                    logbetas[j, k])))
             logbetas[i, k - 1] = logbeta
     return logbetas
Пример #12
0
 def _eln_xi(self, elnalpha, elnbeta, obs_seq):
     elnxi = np.zeros((self.n_states, self.n_states, len(obs_seq)))
     for k in range(len(obs_seq) - 1, -1, -1):
         normalizer = -np.inf
         for i in range(self.n_states):
             for j in range(self.n_states):
                 elnxi[i, j, k - 1] = elnproduct(
                     elnalpha[i, k - 1],
                     elnproduct(
                         eln(self.trans.transpose()[i, j]),
                         elnproduct(eln(self.emis[obs_seq[k] - 1, j]),
                                    elnbeta[j, k])))
                 normalizer = elnsum(normalizer, elnxi[i, j, k - 1])
         for i in range(self.n_states):
             for j in range(self.n_states):
                 elnxi[i, j, k - 1] = elnproduct(elnxi[i, j, k - 1],
                                                 -normalizer)
     return elnxi
Пример #13
0
 def _eln_xi(self, elnalpha, elnbeta, obs_seq):
     """
     This function calculates P(S_i_t, S_j_t+1) i.e. the probability of being in state S_i at time t and state S_j at time t+1.
     """
     elnxi = np.zeros((self.n_states, self.n_states, len(obs_seq) - 1))
     xi = np.zeros((self.n_states, self.n_states, len(obs_seq) - 1))
     for k in range(len(obs_seq) - 1):
         normalizer = -np.inf
         for i in range(self.n_states):
             for j in range(self.n_states):
                 elnxi[i, j, k] = elnproduct(
                     elnalpha[i, k],
                     elnproduct(
                         eln(self.trans.transpose()[i, j]),
                         elnproduct(eln(self.emis[obs_seq[k + 1], j]),
                                    elnbeta[j, k + 1])))
                 normalizer = elnsum(normalizer, elnxi[i, j, k])
         for i in range(self.n_states):
             for j in range(self.n_states):
                 elnxi[i, j, k] = elnproduct(elnxi[i, j, k], -normalizer)
                 xi[i, j, k] = eexp(elnxi[i, j, k])
     return elnxi, xi