HMM——求隐藏序列,维特比算法求解

情景假设

一个东京的朋友天天根据天气{下雨,天晴}决定当天的活动{公园散步,购物,清理房间}中的一种,我天天只能在twitter上看到她发的推“啊,我前天公园散步、昨天购物、今天清理房间了!”,那么我能够根据她发的推特推断东京这三天的天气。在这个例子里,显状态是活动即购物,散步以及整理,隐状态是天气。咱们要求出活动对应得天气状况。html

条件描述

隐含状态 states = ('Rainy', 'Sunny')算法

显性状态 observations = ('walk', 'shop', 'clean')app

初试状态几率(隐含态) start_probability = {'Rainy': 0.6, 'Sunny': 0.4}code

转换状态 transition_probability = { 'Rainy' : {'Rainy': 0.7, 'Sunny': 0.3}, 'Sunny' : {'Rainy': 0.4, 'Sunny': 0.6}, }htm

发射状态(对应隐含状态为显性状态几率) emission_probability = { 'Rainy' : {'walk': 0.1, 'shop': 0.4, 'clean': 0.5}, 'Sunny' : {'walk': 0.6, 'shop': 0.3, 'clean': 0.1}, }get

states = ('Rainy', 'Sunny')

observations = ('walk', 'shop', 'clean')

start_probability = {'Rainy': 0.6, 'Sunny': 0.4}

transition_probability = {
    'Rainy': {'Rainy': 0.7, 'Sunny': 0.3},
    'Sunny': {'Rainy': 0.4, 'Sunny': 0.6},
}

emission_probability = {
    'Rainy': {'walk': 0.1, 'shop': 0.4, 'clean': 0.5},
    'Sunny': {'walk': 0.6, 'shop': 0.3, 'clean': 0.1},
}


# 打印路径几率表
def print_dptable(V):
    print "    ",
    for i in range(len(V)): print "%7d" % i,
    print

    for y in V[0].keys():
        print "%.5s: " % y,
        for t in range(len(V)):
            print "%.7s" % ("%f" % V[t][y]),
        print


def viterbi(obs, states, start_p, trans_p, emit_p):
    """
   
       :param obs:观测序列
       :param states:隐状态
       :param start_p:初始几率(隐状态)
       :param trans_p:转移几率(隐状态)
       :param emit_p: 发射几率 (隐状态表现为显状态的几率)
       :return:
       """
    # 路径几率表 V[时间][隐状态] = 几率
    V = [{}]
    # 一个中间变量,表明当前状态是哪一个隐状态
    path = {}

    # 初始化初始状态 (t == 0)
    for y in states:
        V[0][y] = start_p[y] * emit_p[y][obs[0]]
        path[y] = [y]

    # 对 t > 0 跑一遍维特比算法
    for t in range(1, len(obs)):
        V.append({})
        newpath = {}

        for y in states:
            # 几率 隐状态 =    前状态是y0的几率 * y0转移到y的几率 * y表现为当前状态的几率
            (prob, state) = max([(V[t - 1][y0] * trans_p[y0][y] * emit_p[y][obs[t]], y0) for y0 in states])
            # 记录最大几率
            V[t][y] = prob
            # 记录路径
            newpath[y] = path[state] + [y]

        # 不须要保留旧路径
        path = newpath
        print path
    #print_dptable(V)
    (prob, state) = max([(V[len(obs) - 1][y], y) for y in states])
    return (prob, path[state])


def example():
    return viterbi(observations,
                   states,
                   start_probability,
                   transition_probability,
                   emission_probability)


print example()

须要注意博客

  1. 隐性状态的转移必须知足马尔可夫性。(状态转移的马尔可夫性:一个状态只与前一个状态有关)it

  2. 隐性状态必须可以大概被估计。在知足条件的状况下,肯定问题中的隐性状态是什么,隐性状态的表现可能又有哪些.HMM适用于的问题在于,真正的状态(隐态)难以被估计,而状态与状态之间又存在联系。io

本文转自如下博主

原博主博客table

相关文章
相关标签/搜索