def mhmm_logprob(data, prior, transmat, mu, Sigma, mixmat=None): ''' % LOG_LIK_MHMM Compute the log-likelihood of a dataset using a (mixture of) Gaussians HMM % [loglik, errors] = log_lik_mhmm(data, prior, transmat, mu, sigma, mixmat) % % data{m}(:,t) or data(:,t,m) if all cases have same length % errors is a list of the cases which received a loglik of -infinity % % Set mixmat to ones(Q,1) or omit it if there is only 1 mixture component ''' Q = len(prior); if mixmat.shape[0] != Q: # trap old syntax raise Exception, 'mixmat should be QxM' if mixmat==None: mixmat = np.ones((Q,1)) if not isinstance(data, list): data = [data[:,:,i] for i in range(data.shape[2])] ncases = len(data); loglik = 0 errors = [] for m in range(ncases): obslik, _ = mixgauss_prob(data[m], mu, Sigma, mixmat); alpha, beta, gamma, ll, _, _ = fwdback(prior, transmat, obslik, fwd_only=True) if ll==-np.Inf: errors.append(m) loglik = loglik + ll return loglik, errors
def test_1D_M2_Spherical(self): m = np.array([[1, 2]]) C = 1 x = np.matrix([1]) B, B2 = mixgauss_prob(x, m, C) assert np.all(np.abs(B==np.matrix([[0.3989],[0.2420]])) < 1e-3) assert np.all(np.abs(B2==np.array([[[0.3989]],[[0.2420]]])) < 1e-3)
def test_1D_M1_Spherical(self): m = np.matrix([1]) C = 1 x = np.matrix([1]) B, B2 = mixgauss_prob(x, m, C) assert np.all(np.abs(B==np.matrix([[0.3989]])) < 1e-3) assert np.all(np.abs(B2==np.matrix([[0.3989]])) < 1e-3)
def test2D_M2_tied_ind_MQ(self): m = np.matrix([[1], [2]]) C = np.matrix([[1, 0], [0, 1]]) x = np.matrix([[1], [2]]) B, B2 = mixgauss_prob(x, m, C) assert np.all(np.abs(B == np.matrix([[0.1592]])) < 1e-3) assert np.all(np.abs(B2 == np.matrix([[0.1592]])) < 1e-3)
def test_1D_M2_Spherical(self): m = np.array([[1, 2]]) C = 1 x = np.matrix([1]) B, B2 = mixgauss_prob(x, m, C) assert np.all(np.abs(B == np.matrix([[0.3989], [0.2420]])) < 1e-3) assert np.all(np.abs(B2 == np.array([[[0.3989]], [[0.2420]]])) < 1e-3)
def test_1D_M1_Spherical(self): m = np.matrix([1]) C = 1 x = np.matrix([1]) B, B2 = mixgauss_prob(x, m, C) assert np.all(np.abs(B == np.matrix([[0.3989]])) < 1e-3) assert np.all(np.abs(B2 == np.matrix([[0.3989]])) < 1e-3)
def test2D_M2_tied_ind_MQ(self): m = np.matrix([[1],[2]]) C = np.matrix([[1,0], [0,1]]) x = np.matrix([[1], [2]]) B, B2 = mixgauss_prob(x, m, C) assert np.all(np.abs(B==np.matrix([[0.1592]])) < 1e-3) assert np.all(np.abs(B2==np.matrix([[0.1592]])) < 1e-3)
def ess_mhmm(prior, transmat, mixmat, mu, Sigma, data): ''' % ESS_MHMM Compute the Expected Sufficient Statistics for a MOG Hidden Markov Model. % % Outputs: % exp_num_trans(i,j) = sum_l sum_{t=2}^T Pr(Q(t-1) = i, Q(t) = j| Obs(l)) % exp_num_visits1(i) = sum_l Pr(Q(1)=i | Obs(l)) % % Let w(i,k,t,l) = P(Q(t)=i, M(t)=k | Obs(l)) % where Obs(l) = Obs(:,:,l) = O_1 .. O_T for sequence l % Then % postmix(i,k) = sum_l sum_t w(i,k,t,l) (posterior mixing weights/ responsibilities) % m(:,i,k) = sum_l sum_t w(i,k,t,l) * Obs(:,t,l) % ip(i,k) = sum_l sum_t w(i,k,t,l) * Obs(:,t,l)' * Obs(:,t,l) % op(:,:,i,k) = sum_l sum_t w(i,k,t,l) * Obs(:,t,l) * Obs(:,t,l)' ''' verbose = False # [O T numex] = size(data); numex = len(data) O = data[0].shape[0] Q = len(prior) M = mixmat.shape[1] exp_num_trans = np.zeros((Q, Q)); exp_num_visits1 = np.zeros((Q, 1)); postmix = np.zeros((Q, M)); m = np.zeros((O, Q, M)); op = np.zeros((O, O, Q, M)); ip = np.zeros((Q, M)); mix = M > 1 loglik = 0 if verbose: print 'forwards-backwards example # ' for ex in range(0, numex): if verbose: print '%d ' % ex # obs = data(:,:,ex); obs = data[ex] T = obs.shape[1] if mix: B, B2 = mixgauss_prob(obs, mu, Sigma, mixmat) alpha, beta, gamma, current_loglik, xi_summed, gamma2 = fwdback(prior, transmat, B, obslik2=B2, mixmat=mixmat, compute_xi=True, compute_gamma2=True) else: B, B2 = mixgauss_prob(obs, mu, Sigma) alpha, beta, gamma, current_loglik, xi_summed, _ = fwdback(prior, transmat, B) loglik = loglik + current_loglik if verbose: print 'll at ex %d = %f\n' % (ex, loglik) exp_num_trans = exp_num_trans + xi_summed # sum(xi,2) exp_num_visits1 = exp_num_visits1 + gamma[:, 0] if mix: postmix = postmix + np.sum(gamma2, 2) else: postmix = postmix + np.sum(gamma, 1) gamma2 = np.reshape(gamma, (Q, 1, T)) # gamma2(i,m,t) = gamma(i,t) for i in range(0, Q): for k in range(0, M): w = np.reshape(gamma2[i, k, :], (1, T)) # w(t) = w(i,k,t,l) wobs = np.multiply(obs,w) # np.repmat(w, [O 1]) # wobs(:,t) = w(t) * obs(:,t) m[:, i, k] = m[:, i, k] + np.sum(wobs, 1) # m(:) = sum_t w(t) obs(:,t) op[:, :, i, k] = op[:, :, i, k] + np.dot(wobs, obs.T) # op(:,:) = sum_t w(t) * obs(:,t) * obs(:,t)' ip[i, k] = ip[i, k] + np.sum(np.sum(np.multiply(wobs, obs), 1)) # ip = sum_t w(t) * obs(:,t)' * obs(:,t) if verbose: print return loglik, exp_num_trans, np.asarray(exp_num_visits1)[:,0], postmix, m, ip, op