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

相關文章
相關標籤/搜索