人工智能学习笔记-HMM-维特比算法

参考

github-通用维特比算法的Java实现
一文搞懂HMM(隐马尔可夫模型)

没啥新意,就是不熟悉算法,在网上找了个参考的例子,用Python实现了下算法,用于学习并理解此算法。

维特比算法

测试假设的问题

经典例子:一个东京的朋友每天根据天气{下雨,天晴}决定当天的活动{公园散步,购物,清理房间}中的一种,我每天只能在twitter上看到她发的推“啊,我前天公园散步、昨天购物、今天清理房间了!”,那么我可以根据她发的推特推断东京这三天的天气。

问题分解

假设已经有一个相当长时间的观察记录数据

日期12345678
天气下雨天晴天晴下雨下雨天晴天晴下雨
行为购物公园散步公园散步购物清理房间公园散步公园散步清理房间

这里有两条线,一条天气线一条隐藏线
对统计如下数据(统计数据都是假设):
行为类型:[‘walk’,’shop’,’clean’]
天气类型:[‘Rainy’,’Sunny’]
前一天晴,后一天天气概率:[晴:0.4,雨:0.6]
前一天雨,后一天天气概率:[晴:0.7,雨:0.3]
天晴,三种行为概率:[0.6,0.3,0.1]
下雨,三种行为概率:[0.1,0.4,0.5]

假如今天活动是购物,那么预测天气的计算步骤如下:
今天是晴的概率:

1. ([前一天计算结果][])*([前一天晴,后一天天气概率][晴])*([天晴,三种行为概率][购物])
2. ([前一天计算结果][])*([前一天雨,后一天天气概率][晴])*([天晴,三种行为概率][购物])

最终结果取1,2两步计算里的最大值

今天是雨的概率:

1. ([前一天计算结果][])*([前一天晴,后一天天气概率][雨])*([天雨,三种行为概率][购物])
2. ([前一天计算结果][])*([前一天雨,后一天天气概率][雨])*([天雨,三种行为概率][购物])

最终结果取1,2两步计算里的最大值

明天以此类推,一天天计算下去

代码

#coding=utf-8

import numpy as np
#维特比算法
class Viterbi(object):

    #求解HMM模型
    #int[] obs 每一天的行为
    #int[] work_t 行为的总类列表
    #int[] states 天气的总类列表
    #double[] start_p 初始概率(隐状态)
    #double[][] trans_p 转移概率(隐状态)
    #double[][] emit_p 发射概率 (隐状态表现为显状态的概率)
    #int[] return 最可能的序列
    def compute(self, obs, work_t, states, start_p, trans_p, emit_p):
        N = len(obs)
        obs_p = [work_t.index(obs[x]) for x in xrange(N)]
        T = len(states)
        states_p = [x for x in xrange(T)]
        #V:不同行为对应不同天气的概率
        V = np.zeros((N,T))
        path = np.zeros((T,N), dtype=np.int32)
        #初始化,第一个数据
        for y in xrange(T):
            #计算第一个行为在当前初始概率下,对应不同天气的概率
            V[0][y] = start_p[y]*emit_p[y][obs_p[0]]
            path[y][0] = states_p[y]

        for t in xrange(1,N):
            newpath = np.zeros((T,N),dtype=np.int32)
            for y in xrange(T):
                prob = -1
                state = 0
                for y0 in xrange(T):
                    nprob = V[t-1][y0]*trans_p[y0][y]*emit_p[y][obs_p[t]]
                    if nprob > prob:
                        prob = nprob
                        state = y0
                        #记录最大概率
                        V[t][y]=prob
                        #记录路径
                        for x in xrange(t):
                            newpath[y][x] = path[state][x]
                        newpath[y][t]=states_p[y]

            path = newpath
        prob = -1
        state = 0
        for y in xrange(T):
            if V[N-1][y] > prob:
                prob = V[N - 1][y]
                state = y
        return [states[x] for x in path[state]]


if __name__ == '__main__':
    model = Viterbi()
    result = model.compute(['walk','shop','clean','clean'],['walk','shop','clean'], ['Rainy','Sunny'], [0.5,0.5], [[0.7,0.3],[0.4,0.6]], [[0.1,0.4,0.5],[0.6,0.3,0.1]])
    for r in result:
        print r
    pass
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值