Python Implementation of Viterbi Algorithm

前端 未结 6 1580
别跟我提以往
别跟我提以往 2020-12-12 20:43

I\'m doing a Python project in which I\'d like to use the Viterbi Algorithm. Does anyone know of a complete Python implementation of the Viterbi algorithm? The correctness

6条回答
  •  旧时难觅i
    2020-12-12 21:26

    I have just corrected the pseudo implementation of Viterbi in Wikipedia. From the initial (incorrect) version, it took me a while to figure out where I was going wrong but I finally managed it, thanks partly to Kevin Murphy's implementation of the viterbi_path.m in the MatLab HMM toolbox.

    In the context of an HMM object with variables as shown:

    hmm = HMM()
    hmm.priors = np.array([0.5, 0.5]) # pi = prior probs
    hmm.transition = np.array([[0.75, 0.25], # A = transition probs. / 2 states
                               [0.32, 0.68]])
    hmm.emission = np.array([[0.8, 0.1, 0.1], # B = emission (observation) probs. / 3 obs modes
                             [0.1, 0.2, 0.7]])
    

    The Python function to run Viterbi (best-path) algorithm is below:

    def viterbi (self,observations):
        """Return the best path, given an HMM model and a sequence of observations"""
        # A - initialise stuff
        nSamples = len(observations[0])
        nStates = self.transition.shape[0] # number of states
        c = np.zeros(nSamples) #scale factors (necessary to prevent underflow)
        viterbi = np.zeros((nStates,nSamples)) # initialise viterbi table
        psi = np.zeros((nStates,nSamples)) # initialise the best path table
        best_path = np.zeros(nSamples); # this will be your output
    
        # B- appoint initial values for viterbi and best path (bp) tables - Eq (32a-32b)
        viterbi[:,0] = self.priors.T * self.emission[:,observations(0)]
        c[0] = 1.0/np.sum(viterbi[:,0])
        viterbi[:,0] = c[0] * viterbi[:,0] # apply the scaling factor
        psi[0] = 0;
    
        # C- Do the iterations for viterbi and psi for time>0 until T
        for t in range(1,nSamples): # loop through time
            for s in range (0,nStates): # loop through the states @(t-1)
                trans_p = viterbi[:,t-1] * self.transition[:,s]
                psi[s,t], viterbi[s,t] = max(enumerate(trans_p), key=operator.itemgetter(1))
                viterbi[s,t] = viterbi[s,t]*self.emission[s,observations(t)]
    
            c[t] = 1.0/np.sum(viterbi[:,t]) # scaling factor
            viterbi[:,t] = c[t] * viterbi[:,t]
    
        # D - Back-tracking
        best_path[nSamples-1] =  viterbi[:,nSamples-1].argmax() # last state
        for t in range(nSamples-1,0,-1): # states of (last-1)th to 0th time step
            best_path[t-1] = psi[best_path[t],t]
    
        return best_path
    

提交回复
热议问题