fork download
  1. import numpy as np
  2.  
  3. class HiddenMarkovModel:
  4. def __init__(self, states, observations, start_prob, trans_prob, emit_prob):
  5. self.states = states
  6. self.observations = observations
  7. self.start_prob = start_prob
  8. self.trans_prob = trans_prob
  9. self.emit_prob = emit_prob
  10.  
  11. def viterbi(self, obs_seq):
  12. n_states = len(self.states)
  13. T = len(obs_seq)
  14.  
  15. dp = np.zeros((n_states, T))
  16. path = np.zeros((n_states, T), dtype=int)
  17.  
  18. for s in range(n_states):
  19. dp[s, 0] = self.start_prob[s] * self.emit_prob[s][self.observations.index(obs_seq[0])]
  20. path[s, 0] = 0
  21.  
  22. for t in range(1, T):
  23. for s in range(n_states):
  24. prob_transition = dp[:, t-1] * self.trans_prob[:, s]
  25. best_prev_state = prob_transition.argmax()
  26. dp[s, t] = prob_transition[best_prev_state] * self.emit_prob[s][self.observations.index(obs_seq[t])]
  27. path[s, t] = best_prev_state
  28.  
  29. best_last_state = dp[:, T-1].argmax()
  30. best_path = [best_last_state]
  31.  
  32. for t in range(T-1, 0, -1):
  33. best_last_state = path[best_last_state, t]
  34. best_path.insert(0, best_last_state)
  35.  
  36. best_state_sequence = [self.states[state] for state in best_path]
  37. return best_state_sequence
  38.  
  39.  
  40. if __name__ == "__main__":
  41. states = ['S1', 'S2']
  42. observations = ['obs1', 'obs2', 'obs3']
  43.  
  44. start_prob = np.array([0.6, 0.4])
  45. trans_prob = np.array([[0.7, 0.3],
  46. [0.4, 0.6]])
  47. emit_prob = np.array([[0.5, 0.4, 0.1],
  48. [0.1, 0.3, 0.6]])
  49.  
  50. obs_seq = ['obs3', 'obs1', 'obs3']
  51.  
  52. hmm = HiddenMarkovModel(states, observations, start_prob, trans_prob, emit_prob)
  53. best_sequence = hmm.viterbi(obs_seq)
  54.  
  55. print("Most likely state sequence:", best_sequence)
  56.  
  57. # your code goes here
Success #stdin #stdout 0.79s 41548KB
stdin
Standard input is empty
stdout
Most likely state sequence: ['S2', 'S1', 'S2']