日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

viterbi-algorithm 维特比算法的例子解析

發布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 viterbi-algorithm 维特比算法的例子解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

維特比算法的目的:

尋找最可能的隱藏狀態序列(Finding most probable sequence of hidden states)


關于原理的講解可以參考下面兩篇文章,講的比較清楚
小白給小白詳解維特比算法1.
小白給小白詳解維特比算法2.


本文通過分析維特比算法的例子,來學習該算法

  • 定義HMM的五個重要元素,
  • # 隱藏序列 S states = ("Rainy", "Sunny")# 觀測序列 K observations = ('walk', 'shop', 'clean')# 初始概率 π start_probability = {'Rainy': 0.6, "Sunny": 0.4}# 轉移概率 A transition_probability = {'Rainy': {"Rainy": 0.7, "Sunny": 0.3},"Sunny": {"Rainy": 0.4, "Sunny": 0.6} }# 發射概率 B emission_probability = {"Rainy": {"walk": 0.1, "shop": 0.4, "clean": 0.5},"Sunny": {"walk": 0.6, "shop": 0.3, "clean": 0.1}, }

    2.定義初始化狀態

    # 路徑概率表 V[時間][隱狀態] = 概率V = [{}]# 一個中間變量,代表當前狀態是哪個隱狀態path = {}# 初始化初始狀態 t=0for y in states:V[0][y] = start_p[y] * emit_p[y][obs[0]]path[y] = [y]

    V[時間][天氣] = 概率
    觀測序列(observations)得到的結果 觀測對象第一天是散步
    計算第一天的天氣:
    V[第一天][天晴] = 初始概率[天晴] * 發射概率[散步] = 0.4 * 0.6 = 0.24
    V[第一天][下雨] = 初始概率[下雨] * 發射概率[散步] = 0.6 * 0.1 = 0.06
    計算結果可見,第一天天晴的概率比較大。
    此時初始的路徑 path = {}


  • 后面天氣的情況都是根據前一天天氣概率×轉移概率×發射概率得到
  • def vierbi(obs, states, start_p, trans_p, emit_p):""":param obs: 觀察序列 K:param states: 隱藏狀態 S:param start_p: 初始概率 π:param trans_p: 轉移概率 A:param emit_p: 發射概率 B:return:"""# 路徑概率表 V[時間][隱狀態] = 概率V = [{}]# 一個中間變量,代表當前狀態是哪個隱狀態path = {}# 初始化初始狀態 t=0for 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 = newpathprint_dptable(V)(prob, state) = max([(V[len(obs) - 1][y], y) for y in states])return prob, path[state]

    第二天: 由觀測序列可得 observations[1] = ‘購物’
    ① 首先看計算第二天下雨的概率

    • V[第二天][下雨] = V[第一天][下雨] * 轉移概率[下雨][下雨] * 發射概率[下雨][購物] = 0.06 * 0.7 * 0.4 = 0.0168
    • V[第二天][下雨] = V[第一天][天晴] * 轉移概率[天晴][下雨] * 發射概率[下雨][購物] = 0.24 * 0.4 * 0.4 = 0.0384
      同樣在這里取最大概率
      V[第二天][下雨] = 0.0384
      得到的新路徑 newpath[下雨] = [晴天,下雨]

    ②然后計算第二天天晴的概率

    • V[第二天][天晴] = V[第一天][下雨] * 轉移概率[下雨][天晴] * 發射概率[天晴][購物] = 0.06 * 0.3 * 0.3 = 0.0054
    • V[第二天][天晴] = V[第一天][天晴] * 轉移概率[天晴][天晴] * 發射概率[天晴][購物] = 0.24 * 0.6 * 0.3 = 0.0432
      V[第二天][天晴] = 0.0432
      得到的新路徑 newpath[晴天] = [晴天,晴天]

    第二天計算完成之后得到前兩天的路徑
    paht={雨天:[晴天,下雨],晴天:[晴天,晴天]}

    以同樣的方式得到第三天的結果
    observations[1] = 打掃

    • V[第三天][下雨] = V[第二天][下雨] * 轉移概率[下雨][下雨] * 發射概率[下雨][打掃] = 0.0384 * 0.7 * 0.5 = 0.01344
    • V[第三天][下雨] = V[第二天][天晴] * 轉移概率[天晴][下雨] * 發射概率[下雨][打掃] = 0.0432 * 0.4 * 0.5 = 0.00864
      V[第三天][下雨] = 0.01344
      newpath[下雨] = [晴天,下雨,下雨]
    • V[第三天][天晴] = V[第二天][下雨] * 轉移概率[下雨][天晴] * 發射概率[天晴][打掃] = 0.0384* 0.3 * 0.1 = 0.001152
    • V[第三天][天晴] = V[第二天][天晴] * 轉移概率[天晴][天晴] * 發射概率[天晴][打掃] = 0.0432 * 0.6 * 0.1 = 0.002592
      V[第三天][天晴] = 0.002592
      newpath[晴天] = [晴天,晴天,晴天]
      把得到的newpath賦值給path

    最后通過找出V[第三天]中天氣最大的那個概率得到天氣的情況
    因此第三天的天氣為V[第三天][下雨] = 0.01344
    由此可反推得到路徑path[下雨] = [晴天,下雨,下雨]

    圖形表示如下,第二天之后的天氣概率計算后取最大值,根據第三天天氣的最大概率再反推天氣的路徑

    上面就是維特比算法實現的詳解,下面是完整代碼。

    # -*- coding:utf-8 -*- # @Time :2019/5/27 15:30 # @author :ding # @filename :vertibi.py""" 維特比算法的實現 HMM 五個重要元素 S 隱藏序列的集合 K 輸出狀態或觀測狀態的集合 π對應隱藏狀態的的初始概率 A 隱藏狀態的轉移概率 是一個N*M的概率矩陣 B 影廠狀態到觀測狀態的混淆矩陣,是一個N*M的發射概率的矩陣 """# 隱藏序列 S states = ("Rainy", "Sunny")# 觀測序列 K observations = ('walk', 'shop', 'clean')# 初始概率 π start_probability = {'Rainy': 0.6, "Sunny": 0.4}# 轉移概率 A transition_probability = {'Rainy': {"Rainy": 0.7, "Sunny": 0.3},"Sunny": {"Rainy": 0.4, "Sunny": 0.6} }# 發射概率 B 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, end="")print()for y in V[0].keys():print("%.5s: " % y, end=" ")for t in range(len(V)):print("%.7s" % V[t][y], end=" ")print()def vierbi(obs, states, start_p, trans_p, emit_p):""":param obs: 觀察序列 K:param states: 隱藏狀態 S:param start_p: 初始概率 π:param trans_p: 轉移概率 A:param emit_p: 發射概率 B:return:"""# 路徑概率表 V[時間][隱狀態] = 概率V = [{}]# 一個中間變量,代表當前狀態是哪個隱狀態path = {}# 初始化初始狀態 t=0for 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 = newpathprint_dptable(V)(prob, state) = max([(V[len(obs) - 1][y], y) for y in states])return prob, path[state]def test():return vierbi(observations,states,start_probability,transition_probability,emission_probability)print(test())

    打印結果如下


    維特比算法在NLP方面有很多的應用

    • 詞性標注:給定一個詞的序列,找出最可能的詞性序列
    • 分詞:給定一個字的序列,找出最可能的標簽序列,可利用BMES這些標簽來分詞B(開頭)M(中間詞)E(結尾)S(單個詞)
    • 明明實體識別:給定一個詞的序列,找出最可能的標簽序列

    本文講的可能不是很清楚,有不對的地方,還請不吝指教。

    總結

    以上是生活随笔為你收集整理的viterbi-algorithm 维特比算法的例子解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。