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

基于Viterbi算法的HMM词性标注模型为何总是预测同一种标签?

HMM词性标注始终输出同一标签的错误原因分析

核心错误

错误出现在predict方法中Viterbi递推计算q矩阵和back_point回溯矩阵的逻辑,完全不符合Viterbi算法的递推公式,具体问题如下:

  • 递推逻辑完全倒置:你当前要计算的是t+1时刻处于标签s的最大概率,需要遍历t时刻所有可能的前序标签,计算每个前序标签转移到s、再发射出当前词的联合概率,取最大值作为结果。但你的代码错误地用了t时刻同一状态i_s的概率乘以转移矩阵的整列,逻辑完全错误。该错误会导致概率计算完全偏离真实分布,最终q矩阵最后一行的最大值永远对应训练集中出现频次最高的标签,因此所有预测结果都为同一标签。
  • 初始状态设置不合理:你将q[0]设为全1,等价于假设所有标签作为句子开头的概率完全相同,不符合实际语料分布,会进一步放大计算误差。
  • 回溯指针计算逻辑错误:原代码中back_point的取值从错误的probability变量中推导,完全无法记录正确的前序状态索引。

修正后的Viterbi递推代码

替换原predict方法中遍历t和i_s的两层循环为以下代码即可:

for t in range(len_sent):
    current_word = current_sent[t]
    # 未登录词处理逻辑保留,这里不做修改
    if current_word not in self.words:
        tagdict = findtags('NOUN', brown_tagged_words)
        current_word = tagdict['NOUN'][0][0]
    # 遍历t+1时刻所有可能的标签s
    for i_s in range(len(self.tags)):
        s = self.tags[i_s]
        # 计算所有t时刻标签转移到s的概率序列
        prob_series = q[t] * self.A.loc[:, s].values * self.B.loc[current_word, s]
        # 取最大值作为t+1时刻s标签的概率
        q[t+1][i_s] = prob_series.max()
        # 取最大值对应的前序标签索引作为回溯指针
        back_point[t+1][i_s] = prob_series.argmax()

额外优化建议

  • 给转移矩阵、发射矩阵增加平滑处理(比如加1平滑),避免出现概率为0的情况,进一步提升模型稳定性。
  • 初始状态q[0]可以替换为训练集中每个标签作为句子开头的统计概率,而非全1。

内容的提问来源于stack exchange,提问作者ALiCe P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:24:04