hmm的解码问题:给定训练好的hmm模型,预测给定观测序列对应的最佳隐状态序列。
两种方法:(1)近似算法(2)viterbi维特比算法
近似算法
摘自李航《统计学习方法》
缺点:无法保证所求的状态序列一定有意义和最佳,只能保证当前时刻t选择是状态是最佳的。
viterbi维特比算法
摘自李航《统计学习方法》
核心思想:动态规划机制,从前向后,在每个时间步t仅选择当前状态下的最佳路径,剔除非最佳路径。
viterbi的实现代码:
import time
import numpy as np
# 隐变量:健康、生病
# 观测序列:头晕、发冷、正常
transition_prob = np.array([[0.7, 0.3],
[0.4, 0.6]
])
emission_prob = np.array([[0.1, 0.3, 0.6],
[0.5, 0.4, 0.1]
])
pi = np.array([0.6, 0.4])
# 观测序列
obs_seq = [0, 1, 0, 2, 2, 2, 2, 2]
# 隐状态的中文名称
state_names = ["健康", "发烧"]
# 观测的中文名称
obs_names = ["头晕", "发冷", "正常"]
def viterbi():
""" 给定观测序列,计算最有可能的隐状态序列 """
n_status = transition_prob.shape[0]
n_obs = len(obs_seq)
score = np.array([[-float("inf") for _ in range(n_status)] for _ in range(n_obs)])
path = np.array([[-1 for _ in range(n_status)] for _ in range(n_obs)])
for i, obs in enumerate(obs_seq):
if i == 0:
for j in range(n_status):
score[i][j] = pi[j] * emission_prob[j][obs]
else:
# 当前时间步是j2,上一个时间步是j1
for j2 in range(n_status):
best, best_t = -float("inf"), -1
for j1 in range(n_status):
tmp = score[i - 1][j1] * transition_prob[j1][j2]
if tmp > best:
best = tmp
best_t = j1
score[i][j2] = best
path[i][j2] = best_t # 上一步的最佳状态序号
best_t = np.argmax(score[-1])
best_t = path[-1][best_t]
decode = [best_t]
for i in range(n_obs - 1, 0, -1):
decode.append(path[i][decode[-1]])
decode = decode[:: -1]
print(decode)
print([state_names[i] for i in decode])
pass
def main():
viterbi()
pass
更多学习笔记可以关注我的微信公众号「kelly学技术」,欢迎交流。
-- over --