lihang-code
lihang-code copied to clipboard
第10章隐形马尔可夫模型注释错误及维特比算法实现错误
在研读第10章隐形马尔可夫模型代码的时候,发现出现两个问题:
1.注释错误: 代码中的:N = len(Q) # 状态序列的大小 由定义可知Q应是所有可能状态的集合,而不是状态序列,状态序列为I 因此应更改为:N = len(Q) #可能存在的状态数量 以免误解
2.维特比算法实现中的错误: 在维特比算法实现的过程中多次用到argmax函数,由于其返回的是索引,因此应+1才能和正常的下标值相符合。原代码中在计算时未+1,但在输出时却加了1,导致算法计算的delta、psis参数部分正确、部分错误,最终预测的状态序列也是错误的。 原代码 psis[i][t] = np.argmax(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A])) #未+1 ... I[0][M-1] = np.argmax([delta[M-1] for delta in deltas]) #未+1 print('i%d=argmax[deltaT(i)]=%d' % (M, I[0][M-1]+1)) #输出时手动+1 for t in range(M-2, -1, -1): I[0][t] = psis[int(I[0][t+1])][t+1] #因之前未+1,因此此处直接当索引使用了 print('i%d=psis%d(i%d)=%d' % (t+1, t+2, t+2, I[0][t]+1)) #输出时手动+1 print(I) #最终输出错误
建议在计算产生索引时统一+1,以生成符合实际的下标值;而在使用索引时再-1来避免超限 更改代码: psis[i][t] = np.argmax(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A])) + 1 #索引值要+1 ... I[0][M-1] = np.argmax([delta[M-1] for delta in deltas]) + 1 #索引值要+1 print('i%d=argmax[deltaT(i)]=%d' % (M, I[0][M-1])) #直接输出 for t in range(M-2, -1, -1): I[0][t] = psis[int(I[0][t+1]) - 1][t+1] #用做索引,因此-1 print('i%d=psis%d(i%d)=%d' % (t+1, t+2, t+2, I[0][t])) #直接输出 print("状态序列I:", I)
此时所有参数及最终结果均正确,且与书本中的结果一致。
谢谢,已修改