我正在尝试使用" 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的排放事件,并且该模型可以预测并没有投诉。
这是理想的行为吗?概率是否在某种程度上正常化了?如果是这样,怎么样?
答案 0 :(得分:2)
首先,HMM
中不推荐使用sklearn
。你需要查看https://github.com/hmmlearn/hmmlearn,这是 Python中的隐马尔可夫模型,scikit-learn like API
emissionprob_
后,系统会调用_set_emissionprob
。这会通过调用re-normalize
来尝试normalize(emissionprob)
:
if not np.alltrue(emissionprob):
normalize(emissionprob)
但是,此代码有两个问题:
如此修改为
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