viterbi演算法其實就是多步驟每步多選擇模型的最優選擇問題,其在每一步的所有選擇都儲存了前續所有步驟到當前步驟當前選擇的最小總代價(或者最大價值)以及當前代價的情況下前繼步驟的選擇。依次計算完所有步驟後,通過回溯的方法找到最優選擇路徑。符合這個模型的都可以用viterbi演算法解決。
隱含的身體狀態 =
可觀察的感覺狀態 =
月兒預判的阿驢身體狀態的概率分布 =這就是初始狀態序列。
月兒認為的阿驢身體健康狀態的轉換概率分布 =
這樣就可以列出相應的狀態轉移矩陣。
月兒認為的在相應健康狀況條件下,阿驢的感覺的概率分布 = 這樣就可以列出相應的觀測矩陣。
下面就是解決問題了。阿驢連續三天的身體感覺依次是: 正常、冷、頭暈 。
已知如上,求:阿驢這三天的身體健康狀態變化的過程是怎麼樣的?即已知觀測序列和hmm模型的情況下,求狀態序列。
最後一天的狀態概率分布即為最優路徑的概率,即p(最優)=0.01512,這樣我們可以得到最優路徑的終點,是發燒。這樣,我們的狀態序列逆推出來了。即為:健康,健康,發燒。
# 狀態的樣本空間
states = ('健康', '發熱')
# 觀測的樣本空間
observations = ('正常', '發冷', '發暈')
# 起始個狀態概率
start_probability =
# 狀態轉移概率
transition_probability = ,
'發熱': ,
}# 狀態->觀測的發散概率
emission_probability = ,
'發熱': ,
}# 計算以e為底的冪
def e(x):
#return math.pow(math.e,x)
return x
def display_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"))
def viterbi(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 # 所有結果(包括最佳路徑)都在這裡,但直觀的最佳路徑還需要依此結果單獨生成,在顯示的時候生成
def example():
"""乙個可以互動的示例
"""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)
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....
維特比演算法(Viterbi)
編輯 維特比演算法是一種 動態規劃演算法用於尋找最有可能產生觀測事件序列的 維特比路徑 隱含狀態序列,特別是在馬爾可夫資訊源上下文和隱馬爾可夫模型中。術語 維特比路徑 和 維特比演算法 也被用於尋找觀察結果最有可能解釋相關的動態規劃演算法。例如在統計句法分析中動態規劃演算法可以被用於發現最可能的上下...
維特比viterbi演算法
先舉個例子來解釋 已知情況 假如模型已經學出這些引數概率 隱含的身體狀態 可觀察的感覺狀態 月兒預判的阿驢身體狀態的概率分布 月兒認為的阿驢身體健康狀態的轉換概率分布 健康發燒 健康0.7 0.4發燒 0.30.6 月兒認為的在相應健康狀況條件下,阿驢的感覺的概率分布 健康發燒 正常0.5 0.1冷...