wikipedia上HMM的例子代码

# hidden states
states = ('Rainy', 'Sunny')
# observations:
observations = ('walk', 'shop', 'clean')
start_probability = {'Rainy':0.6, 'Sunny':0.4}
transition_probability = {
        'Rainy':{'Rainy':0.7, 'Sunny':0.3},
        'Sunny':{'Rainy':0.4, 'Sunny':0.6},
        }
emission_probability = {
        'Rainy':{'walk':0.1, 'shop':0.4, 'clean':0.5},
        'Sunny':{'walk':0.6, 'shop':0.3, 'clean':0.1},
        }
'''obs is the sequence of observations, e.g. ['walk', 'shop', 'clean']; states is the set of hidden states; start_p is the start probability; trans_p are the transition probabilities; and emit_p are the emission probabilities.
'''
# Helps visualize the steps of Viterbi.
def print_dptable(V):
    print "      ",
    for i in range(len(V)):
        print "%7s" % ("%d" % i),
    print

    for y in V[0].keys():
        print "%.5s: " % y,
        for t in range(len(V)):
            print "%.7s" % ("%f" % V[t][y]),
        print

def viterbi(obs, states, start_p, trans_p, emit_p):
    V = [{}] # a list whose elements are dictionary
    path = {}
    # Initialize base cases (t==0)
    for y in states:
        V[0][y] = start_p[y]*emit_p[y][obs[0]]
        path[y] = [y]

    # Run Viterbi for t>0 from 1 to len(obs)
    for t in range(1,len(obs)):
        V.append({})
        newpath = {}

        for y in states:
            (prob, state) = max([(V[t-1][y0]*trans_p[y0][y]*emit_p[y][obs[t]],y0) for y0 in states])
            V[t][y] = prob
            newpath[y] = path[state] + [y]

        # Dont need to remember the old paths
        path = newpath

    print_dptable(V)
    (prob, state) = max([(V[len(obs)-1][y],y) for y in states])
    return (prob, path[state])

def forward_viterbi(obs, states, start_p, trans_p, emit_p):
    T = {}
    for state in states:
        ## initial T  the total probability for a state is just the start probability of that state; and the Viterbi path to a start state is the singleton path consisting only of that state; the probability of the Viterbi path is the same as the start probability    
        T[state] = (start_p[state], [state], start_p[state])
    for output in obs:#  main loop
        U = {}
        for next_state in states: # compute next_state value one by one
            total = 0
            argmax = None
            valmax = 0
            for source_state in states:# compute from all the last state
                (prob, v_path, v_prob) = T[source_state]
                p = emit_p[source_state][output]*trans_p[source_state][next_state]
                prob *=p
                v_prob *=p #viterbi path probability
                total += prob #add all the probability to this state
                if v_prob > valmax: # update viterbi path
                    argmax = v_path + [next_state]
                    valmax = v_prob
            U[next_state] = (total, argmax, valmax)# U for storage the temp data
        T = U
    ##apply sum/max to the final states:
    total = 0
    argmax = None
    valmax = 0
    for state in states:
        (prob, v_path, v_prob) = T[state]
        total += prob
        if v_prob > valmax:
            argmax = v_path
            valmax = v_prob
    return (total, argmax, valmax)


def example1():
    return forward_viterbi(observations,states,
            start_probability, transition_probability,
            emission_probability)

def example():
    return viterbi(observations,states,
            start_probability, transition_probability,
            emission_probability)
print example()

def example

本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。

posted @ 2011-04-05 21:24  莫忆往西  阅读(217)  评论(0编辑  收藏  举报