You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

hmmlearn拟合MultinomialHMM时维度不匹配错误的技术问询

问题分析与解决

错误原因解析

你遇到的维度不匹配问题,核心是对MultinomialHMM的输入数据格式理解有误:

  • 你手动设置了model.n_features = 4(对应词汇表大小),这代表模型期望每个观测样本是4维的计数向量(对应词汇表中每个类别的出现次数)。
  • 但你生成的observations是(10,7)的数组,每个样本是7个离散取值(属于词汇表),模型把这7当成了特征维度,自然和期望的4不匹配。

另外,lengths参数的用法也有误:它的作用是指定多个观测序列的长度,当你把多个序列拼接成一个一维数组时,用lengths告诉模型每个序列的长度,而非每个样本的长度。

修正后的代码

根据你的需求(离散观测值,每个时间步取词汇表中的一个值),正确实现如下:

import numpy as np
from hmmlearn import hmm

states = ['up', 'down']
start_probs = np.array([0.6, 0.4])
vocabulary = [0, 1, 2, 3]
emission_probs = np.array(
    [
        [0.25, 0.1, 0.4, 0.25],
        [0.2, 0.5, 0.1, 0.2],
    ]
)
trans_mat = np.array(
    [
        [0.8, 0.2], 
        [0.2, 0.8],
    ]
)

# 生成10个观测序列,每个序列长度为7
sequences = [np.random.choice(vocabulary, 7) for _ in range(10)]
# 把所有序列拼接成二维数组(每个观测值单独成一行)
observations = np.concatenate(sequences).reshape(-1, 1)
# lengths记录每个序列的长度,这里每个序列长度都是7
lengths = [len(seq) for seq in sequences]

# 初始化模型:单变量离散观测无需设置n_trials
model = hmm.MultinomialHMM(
    n_components=len(states),
    n_iter=50,
    init_params='',
)

model.n_features = len(vocabulary)
model.startprob_ = start_probs
model.transmat_ = trans_mat
model.emissionprob_ = emission_probs

# 拟合模型
model.fit(observations, lengths)
# 解码时传入完整观测数组和序列长度列表
logprob, received = model.decode(observations, lengths)
# 将解码结果拆分回对应每个序列的状态
states_per_sequence = np.split(received, np.cumsum(lengths)[:-1])

关键要点说明

  • 观测数据格式:对于单变量离散观测(每个时间步一个词汇值),X需要是形状为(n_total_samples, 1)的二维数组,其中n_total_samples是所有观测序列的总长度。
  • lengths参数:必须是一个列表,每个元素对应一个观测序列的长度,列表元素总和等于X的第一维长度。
  • n_trials参数:该参数用于多试验的多项分布观测(比如每个时间步做N次试验,统计每个类别的出现次数),你的场景是单试验(每个时间步一个观测值),因此不需要设置。

内容的提问来源于stack exchange,提问作者zzzbbx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 15:26:31