Skip to content

Commit 4a8534f

Browse files
committed
Viterbi Algorithm for HMM, https://tinyurl.com/y8xt2lcf
1 parent dc9b85d commit 4a8534f

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

python/Viterbi.py

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# -*- coding: utf-8 -*-
2+
# @Author: WuLC
3+
# @Date: 2017-04-02 08:52:24
4+
# @Last Modified by: WuLC
5+
# @Last Modified time: 2017-04-02 09:50:31
6+
7+
###########################################################################################################
8+
# Viterbi Algorithm for HMM
9+
# dynamic programming, time complexity O(mn^2), m is the length of sequence of observation, n is the number of hidden states
10+
# more details can be obtained from: https://tinyurl.com/y8xt2lcf
11+
##########################################################################################################
12+
13+
14+
# five elements for HMM
15+
states = ('Healthy', 'Fever')
16+
17+
observations = ('normal', 'cold', 'dizzy')
18+
19+
start_probability = {'Healthy': 0.6, 'Fever': 0.4}
20+
21+
transition_probability = {
22+
'Healthy' : {'Healthy': 0.7, 'Fever': 0.3},
23+
'Fever' : {'Healthy': 0.4, 'Fever': 0.6},
24+
}
25+
26+
emission_probability = {
27+
'Healthy' : {'normal': 0.5, 'cold': 0.4, 'dizzy': 0.1},
28+
'Fever' : {'normal': 0.1, 'cold': 0.3, 'dizzy': 0.6},
29+
}
30+
31+
32+
33+
def Viterbit(obs, states, s_pro, t_pro, e_pro):
34+
path = { s:[] for s in states} # init path: path[s] represents the path ends with s
35+
curr_pro = {}
36+
for s in states:
37+
curr_pro[s] = s_pro[s]*e_pro[s][obs[0]]
38+
for i in xrange(1, len(obs)):
39+
last_pro = curr_pro
40+
curr_pro = {}
41+
for curr_state in states:
42+
max_pro, last_sta = max(((last_pro[last_state]*t_pro[last_state][curr_state]*e_pro[curr_state][obs[i]], last_state)
43+
for last_state in states))
44+
curr_pro[curr_state] = max_pro
45+
path[curr_state].append(last_sta)
46+
47+
# find the final largest probability
48+
max_pro = -1
49+
max_path = None
50+
for s in states:
51+
path[s].append(s)
52+
if curr_pro[s] > max_pro:
53+
max_path = path[s]
54+
max_pro = curr_pro[s]
55+
# print '%s: %s'%(curr_pro[s], path[s]) # different path and their probability
56+
return max_path
57+
58+
59+
if __name__ == '__main__':
60+
obs = ['normal', 'cold', 'dizzy']
61+
print Viterbit(obs, states, start_probability, transition_probability, emission_probability)

0 commit comments

Comments
 (0)