概率计算问题/评估问题
前向算法
摘自李航老师《统计学习方法》
个人理解:基于已有的部分观测片段,计算转移之后的新增观测片段的结果。
容错点:首先对t步的alpha转移得到t+1步,然后对t+1转移后的结果逐点相乘发射概率。
后向算法
摘自李航老师《统计学习方法》
和前向算法的区别:假定当前时间步t,已有的观测片段是[t+2, T],则站在t步计算[t+1, T]观测片段的概。因此最后在t=0步时,需要补充t=1步的发射概率。
容错点:首先对beta连乘t+1步的发射概率,然后再计算t步到t+1步的转移。
完成的python代码
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]
def forward():
""" 前向算法
基于上一步的观测序列结果,计算转移到当前步的观测的结果。
"""
alpha = pi * emission_prob[:, obs_seq[0]] # 状态到当前观测的概率,shape=(状态数目,)
print(alpha)
for obs in obs_seq[1:]:
# (状态数目,) * (状态数目,状态数目) 。(状态数目,1) 。(状态数目,1)
# 前一个状态“转移到”后一个状态,transition_prob需要放在后面,不能放在前面!
alpha = np.dot(alpha, transition_prob) * emission_prob[:, obs]
print(alpha)
return np.sum(alpha)
def backward():
""" 后向算法
基于后一步的观测系列结果,计算如果需要从当前步向后转移,则相应观测序列片段的结果
"""
obs_len = len(obs_seq)
beta = np.ones_like(emission_prob[:, 0]) # (状态数目,1)
print(beta)
# 反向
for i in list(range(0, obs_len - 1))[::-1]:
obs = obs_seq[i + 1]
# beta是i+1时间步的状态下的观测序列结果
beta = np.dot(transition_prob, emission_prob[:, obs] * beta)
print(beta)
return np.sum(pi * emission_prob[:, obs_seq[0]] * beta)
def main():
res_forward = forward()
print(f"res_forward={res_forward}")
print("")
res_backward = backward()
print(f"res_backward={res_backward}")
pass
更多学习笔记可以关注我的微信公众号「kelly学挖掘」,欢迎交流。
-- over --