样例:
观测序列:【A,B,A,B】 (代码中用1,2,1,2代表)
# 隐马尔可夫模型代码演示
def main():
pos = [[0.4, 0.6, 0], [0, 0.8, 0.2],[0, 0, 1]] # 状态转化
A = [0.7,0.3]
B = [0.4,0.6]
C = [0.8,0.2]
gcgl = [A,B,C] # 观测概率
guance = [1,2,1,2] # 观测序列
N = len(pos) # 状态数
len_g = len(guance) # 观测序列长度
dp = [[0 for i in range(len_g)]for i in range(N)]
dp[0][0] = A[0]
dp[1][0] = 0
for j in range(1,len_g):
for i in range(N):
for k in range(N): # 上一时刻的状态
dp[i][j] += dp[k][j - 1] * pos[k][i] * gcgl[i][guance[j] - 1]
ans = 0
for i in range(N):
ans += dp[i][len_g - 1]
print(dp[i])
print("观测序列出现概率:" , ans)
# 维特比算法
fai = [[0 for i in range(len_g)]for i in range(N)] # 上一最佳状态存储
dpv = [[0 for i in range(len_g)]for i in range(N)]
dpv[0][0] = A[0]
dpv[1][0] = 0
fai[0][0] = -1
for j in range(1,len_g):
for i in range(N):
flag = 0
max1 = 0
for k in range(N): # 上一时刻的状态
if max1 < dpv[k][j - 1] * pos[k][i] * gcgl[i][guance[j] - 1]:
max1 = dpv[k][j - 1] * pos[k][i] * gcgl[i][guance[j] - 1]
flag = k
dpv[i][j] = max1
fai[i][j] = flag # 上一最佳来源
maxpos = 0
maxpoint = 0
for i in range(N):
if maxpoint < dpv[i][len_g - 1]:
maxpos = i
maxpoint = dpv[i][len_g - 1]
i = maxpos
j = len_g - 1
best = []
best.append(i)
while fai[i][j] != -1:
best.append(fai[i][j])
i = fai[i][j]
j -= 1
best.reverse()
for i in range(len(best)):
best[i] += 1
print("最佳出现状态序列:",best)
if __name__ == '__main__':
main()
运行结果: