Python實(shí)現(xiàn)隱馬爾可夫模型的前向后向算法的示例代碼
本篇文章對(duì)隱馬爾可夫模型的前向和后向算法進(jìn)行了Python實(shí)現(xiàn),并且每種算法都給出了循環(huán)和遞歸兩種方式的實(shí)現(xiàn)。
前向算法Python實(shí)現(xiàn)
循環(huán)方式
import numpy as np def hmm_forward(Q, V, A, B, pi, T, O, p): """ :param Q: 狀態(tài)集合 :param V: 觀測(cè)集合 :param A: 狀態(tài)轉(zhuǎn)移概率矩陣 :param B: 觀測(cè)概率矩陣 :param pi: 初始概率分布 :param T: 觀測(cè)序列和狀態(tài)序列的長(zhǎng)度 :param O: 觀測(cè)序列 :param p: 存儲(chǔ)各個(gè)狀態(tài)的前向概率的列表,初始為空 """ for t in range(T): # 計(jì)算初值 if t == 0: for i in range(len(Q)): p.append(pi[i] * B[i, V[O[0]]]) # 初值計(jì)算完畢后,進(jìn)行下一時(shí)刻的遞推運(yùn)算 else: alpha_t_ = 0 alpha_t_t = [] for i in range(len(Q)): for j in range(len(Q)): alpha_t_ += p[j] * A[j, i] alpha_t_t.append(alpha_t_ * B[i, V[O[t]]]) alpha_t_ = 0 p = alpha_t_t return sum(p) # 《統(tǒng)計(jì)學(xué)習(xí)方法》書上例10.2 Q = [1, 2, 3] V = {'紅':0, '白':1} A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]) B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]) pi = [0.2, 0.4, 0.4] T = 3 O = ['紅', '白', '紅'] p = [] print(hmm_forward(Q, V, A, B, pi, T, O, p)) # 0.130218
遞歸方式
import numpy as np def hmm_forward_(Q, V, A, B, pi, T, O, p, T_final): """ :param T_final:遞歸的終止條件 """ if T == 0: for i in range(len(Q)): p.append(pi[i] * B[i, V[O[0]]]) else: alpha_t_ = 0 alpha_t_t = [] for i in range(len(Q)): for j in range(len(Q)): alpha_t_ += p[j] * A[j, i] alpha_t_t.append(alpha_t_ * B[i, V[O[T]]]) alpha_t_ = 0 p = alpha_t_t if T >= T_final: return sum(p) return hmm_forward_(Q, V, A, B, pi, T+1, O, p, T_final) Q = [1, 2, 3] V = {'紅':0, '白':1} A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]) B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]) pi = [0.2, 0.4, 0.4] T = 0 O = ['紅', '白', '紅'] p = [] T_final = 2 # T的長(zhǎng)度是3,T的取值是(0時(shí)刻, 1時(shí)刻, 2時(shí)刻) print(hmm_forward_(Q, V, A, B, pi, T, O, p, T_final))
后向算法Python實(shí)現(xiàn)
循環(huán)方式
import numpy as np def hmm_backward(Q, V, A, B, pi, T, O, beta_t, T_final): for t in range(T, -1, -1): if t == T_final: beta_t = beta_t else: beta_t_ = 0 beta_t_t = [] for i in range(len(Q)): for j in range(len(Q)): beta_t_ += A[i, j] * B[j, V[O[t + 1]]] * beta_t[j] beta_t_t.append(beta_t_) beta_t_ = 0 beta_t = beta_t_t if t == 0: p=[] for i in range(len(Q)): p.append(pi[i] * B[i, V[O[0]]] * beta_t[i]) beta_t = p return sum(beta_t) # 《統(tǒng)計(jì)學(xué)習(xí)方法》課后題10.1 Q = [1, 2, 3] V = {'紅':0, '白':1} A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]) B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]) pi = [0.2, 0.4, 0.4] T = 3 O = ['紅', '白', '紅', '白'] beta_t = [1, 1, 1] T_final = 3 print(hmm_backward_(Q, V, A, B, pi, T, O, beta_t, T_final)) # 0.06009
遞歸方式
import numpy as np def hmm_backward(Q, V, A, B, pi, T, O, beta_t, T_final): if T == T_final: beta_t = beta_t else: beta_t_ = 0 beta_t_t = [] for i in range(len(Q)): for j in range(len(Q)): beta_t_ += A[i, j] * B[j, V[O[T+1]]] * beta_t[j] beta_t_t.append(beta_t_) beta_t_ = 0 beta_t = beta_t_t if T == 0: p=[] for i in range(len(Q)): p.append(pi[i] * B[i, V[O[0]]] * beta_t[i]) beta_t = p return sum(beta_t) return hmm_backward(Q, V, A, B, pi, T-1, O, beta_t, T_final) jpgQ = [1, 2, 3] V = {'紅':0, '白':1} A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]) B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]) pi = [0.2, 0.4, 0.4] T = 3 O = ['紅', '白', '紅', '白'] beta_t = [1, 1, 1] T_final = 3 print(hmm_backward_(Q, V, A, B, pi, T, O, beta_t, T_final)) # 0.06009
這里我有個(gè)問(wèn)題不理解,這道題的正確答案應(yīng)該是0.061328,我計(jì)算出的答案和實(shí)際有一點(diǎn)偏差,我跟蹤了代碼的計(jì)算過(guò)程,發(fā)現(xiàn)在第一次循環(huán)完成后,計(jì)算結(jié)果是正確的,第二次循環(huán)后的結(jié)果就出現(xiàn)了偏差,我懷疑是小數(shù)部分的精度造成,希望有人能給出一個(gè)更好的解答,如果是代碼的問(wèn)題也歡迎指正。
以上所述是小編給大家介紹的Python實(shí)現(xiàn)隱馬爾可夫模型的前向后向算法,希望對(duì)大家有所幫助!
相關(guān)文章
Python實(shí)現(xiàn)爬取房源信息的示例詳解
站在一個(gè)租房人的立場(chǎng),租房平臺(tái)實(shí)在太多了,并且各平臺(tái)篩選和排序邏輯都不太一致。這篇文章將教教大家如何利用Python語(yǔ)言實(shí)現(xiàn)爬取房源信息,需要的可以參考一下2022-09-09解決python中os.listdir()函數(shù)讀取文件夾下文件的亂序和排序問(wèn)題
今天小編就為大家分享一篇解決python中os.listdir()函數(shù)讀取文件夾下文件的亂序和排序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10Python實(shí)現(xiàn)螺旋矩陣的填充算法示例
這篇文章主要介紹了Python實(shí)現(xiàn)螺旋矩陣的填充算法,結(jié)合實(shí)例形式分析了Python實(shí)現(xiàn)螺旋矩陣的相關(guān)循環(huán)、遍歷、判斷、運(yùn)算等操作技巧,需要的朋友可以參考下2017-12-12django之session與分頁(yè)(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇django之session與分頁(yè)(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11conda查看、創(chuàng)建、刪除、激活與退出環(huán)境命令詳解
在不同的項(xiàng)目中經(jīng)常需要conda來(lái)配置環(huán)境,這樣能夠?qū)崿F(xiàn)不同版本的python和庫(kù)的隨意切換,并且減少了很多不必要的麻煩,下面這篇文章主要給大家介紹了關(guān)于conda查看、創(chuàng)建、刪除、激活與退出環(huán)境命令的相關(guān)資料,需要的朋友可以參考下2023-05-05解決PyCharm不在run輸出運(yùn)行結(jié)果而不是再Console里輸出的問(wèn)題
這篇文章主要介紹了解決PyCharm不在run輸出運(yùn)行結(jié)果而不是再Console里輸出的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Python中l(wèi)ogging日志記錄到文件及自動(dòng)分割的操作代碼
這篇文章主要介紹了Python中l(wèi)ogging日志記錄到文件及自動(dòng)分割,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08pandas 轉(zhuǎn)換成行列表進(jìn)行讀取與Nan處理的方法
今天小編就為大家分享一篇pandas 轉(zhuǎn)換成行列表進(jìn)行讀取與Nan處理的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10