python - Scikit 的隐马尔可夫模型接受加起来不等于 1 的观察概率

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

我正在尝试使用“MultinomialHMM”模块(scikit-learn 库的一部分)构建一个具有 2 个状态和 3 个可能观察值的玩具隐马尔可夫模型。我的问题是,即使状态的观测概率加起来大于 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 的排放概率,并且模型会毫无怨言地生成预测。

这是期望的行为吗?概率是否以某种方式标准化?如果是这样,怎么办?

最佳答案

首先,sklearn 中已弃用 HMM。您需要查看https://github.com/hmmlearn/hmmlearn ,这是Python中的隐马尔可夫模型,具有类似scikit-learn的API

顺便说一句,你问的问题似乎是一个错误。当您设置emissionprob_时,将调用_set_emissionprob。这会尝试通过调用 normalize(emissionprob) 来重新标准化:

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

但是,这段代码有两个问题:

  1. 没有正确设置轴。
  2. 尽管文件这么说,但还没有到位。

如此修改为

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

关于python - Scikit 的隐马尔可夫模型接受加起来不等于 1 的观察概率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23520101/

相关文章:

python - 可以使用 * 运算符解包的对象的正确类型注释?

python - 如何使用 opencv-python 创建缩略图?

python - Scikit-learn 的 DecisionTreeClassifier 的 fit 方法将 ValueError : Couldn't broadcast input array from shape (10, 35) 赋予形状 (10)

python - 自动sklearn安装错误

r - 逻辑回归返回错误,但在减少的数据集上运行正常

python - 使用 tripcolor 绘制多组数据 - 颜色图中的透明度

python - 将 pyqtgraph LinearRegionitem 与绘图项的轴连接时出现递归错误

python - Scikit-learn 未正确构建

machine-learning - 支持向量机模型应该有多具体?

python - 在 Python 中使用 3D 数据实现 2 样本 KS 测试