马尔科夫系列——四、预测问题Viterbi算法、案例和代码实现

        转载自——隐马尔可夫模型 - HMM的三个问题 - 预测问题 - Viterbi算法

原文中的有些过程不是很详细,我在这里进行了修改!并且添加了代码实现部分

目录

近似算法

Viterbi算法

HMM案例-Viterbi

代码实现


问题: 在观测序列已知的情况下,状态序列未知。想找到一个最有可能产生当前观测序列的状态序列。

可以用下面两种办法来求解这个问题:
1、近似算法
2、Viterbi算法

近似算法

直接在每个时刻t时候最优可能的状态作为最终的预测状态,使用下列公式计算概率值:

遍历时间t。

优点是计算简单;而缺点就很明显了,没有考虑时序关系,不能保证预测的状态序列整体上是最优可能的状态序列,预测的状态序列可能有实际不发生的部分。

Viterbi算法

它的核心思想和运筹学中的使用动态规划的思路求解最短路径问题是一样的。

其中it表示最短路径,Ot表示观测符号,lamda表示模型参数,根据上式可以得出变量sigma的递推公式:

下面看个例子来深入理解这个公式。

HMM案例-Viterbi

在给定参数π、A、B的时候,得到观测序列为“白黑白白黑”,求出最优的隐藏状态序列。

 回溯最优路径:

最优状态序列为:23223

代码实现

这里把最原始的viterbi算法做一个简单的实现——代码来自github——viterbi

###########################################################################################################
# Viterbi Algorithm for HMM
# dp, time complexity O(mn^2), m is the length of sequence of observation, n is the number of hidden states
##########################################################################################################


# five elements for HMM
states = ('1号盒子', '2号盒子','3号盒子')

observations = ('白球', '黑球', '白球','白球','黑球')

start_probability = {'1号盒子': 0.2, '2号盒子': 0.5,'3号盒子':0.3}

transition_probability = {
    '1号盒子': {'1号盒子': 0.5, '2号盒子': 0.4,'3号盒子':0.1},
    '2号盒子': {'1号盒子': 0.2, '2号盒子': 0.2,'3号盒子':0.6},
    '3号盒子': {'1号盒子': 0.2, '2号盒子': 0.5,'3号盒子':0.3}
}

emission_probability = {
    '1号盒子': {'白球': 0.4, '黑球': 0.6},
    '2号盒子': {'白球': 0.8, '黑球': 0.2},
    '3号盒子': {'白球': 0.5, '黑球': 0.5}
}


def Viterbit(obs, states, s_pro, t_pro, e_pro):
    path = {s: [] for s in states}  # init path: path[s] represents the path ends with s
    curr_pro = {}
    for s in states:
        curr_pro[s] = s_pro[s] * e_pro[s][obs[0]]
    for i in range(1, len(obs)):
        last_pro = curr_pro
        curr_pro = {}
        for curr_state in states:
            max_pro, last_sta = max(
                ((last_pro[last_state] * t_pro[last_state][curr_state] * e_pro[curr_state][obs[i]], last_state)
                 for last_state in states))
            curr_pro[curr_state] = max_pro
            path[curr_state].append(last_sta)

    # find the final largest probability
    max_pro = -1
    max_path = None
    for s in states:
        path[s].append(s)
        if curr_pro[s] > max_pro:
            max_path = path[s]
            max_pro = curr_pro[s]
    # print '%s: %s'%(curr_pro[s], path[s]) # different path and their probability
    return max_path


if __name__ == '__main__':
    obs = ['白球', '黑球', '白球','白球','黑球']
    print(Viterbit(obs, states, start_probability, transition_probability, emission_probability))

代码原理很好理解,主要是要把不同时刻的最优路径的当前状态和前一时刻的状态都保存下来,然后再回溯全局最优路径。代码不熟悉的话可以多调试一下!

 

 

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值