隐马尔可夫模型中转移概率矩阵对数转换报错问题

何老师:
您好,在阅读源码的时候发现书第148页,使用{B,M,E,S}标注集进行字符标记,我使用python实现这个功能,程序在统计转换概率的时候,数据大致如下:


看到其中有 0.0 的数据,进行归一化处理后,再进行对数转换,程序报错。原因是 math.log() 中参数是不能为0的,我不知道为什么java的demo没有报错,但是在python的确无法执行。
因此,请问是否可以加入判断,若出现等于0.0的情况,使用最小浮点数或者直接不做log()转换处理?

这段教学代码为了简洁的确没有考虑0的情况。你可以给概率加一个小数 \epsilon=e^{-10} 或者max一下:

谢谢何老师的指正,我在这里碰到了另外一个问题,之前不使用最小概率来进行模型测评的时候 p = 23%,而当我修改代码后准确率提升到了65.9%,但是和java代码测评结果(78.49%)对比还是差了很多。
我对比了两者的初始概率向量、转移概率矩阵和发射概率矩阵的数据,都是参数上靠后几位小数点差别,而我现在不确定是不是就是因为这些微小的差值,而造成准确率有如此大的差异?

我不确定你的Python实现中是否有其他差异,比如Viterbi算法是否正确实现。你可以逐步替换Java实现到你的实现中来排查问题。

  1. 把Java训练出来的3个参数向量/矩阵替换你的Python代码中排查是否是浮点数精度问题
  2. 实现一个仿Java的log: float('-inf') if not x else log(x) 排查是否是log导致
  3. 把你的参数替换到Java代码中排查是否是你的维特比算法实现错误
1 Like

感谢何老师指导,我通过把java运行的模型参数,放在python进行执行测评,准确率还是未提高,从而定位到在python的解码问题上,不过,也并非是维特比算法的问题,而是字符转换的问题。谢谢何老师。