viterbi演算法其實就是多步驟每步多選擇模型的最優選擇問題,其在每一步的所有選擇都儲存了前續所有步驟到當前步驟當前選擇的最小總代價(或者最大價值)以及當前代價的情況下前繼步驟的選擇。依次計算完所有步驟後,通過回溯的方法找到最優選擇路徑。符合這個模型的都可以用viterbi演算法解決。
隱含的身體狀態 =
可觀察的感覺狀態 =
月兒預判的阿驢身體狀態的概率分布 =這就是初始狀態序列。
月兒認為的阿驢身體健康狀態的轉換概率分布 =
這樣就可以列出相應的狀態轉移矩陣。
月兒認為的在相應健康狀況條件下,阿驢的感覺的概率分布 = 這樣就可以列出相應的觀測矩陣。
下面就是解決問題了。阿驢連續三天的身體感覺依次是: 正常、冷、頭暈 。
已知如上,求:阿驢這三天的身體健康狀態變化的過程是怎麼樣的?即已知觀測序列和hmm模型的情況下,求狀態序列。
最後一天的狀態概率分布即為最優路徑的概率,即p(最優)=0.01512,這樣我們可以得到最優路徑的終點,是發燒。這樣,我們的狀態序列逆推出來了。即為:健康,健康,發燒。
# 狀態的樣本空間
states = ('健康', '發熱')
# 觀測的樣本空間
observations = ('正常', '發冷', '發暈')
# 起始個狀態概率
start_probability =
# 狀態轉移概率
transition_probability = ,
'發熱': ,
}# 狀態->觀測的發散概率
emission_probability = ,
'發熱': ,
}# 計算以e為底的冪
defe
(x):
#return math.pow(math.e,x)
return x
defdisplay_result
(observations,result_m):
""" 較為友好清晰的顯示結果
:param result_m:
:return:
"""# 從結果中找出最佳路徑
infered_states =
final = len(result_m) - 1
(p, pre_state), final_state = max(zip(result_m[final].values(), result_m[final].keys()))
infered_states.insert(0, final_state)
infered_states.insert(0, pre_state)
for t in range(final - 1, 0, -1):
_, pre_state = result_m[t][pre_state]
infered_states.insert(0, pre_state)
print(format("viterbi result", "=^59s"))
head = format("obs", " ^10s")
head += format("infered state", " ^18s")
for s in states:
head += format(s, " ^15s")
print(head)
print(format("", "-^59s"))
for obs,result,infered_state in zip(observations,result_m,infered_states):
item = format(obs," ^10s")
item += format(infered_state," ^18s")
for s in states:
item += format(result[s][0]," >12.8f")
if infered_state == s:
item += "(*)"
else:
item +=" "
print(item)
print(format("", "=^59s"))
defviterbi
(obs, states, start_p, trans_p, emit_p):
result_m = [{}] # 存放結果,每乙個元素是乙個字典,每乙個字典的形式是 state:(p,pre_state)
# 其中state,p分別是當前狀態下的概率值,pre_state表示該值由上一次的那個狀態計算得到
for s in states: # 對於每乙個狀態
result_m[0][s] = (e(start_p[s]*emit_p[s][obs[0]]),none) # 把第乙個觀測節點對應的各狀態值計算出來
for t in range(1,len(obs)):
for s in states: # 對於每乙個t時刻狀態s,獲取t-1時刻每個狀態s0的p,結合由s0轉化為s的轉移概率和s狀態至obs的發散概率
# 計算t時刻s狀態的最大概率,並記錄該概率的**狀態s0
# max()內部比較的是乙個tuple:(p,s0),max比較tuple內的第乙個元素值
result_m[t][s] = max([(e(result_m[t-1][s0][0]*trans_p[s0][s]*emit_p[s][obs[t]]),s0) for s0 in states])
return result_m # 所有結果(包括最佳路徑)都在這裡,但直觀的最佳路徑還需要依此結果單獨生成,在顯示的時候生成
defexample
():"""
乙個可以互動的示例
"""result_m = viterbi(observations,
states,
start_probability,
transition_probability,
emission_probability)
display_result(observations,result_m)
while
true:
user_obs = input("輪到你來輸入觀測,計算機來推斷可能狀態\n"
"使用 'n' 代表'正常', 'c' 代表'發冷','d'代表'發暈'\n"
"您輸入:('q'將退出):")
參考自:
簡單理解viterbi 維特比演算法
viterbi演算法其實就是多步驟每步多選擇模型的最優選擇問題,其在每一步的所有選擇都儲存了前續所有步驟到當前步驟當前選擇的最小總代價 或者最大價值 以及當前代價的情況下前繼步驟的選擇。依次計算完所有步驟後,通過回溯的方法找到最優選擇路徑。符合這個模型的都可以用viterbi演算法解決。隱含的身體狀...
viterbi演算法 python版
牛mm細心給我講了乙個小時,終於明白它的含義,然後花了一兩節分布式資料庫的課實現了。當時牛mm還說不可能這麼快實現,結果不可能事還是發生了。發現python果真非常好用。不明白此演算法可以看這篇blog 初始化方法 viterbi演算法函式 結果列印輸出函式 nodes format path is...
維特比演算法(Viterbi)
import numpy as np state transfer np.array 0.5,0.2,0.3 0.3,0.5,0.2 0.2,0.3,0.5 狀態轉移矩陣 observe prob np.array 0.5,0.5 0.4,0.6 0.7,0.3 觀測概率矩陣 initial np....