Scikit的隐马尔可夫模型接受不加1的观察概率

时间:2014-05-07 14:07:26

标签: python scikit-learn statistics hidden-markov-models

我正在尝试使用" MultinomialHMM"来构建具有2种状态和3种可能观察结果的玩具隐马尔可夫模型。模块,scikit-learn库的一部分。我的问题是,即使状态的观察概率加起来大于1或小于1,模块也接受(并生成预测)。例如:

import numpy
from sklearn import hmm
startprob = numpy.array([0.5, 0.5])
transition_matrix = numpy.array([[0.5, 0.5], [0.5, 0.5]])
model = hmm.MultinomialHMM(2, startprob, transition_matrix)
model.emissionprob_ = numpy.array([[0, 0, 0.2], [0.6, 0.4, 0]])

请注意,状态0发出的信号的概率为[0,0,0.2](加起来为0.2)。当被要求生成观察样本时,该模块不会抱怨:

model.sample(10) 
(array([1, 0, 0, 0, 0, 2, 1, 0, 0, 0], dtype=int64), array([1, 1, 0, 1, 1, 0, 1, 0, 0, 0]))

我还可以指定总计超过1的排放事件,并且该模型可以预测并没有投诉。

这是理想的行为吗?概率是否在某种程度上正常化了?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:2)

首先,HMM中不推荐使用sklearn。你需要查看https://github.com/hmmlearn/hmmlearn,这是 Python中的隐马尔可夫模型,scikit-learn like API

顺便说一句,你问的问题好像是一个bug。设置emissionprob_后,系统会调用_set_emissionprob。这会通过调用re-normalize来尝试normalize(emissionprob)

if not np.alltrue(emissionprob):
    normalize(emissionprob)

但是,此代码有两个问题:

  1. 剂量未正确设置轴。
  2. 即使文件说明了,也不是原地。
  3. 如此修改为

    if not np.alltrue(emissionprob):
        normalize(emissionprob, 1) # added axis term
    

    def normalize(A, axis=None):
        A += EPS
        Asum = A.sum(axis)
        if axis and A.ndim > 1:
            # Make sure we don't divide by zero.
            Asum[Asum == 0] = 1
            shape = list(A.shape)
            shape[axis] = 1
            Asum.shape = shape
        A /= Asum # this is true in-place, it was `return A / Asum`  <<= here