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.array([0.2, 0.4, 0.4]) # 初始狀態概率向量
observes = ['紅', '白'] # 所有可能的觀測集合
states = [0, 1, 2] # 所有可能的狀態集合
observe_seq = ['紅', '白', '紅'] # 觀測序列
def argmax(path_value, state_transfer, states, state, m): # 在t時刻狀態為i的所有單個路徑(i1,i2,...,it)中概率最大的路徑第t-1個結點
max_index = -1
max_value = -1
for statej in states:
if path_value[m-1][statej] * state_transfer[statej][state] > max_value:
max_value = path_value[m-1][statej] * state_transfer[statej][state]
max_index = statej
return max_index
def argmax2(path_value_len):
max_index = -1
max_value = -1
for i in range(len(path_value_len)):
if path_value_len[i] > max_value:
max_value = path_value_len[i]
max_index = i
return max_index
def viterbi(state_transfer, states, observe_prob, initial, observe_seq):
path_value = np.zeros(shape=(3, 3)) # 儲存在t時刻狀態為i的所有單個路徑(i1,i2,...it)中概率最大值(t=0,1,2, i=0,1,2)
path_node = np.zeros(shape=(3, 3), dtype=int) # 儲存在t時刻狀態為i的所有單個路徑(i1,i2,...,it)中概率最大的路徑第t-1個結點
for m in range(len(observe_seq)):
if m == 0: #初始化
for state in states:
path_value[m][state] = initial[state] * observe_prob[state][observes.index(observe_seq[m])] #在t時刻狀態為i的所有單個路徑(i1,i2,...it)中概率最大值(t=0,1,2, i=0,1,2)
path_node[m] = [-1, -1, -1]
else:
for state in states: # 遞推
path_value[m][state] = max([path_value[m-1][statej] * state_transfer[statej][state] for statej in states]) \
* observe_prob[state][observes.index(observe_seq[m])] # 在t時刻狀態為i的所有單個路徑(i1,i2,...it)中概率最大值(t=0,1,2, i=0,1,2)
path_node[m][state] = argmax(path_value, state_transfer, states, state, m) # 在t時刻狀態為i的所有單個路徑(i1,i2,...,it)中概率最大的路徑第t-1個結點
max_path_value = max(path_value[len(observe_seq)-1])
path =
i_t = argmax2(path_value[len(observe_seq)-1]) #最優路徑第t時刻狀態
for k in range(len(observe_seq)-1, -1, -1): # 最優路徑回溯
i_t = path_node[k][i_t]
print(list(reversed(path))[1:]) # 輸出最優路徑
print(max_path_value)
if __name__ == '__main__':
viterbi(state_transfer, states, observe_prob, initial, observe_seq)
維特比演算法(Viterbi)
編輯 維特比演算法是一種 動態規劃演算法用於尋找最有可能產生觀測事件序列的 維特比路徑 隱含狀態序列,特別是在馬爾可夫資訊源上下文和隱馬爾可夫模型中。術語 維特比路徑 和 維特比演算法 也被用於尋找觀察結果最有可能解釋相關的動態規劃演算法。例如在統計句法分析中動態規劃演算法可以被用於發現最可能的上下...
維特比viterbi演算法
先舉個例子來解釋 已知情況 假如模型已經學出這些引數概率 隱含的身體狀態 可觀察的感覺狀態 月兒預判的阿驢身體狀態的概率分布 月兒認為的阿驢身體健康狀態的轉換概率分布 健康發燒 健康0.7 0.4發燒 0.30.6 月兒認為的在相應健康狀況條件下,阿驢的感覺的概率分布 健康發燒 正常0.5 0.1冷...
簡單理解viterbi 維特比演算法
viterbi演算法其實就是多步驟每步多選擇模型的最優選擇問題,其在每一步的所有選擇都儲存了前續所有步驟到當前步驟當前選擇的最小總代價 或者最大價值 以及當前代價的情況下前繼步驟的選擇。依次計算完所有步驟後,通過回溯的方法找到最優選擇路徑。符合這個模型的都可以用viterbi演算法解決。隱含的身體狀...