我使用下面的代码来拟合具有两个隐藏状态、大小为 5 的词汇表(即 5 个可能的符号)和序列列表(每个序列有 10 个观察值)的 HMM 模型。 我不明白为什么
model.emissionprob_
的大小为 (2, 10)
,列数应等于词汇表中可用符号的数量,在本例中为 5。
from hmmlearn import hmm
import numpy as np
import pandas as pd
# Define the sequences
sequences = np.random.randint(1, 6, size=(100000, 10)).tolist()
# Convert sequences to numpy array
sequences_np = np.array(sequences)
# Create and fit the Multinomial HMM model with 2 hidden states
model = hmm.MultinomialHMM(n_components=2)
model.fit(sequences_np)
# Print the model parameters
print("Initial state distribution:")
print(model.startprob_)
print("\nTransition matrix:")
print(model.transmat_)
print("\nEmission probabilities:")
print(model.emissionprob_)
简短回答:听起来您可能需要
CategoricalHMM
而不是 MultinomialHMM
。 hmmlearn 曾经将前者称为后者(https://github.com/hmmlearn/hmmlearn/issues/335)。如果结果可以采用五个值,您可能还想使用 0 到 4 之间的值(而不是 1 到 5),否则 CategoricalHMM 会为 0 创建一个类别。
我在下面描述这两种型号之间的区别。
多项分布对 n 次试验中每种可能结果的数量进行建模。标准的例子是统计投掷n次骰子时每一面出现的次数。在此示例中,如果 n = 10,则观察结果可能是
(2, 2, 2, 0, 0, 4)
(1, 2, 3, 1, 3, 0)
(1, 0, 2, 4, 2, 1)
(4, 0, 0, 2, 1, 3)
(2, 1, 1, 0, 2, 4)
...
第一个观察结果告诉我们,在 n = 10 次掷骰子中,面 1、2 和 3 各出现了两次,面 4 和 5 没有出现,面 6 出现了四次。请注意,每次观察都是 6 次计数的序列,每个计数对应一种可能的结果(即骰子的每一面),并且每次观察中的计数加起来为 10(尝试/投掷的次数)。
该模型中感兴趣的参数通常是不同可能结果的概率。在上面的例子中,如果模具是平衡的,这些只是
(1/6, 1/6, 1/6, 1/6, 1/6, 1/6)
,我们可以根据数据(即根据上面的观察)估计这些。在 HMM 上下文中,假设这些概率由每个时间点的隐藏过程的状态决定。
这解释了在您模拟的数据上使用
MultinomialHMM
时获得的结果,其形式为
(4, 1, 3, 3, 4, 3, 2, 1, 2, 4)
(1, 1, 3, 5, 2, 1, 3, 4, 2, 2)
(3, 3, 5, 1, 5, 4, 2, 4, 5, 1)
(3, 1, 5, 2, 3, 2, 4, 5, 3, 1)
hmmlearn 将这些解释为 10 个可能结果的计数(每个观察向量的长度),并尝试估计每个状态下每个结果的概率。这就是为什么它在您的示例中返回两个 10 个概率的向量。因为您随机生成值,所以它估计所有概率都非常接近 0.1。
分类分布对一个变量进行建模,该变量可以具有一定概率的多个(定性)值。它可以被视为多项分布的特例,其中试验次数 (n) 等于 1。
在骰子示例中,每次观察都只是一次投掷的结果:
4
4
3
5
1
...
请注意,与上面的多项式示例相反,数字表示结果(为了方便起见,用整数索引),而不是计数。可能结果的数量对应于多项式示例中每个观察向量的长度,而在这里您将查看观察序列中出现了多少个唯一值。
该模型的参数也是不同结果的概率,即骰子示例中的
(1/6, 1/6, 1/6, 1/6, 1/6, 1/6)
。在分类 HMM 中,我们假设这些概率是由状态过程驱动的,因此某些结果可能在状态 1 中更频繁,而其他结果在状态 2 中更频繁。
使用问题中的代码,但将
MultinomialHMM
替换为 CategoricalHMM
(并模拟 0 到 4 之间的值),hmmlearn 估计的发射概率变为:
>>> print(model.emissionprob_)
[[0.19290415 0.20328402 0.19841795 0.20260928 0.2027846 ]
[0.58753269 0.01360612 0.30773709 0.06664846 0.02447564]]
正如预期的那样,我们得到了两个 5 个概率的向量:两种状态下 5 个结果的概率。