def _exact_loglikelihood(self, ob): log_transmat = np.zeros((self.n_chains, self.n_states, self.n_states)) log_startprob = np.zeros((self.n_chains, self.n_states)) for idx, chain in enumerate(self.chains_): log_transmat[idx] = chain._log_transmat log_startprob[idx] = chain._log_startprob n_state_combinations = self.n_states ** self.n_chains state_combinations = [tuple(x) for x in list(itertools.product(np.arange(self.n_states), repeat=self.n_chains))] n_observations = ob.shape[0] n_features = ob.shape[1] fwdlattice = np.zeros((n_observations, n_state_combinations)) # Calculate means and covariances for all state combinations and calculate emission probabilities weight = (1.0 / float(self.n_chains)) weight_squared = weight * weight covars = np.zeros((n_state_combinations, n_features)) # TODO: add support for all covariance types means = np.zeros((n_state_combinations, n_features)) for idx, state_combination in enumerate(state_combinations): for chain_idx, state in enumerate(state_combination): chain = self.chains_[chain_idx] covars[idx] += chain._covars_[state] means[idx] += chain._means_[state] covars[idx] *= weight_squared means[idx] *= weight framelogprob = log_multivariate_normal_density(ob, means, covars, covariance_type='diag') # TODO: add support for all covariance types # Run the forward algorithm fhmmc._forward(n_observations, self.n_chains, self.n_states, state_combinations, log_startprob, log_transmat, framelogprob, fwdlattice) last_column = fwdlattice[-1] assert np.size(last_column) == n_state_combinations score = logsumexp(last_column) return score
def _do_forward_pass(self, framelogprob): n_observations = framelogprob.shape[0] state_combinations = [tuple(x) for x in list(itertools.product(np.arange(self.n_states), repeat=self.n_chains))] fwdlattice = np.zeros((n_observations, self.n_states ** self.n_chains)) fhmmc._forward(n_observations, self.n_chains, self.n_states, state_combinations, self.log_startprob, self.log_transmat, framelogprob, fwdlattice) return logsumexp(fwdlattice[-1]), fwdlattice
def _do_forward_pass(self, framelogprob): n_observations = framelogprob.shape[0] state_combinations = [ tuple(x) for x in list( itertools.product(np.arange(self.n_states), repeat=self.n_chains)) ] fwdlattice = np.zeros((n_observations, self.n_states**self.n_chains)) fhmmc._forward(n_observations, self.n_chains, self.n_states, state_combinations, self.log_startprob, self.log_transmat, framelogprob, fwdlattice) return logsumexp(fwdlattice[-1]), fwdlattice
def _exact_loglikelihood(self, ob): log_transmat = np.zeros((self.n_chains, self.n_states, self.n_states)) log_startprob = np.zeros((self.n_chains, self.n_states)) for idx, chain in enumerate(self.chains_): log_transmat[idx] = chain._log_transmat log_startprob[idx] = chain._log_startprob n_state_combinations = self.n_states**self.n_chains state_combinations = [ tuple(x) for x in list( itertools.product(np.arange(self.n_states), repeat=self.n_chains)) ] n_observations = ob.shape[0] n_features = ob.shape[1] fwdlattice = np.zeros((n_observations, n_state_combinations)) # Calculate means and covariances for all state combinations and calculate emission probabilities weight = (1.0 / float(self.n_chains)) weight_squared = weight * weight covars = np.zeros( (n_state_combinations, n_features)) # TODO: add support for all covariance types means = np.zeros((n_state_combinations, n_features)) for idx, state_combination in enumerate(state_combinations): for chain_idx, state in enumerate(state_combination): chain = self.chains_[chain_idx] covars[idx] += chain._covars_[state] means[idx] += chain._means_[state] covars[idx] *= weight_squared means[idx] *= weight framelogprob = log_multivariate_normal_density( ob, means, covars, covariance_type='diag' ) # TODO: add support for all covariance types # Run the forward algorithm fhmmc._forward(n_observations, self.n_chains, self.n_states, state_combinations, log_startprob, log_transmat, framelogprob, fwdlattice) last_column = fwdlattice[-1] assert np.size(last_column) == n_state_combinations score = logsumexp(last_column) return score
def test_forward_with_hmmlearn(self): r = np.random.randn obs = [np.array([[-600 + r(), 100 + r()], [-300 + r(), 200 + r()], [0 + r(), 300 + r()]]) for _ in xrange(10)] hmm = GaussianHMM(n_components=3) hmm.fit(obs) # Calculcate fwdlattice using hmmlearn algorithm framelogprob = hmm._compute_log_likelihood(obs[0]) start = timeit.default_timer() _, fwdlattice1 = hmm._do_forward_pass(framelogprob) print('hmmlearn took %fs' % (timeit.default_timer() - start)) # Calculate fwdlattice using fhmm algorithm with #chains = 1. This should yield the exact same results start = timeit.default_timer() fwdlattice2 = np.zeros(fwdlattice1.shape) fhmmc._forward(obs[0].shape[0], 1, hmm.n_components, [(x,) for x in xrange(hmm.n_components)], hmm._log_startprob.reshape(1, 3), hmm._log_transmat.reshape(1, 3, 3), framelogprob, fwdlattice2) print('fhmm took %fs' % (timeit.default_timer() - start)) self.assertTrue(np.allclose(fwdlattice1, fwdlattice2))