-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path4-viterbi.py
executable file
·39 lines (36 loc) · 1.48 KB
/
4-viterbi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env python3
"""Function that calculates the most likely
sequence of hidden states for a hidden markov model"""
import numpy as np
def viterbi(Observation, Emission, Transition, Initial):
"""Function that calculates the most likely
sequence of hidden states for a hidden markov model"""
if type(Observation) is not np.ndarray or len(Observation.shape) != 1:
return (None, None)
if type(Emission) is not np.ndarray or len(Emission.shape) != 2:
return (None, None)
if type(Transition) is not np.ndarray or len(Transition.shape) != 2:
return (None, None)
if type(Initial) is not np.ndarray or len(Initial.shape) != 2:
return (None, None)
T = Observation.shape[0]
N, M = Emission.shape
if Transition.shape[0] != Transition.shape[1] or Transition.shape[0] != N:
return (None, None)
if N != Initial.shape[0] or Initial.shape[1] != 1:
return (None, None)
D = np.zeros([N, T])
path = np.zeros(T)
phi = np.zeros([N, T])
D[:, 0] = Initial.T * Emission[:, Observation[0]]
for i in range(1, T):
for j in range(N):
D[j, i] = np.max(D[:, i - 1] * Transition[:, j]) *\
Emission[j, Observation[i]]
phi[j, i] = np.argmax(D[:, i-1] * Transition[:, j])
path[T - 1] = np.argmax(D[:, T - 1])
for i in range(T-2, -1, -1):
path[i] = phi[int(path[i + 1]), i + 1]
P = np.max(D[:, T - 1:], axis=0)[0]
path = [int(i) for i in path]
return (path, P)