def path(prior,transition_matrix,emission_matrix,observation_vector,scaling=True): print "Starting Viterbi" print observation_vector.shape number_of_hidden_states=len(prior) number_of_observations=len(observation_vector) shape_delta=(number_of_hidden_states,number_of_observations) shape_psi=shape_delta delta=np.zeros(shape_delta) psi=np.zeros(shape_psi,dtype=np.int) scale=np.ones(number_of_observations) optimum_path=np.zeros(number_of_observations,dtype=np.int) '''1.Initialization''' first_observation=observation_vector[0] # first_observation,"Frist " #print prior,"Prior" #print emission_matrix[first_observation:,0],"Emission" #print prior*emission_matrix[first_observation][0],"Prod" #print emission_matrix[5:,0],"ya" #print emission_matrix[0][first_observation],emission_matrix[0][first_observation].shape for i in range(number_of_hidden_states): delta[i][0]=prior[i]*emission_matrix[i][first_observation] psi[i,0]=0 #print delta if scaling: [delta[:,0], n] = normalize(delta[:,0]) scale[0] = 1/n '''2.Recursion''' '''Currently non vectorized''' for t in range(1,number_of_observations): for j in range(0,number_of_hidden_states): p=0 for i in range(0,number_of_hidden_states): p=delta[i][t-1]*transition_matrix[i][j]*emission_matrix[j][observation_vector[t]] if p>delta[j][t]: delta[j][t]=p psi[j][t]=i #print delta if scaling: [delta[:,t], n] = normalize(delta[:,t]) scale[t] = 1/n '''3.Termination''' p_star=max(delta[:,number_of_observations-1]) optimum_path[number_of_observations-1]=np.argmax(delta[:,number_of_observations-1]) '''4.Path Backtracking''' for t in range(number_of_observations-2,-1,-1): optimum_path[t]=psi[optimum_path[t+1]][t] '''Log Probability''' if scaling: loglik=-sum(np.log(scale)) else: loglik=np.log(p_star) return [optimum_path,delta,loglik]
def dhmm_em(observation_i,prior,transition_matrix,emission_matrix,max_iter,thresh): previous_loglik = -np.inf loglik = 0 converged = False num_iter = 1 LL = [] while (num_iter <= max_iter) and not converged : #E step [loglik,exp_num_visits1,exp_num_visitsT,exp_num_trans,exp_num_emit]=compute_ess_dhmm(observation_i,prior,transition_matrix,emission_matrix, 0) #[loglik, prior,A,B] = compute_ess_dhmm(observation_i,hidden,prior,transition_matrix,emission_matrix, 0) #print "-----------ITERATION "+str(num_iter)+"----------" #M Step #prior = prior prior=normalize(exp_num_visits1)[0] #print "AFTER M STEP:",prior transition_matrix = mk_stochastic(exp_num_trans) #emission_matrix = mk_stochastic(B) emission_matrix=mk_stochastic(exp_num_emit) num_iter = num_iter + 1 [converged,decrease] = em_converged(loglik, previous_loglik, thresh,False) previous_loglik = loglik LL.append(loglik) #print "Log Likelihood:",LL return [LL, prior, transition_matrix, emission_matrix, num_iter]
def forward(prior,transition_matrix,emission_matrix,observation_vector,scaling=True): number_of_hidden_states=len(prior) number_of_observations=len(observation_vector) shape_alpha=(number_of_hidden_states,number_of_observations) alpha=np.zeros(shape_alpha) scale=np.ones(number_of_observations) xi_summed = np.zeros((number_of_hidden_states,number_of_hidden_states)) '''1.Initialization''' t=0 first_observation=observation_vector[t] alpha[:,t]=prior*emission_matrix[first_observation:,t] if scaling: [alpha[:,0], n] = normalize(alpha[:,0]) scale[0] = 1/n; '''2.Induction''' '''Currently Non-vectorized''' for t in range(1,number_of_observations): for j in range(0,number_of_hidden_states): prob_sum=0 for i in range(0,number_of_hidden_states): prob_sum+=alpha[i][t-1]+transition_matrix[i][j] alpha[j][t]=prob_sum*emission_matrix[j][observation_vector[t]] if scaling: [alpha[:,t], n] = normalize(alpha[:,t]) scale[t] = 1/n xi_summed = xi_summed + normalise(np.dot(alpha[:,t-1] ,emission_matrix[:,t].H) * transition_matrix) '''3.Termination''' if scaling: loglik=sum(np.log(scale)) else: loglik=np.log(sum(alpha[:,number_of_observations])) return alpha,loglik
def backward(prior,transition_matrix,emission_matrix,observation_vector,scaling=True): number_of_hidden_states=len(prior) number_of_observations=len(observation_vector) shape_alpha=(number_of_hidden_states,number_of_observations) beta=np.ones(shape_alpha) scale=np.ones(number_of_observations) '''1.Initialization''' '''We have already set beta as a sequence of 1's.''' '''2.Induction''' '''Currently Non-vectorized''' for t in range(number_of_observations-1,1,-1): for i in range(0,number_of_hidden_states): beta_sum=0 for j in range(0,number_of_hidden_states): beta_sum+=beta[i][t-1]+transition_matrix[i][j] beta[i][t]=beta_sum*emission_matrix[j][observation_vector[t]] if scaling: [beta[:,t], n] = normalize(beta[:,t]); scale[t] = 1/n;
import numpy as np from underflow_normalize import normalize,mk_stochastic from sample import * from dhmm_em import dhmm_em O = 3 Q = 2 #"true" parameters prior0 = normalize(np.random.rand(Q,1))[0] prior0 =np.array([.5,.5]) transmat0 = mk_stochastic(np.random.rand(Q,Q)) transmat0=np.array([[.3 ,.7],[.7,.3]]) obsmat0 = mk_stochastic(np.random.rand(Q,O)) obsmat0=np.array([[.333,.333,.333],[.333,.333,.333]]) print "True Parameters" print "-"*80 print "Prior:",prior0 print "Observation",obsmat0 print "Transition:",transmat0 # training data T = 1 nex =5 [obs,hidden] = sample_dhmm(prior0, transmat0, obsmat0, T, nex) #print hidden,obs# initial guess of parameters prior1 = normalize(np.random.rand(Q,1))[0]
def compute_ess_dhmm(observation_vector,prior,transition_matrix,emission_matrix, dirichlet): #print "__________________________________" #print "Observation:",observation_vector,"\n","Hidden:",hidden,"\n","Prior",prior,"\n","Transition",transition_matrix,"\n","Emission",emission_matrix (S,O)=np.shape(emission_matrix) exp_num_trans=np.zeros((S,S)) exp_num_visits1=np.zeros((1,S)).flatten(1) exp_num_visitsT=np.zeros((1,S)).flatten(1) exp_num_emit = dirichlet*np.ones((S,O)) loglik = 0 num_sequences=len(observation_vector) for i in range(num_sequences): observation_i=observation_vector[i] #Number of observations T=len(observation_i) obslik = evaluate_pdf_cond_multinomial(observation_i, emission_matrix) #E [alpha, beta, gamma, xi,xi_summed,current_ll] = forward_backward(prior, transition_matrix, emission_matrix,observation_i,True,obslik) loglik = loglik + current_ll exp_num_trans = exp_num_trans + xi_summed #print "EXPETCED VISISTS 1 BEFORE",exp_num_visits1 exp_num_visits1 += gamma[:,0] #print "EXPETCED VISISTS 1 AFTER",exp_num_visits1 exp_num_visitsT = exp_num_visitsT + gamma[:,T-1] #print "Visits 1",exp_num_visits1 #print "Visits T",exp_num_visitsT #print "EXP NUM TRANS",exp_num_trans for t in range(0,T): o = observation_i[t] exp_num_emit[:,o] = exp_num_emit[:,o] + gamma[:,t] #print "Log Likelihood:",loglik #print "Exp Num Transitions",exp_num_trans #print "Exp Num Visits 1",exp_num_visits1 #print "Exp Num Visits T",exp_num_visitsT #print "Exp Num Emit",exp_num_emit #print "Xi Summed",xi_summed #print "Sequence",np.array(observation_i)+1 #print "Alpha",alpha #print "Beta",beta #raw_input('After iteration%s'%i) new_pi=normalize(gamma[:,0])[0] new_A=xi_summed/np.sum(gamma,1) (number_of_hidden_states,number_of_observation_states)=np.shape(emission_matrix) B_new = np.zeros(np.shape(emission_matrix)) for j in xrange(number_of_hidden_states): for k in xrange(number_of_observation_states): numer = 0.0 denom = 0.0 for t in xrange(T): if observation_i[t] == k: numer += gamma[j][t] denom += gamma[j][t] B_new[j][k] = numer/denom #print "******************************" #print "New Pi:",new_pi #print "New A:",new_A #print "After normalizing",mk_stochastic(new_A) return [loglik,exp_num_visits1,exp_num_visitsT,exp_num_trans,exp_num_emit]
def forward_backward(prior,transition_matrix,emission_matrix,observation_vector,scaling,obslik): number_of_hidden_states=len(prior) number_of_observations=len(observation_vector) shape_alpha=(number_of_hidden_states,number_of_observations) alpha=np.zeros(shape_alpha) scale=np.ones(number_of_observations) xi = np.zeros((number_of_observations,number_of_hidden_states,number_of_hidden_states)) gamma=np.zeros(shape_alpha) gamma2=np.zeros(shape_alpha) xi_summed=np.zeros((number_of_hidden_states,number_of_hidden_states)) '''Forwards''' '''1.Initialization''' t=0 ''' first_observation=observation_vector[t] print "Forward Backward" print prior,emission_matrix[first_observation:,t] print prior*emission_matrix[first_observation:,t],np.shape(prior*emission_matrix[first_observation:,t]) print print np.dot(prior,emission_matrix[first_observation:,t]) alpha[:,t]=np.dot(prior,emission_matrix[first_observation:,t]) ''' for i in range(0,number_of_hidden_states): alpha[i][0]=prior[i]*emission_matrix[i][observation_vector[0]] #print "Prior_i",prior[i] #print "Obs",observation_vector[0] #print emission_matrix[i][observation_vector[0]] if scaling: [alpha[:,0], n] = normalize(alpha[:,0]) scale[0] = n else: pass '''2.Induction''' '''Currently Non-vectorized''' for t in range(1,number_of_observations): for j in range(0,number_of_hidden_states): prob_sum=0 for i in range(0,number_of_hidden_states): prob_sum+=alpha[i][t-1]*transition_matrix[i][j] alpha[j][t]=prob_sum*emission_matrix[j][observation_vector[t]] if scaling: [alpha[:,t], n] = normalize(alpha[:,t]) scale[t] = n '''3.Termination''' if scaling: #print scale,"SCALE" loglik=sum(np.log(scale)) else: loglik=np.log(sum(alpha[:,number_of_observations-1])) '''Backwards''' beta=np.ones(shape_alpha) gamma[:,number_of_observations-1] = normalize(alpha[:,number_of_observations-1] * beta[:,number_of_observations-1])[0] '''1.Initialization''' '''We have already set beta as a sequence of 1's.''' '''2.Induction''' '''Currently Non-vectorized''' for t in range(number_of_observations-2,-1,-1): b = beta[:,t+1] * obslik[:,t+1] for i in range(0,number_of_hidden_states): beta_sum=0 for j in range(0,number_of_hidden_states): beta_sum+=(beta[j][t+1]*transition_matrix[i][j]*emission_matrix[j][observation_vector[t+1]]) beta[i][t]=beta_sum if scaling: [beta[:,t], n] = normalize(beta[:,t]) scale[t] = n gamma[:,t] = normalize(alpha[:,t] * beta[:,t])[0] a=alpha[:,t].reshape(number_of_hidden_states,1) #print transition_matrix #print b #print obslik[:,t+1],"OBSLIK" #print np.dot(a, b.conj().T[np.newaxis]) #print np.mat(alpha[:,t])*np.mat(b.conj().T) xi_summed = xi_summed + normalize((transition_matrix * np.dot(a, b.conj().T[np.newaxis])))[0] '''Computing xi''' for t in range(number_of_observations-1): denom=0.0 for i in range(0,number_of_hidden_states): for j in range(0,number_of_hidden_states): denom+=alpha[i][t]*transition_matrix[i][j]*emission_matrix[j][observation_vector[t+1]]*beta[j][t+1] for i in range(0,number_of_hidden_states): for j in range(0,number_of_hidden_states): numer=alpha[i][t]*transition_matrix[i][j]*emission_matrix[j][observation_vector[t+1]]*beta[j][t+1] xi[t][i][j]=numer/denom '''Computing xi_summed for t in range(number_of_observations-1): for i in range(number_of_hidden_states): for j in range(number_of_hidden_states): xi_summed[i][j]+=xi[t][i][j] for t in xrange(number_of_observations): for i in xrange(number_of_hidden_states): gamma2[i][t] = sum(xi[t][i])''' '''CHECKING''' #print "Asserting" for t in range(number_of_observations): for i in range(0,number_of_hidden_states): p=0.0 for j in range(number_of_hidden_states): p+=xi[t][i][j] #print p/gamma[i][t] #assert(p==gamma[t][i]) return [alpha,beta,gamma,xi,xi_summed,loglik]