概述

隐马尔可夫模型(Hidden Markov Model,HMM)是一种统计模型,用于描述一个含有隐含未知参数的马尔可夫过程。1

HMM的核心思想是:系统状态不可直接观测,只能通过观测序列间接推断。

经典应用场景

领域应用
语音识别将声学信号转为文字
自然语言处理词性标注、命名实体识别
生物信息学基因序列分析
金融市场状态预测(牛市/熊市)
手势识别从视频序列中识别动作

HMM的基本结构

一个直观的例子

问题:根据多年树木年轮的尺寸(观察值),推断过去的气温状态(隐藏状态)。

隐藏状态(不可观测):  炎热(H) → 炎热(H) → 寒冷(C) → 炎热(H)
                          ↓         ↓         ↓         ↓
观察值(可观测):      小(S)     中(M)     小(S)     大(L)

五元组定义

符号含义说明
状态数隐藏状态的个数
观测符号数可能的观测值个数
转移概率矩阵
观测概率矩阵
初始状态分布

HMM通常记作


HMM的三个基本问题

问题一:评估问题(Evaluation)

给定:模型 和观测序列

求解:计算 ,即观测序列出现的概率

问题二:解码问题(Decoding)

给定:模型 和观测序列

求解:找到最可能的状态序列

问题三:学习问题(Learning)

给定:观测序列

求解:调整参数 使得 最大


问题一:Forward算法

朴素方法的困境

直接计算 需要对所有可能的状态序列求和:

对于长度为 的序列,状态数为 ,则需要计算 种可能,这在实际中是不可行的。

α-pass递归

定义前向变量

递归步骤

  1. 初始化):
  1. 递归):
  1. 终止

时间复杂度

方法时间复杂度
朴素方法
Forward算法

问题二:Viterbi算法

动态规划思想

Viterbi算法使用动态规划找到最可能的状态序列。核心思想是:保留到达每个状态的最优路径。

δ-ψ变量

定义:

  • :时刻 ,状态为 的所有路径中,最大概率值
  • :时刻 ,状态为 的最优路径的前驱状态

算法步骤

  1. 初始化
  1. 递归):
  1. 终止
  1. 回溯

下溢问题

由于概率连乘会导致数值下溢,实际中通常使用对数概率


问题三:Baum-Welch算法(EM算法)

后向变量

定义后向变量

递归步骤

  1. 初始化):
  1. 递归):

γ和ξ变量

γ变量(单状态概率):

ξ变量(双状态概率):

参数重估计

  1. 更新初始分布
  1. 更新转移概率
  1. 更新观测概率

算法流程

输入: 观测序列 O, 初始参数估计
输出: 最优参数 λ*

重复:
    1. E步: 计算 γ_t(i) 和 ξ_t(i,j)
    2. M步: 用公式更新 A, B, π
    3. 计算 log P(O|λ)
直到 log P(O|λ) 收敛

Python实现

Forward算法实现

import numpy as np
 
def forward(obs, A, B, pi):
    """
    Forward算法计算观测概率
    
    参数:
        obs: 观测序列 (T,)
        A: 转移概率矩阵 (N, N)
        B: 观测概率矩阵 (N, M)
        pi: 初始分布 (N,)
    
    返回:
        prob: 观测序列的概率
        alpha: 前向变量 (T, N)
    """
    T = len(obs)
    N = len(pi)
    
    # 缩放因子,防止下溢
    scale = np.zeros(T)
    
    # 初始化
    alpha = np.zeros((T, N))
    alpha[0] = pi * B[:, obs[0]]
    scale[0] = np.sum(alpha[0])
    alpha[0] /= scale[0]
    
    # 递归
    for t in range(1, T):
        for j in range(N):
            alpha[t, j] = np.dot(alpha[t-1], A[:, j]) * B[j, obs[t]]
        scale[t] = np.sum(alpha[t])
        alpha[t] /= scale[t]
    
    # 计算对数概率
    prob = -np.sum(np.log(scale))
    
    return np.exp(prob), alpha
 
# 示例:天气模型
# 状态:0=晴, 1=雨
# 观测:0=散步, 1=购物, 2=打扫
 
A = np.array([[0.7, 0.3],
              [0.4, 0.6]])  # 转移概率
 
B = np.array([[0.5, 0.2, 0.3],
              [0.1, 0.6, 0.3]])  # 观测概率
 
pi = np.array([0.6, 0.4])  # 初始分布
 
obs = np.array([0, 2, 1])  # 观测序列:散步→打扫→购物
prob, alpha = forward(obs, A, B, pi)
print(f"观测概率: {prob:.6f}")

Viterbi算法实现

def viterbi(obs, A, B, pi):
    """
    Viterbi算法求解最优状态序列
    
    返回:
        path: 最优状态序列
        prob: 最优路径的概率
    """
    T = len(obs)
    N = len(pi)
    
    # 初始化
    delta = np.zeros((T, N))
    psi = np.zeros((T, N), dtype=int)
    
    delta[0] = np.log(pi) + np.log(B[:, obs[0]])
    psi[0] = 0
    
    # 递归
    for t in range(1, T):
        for j in range(N):
            prob = delta[t-1] + np.log(A[:, j])
            psi[t, j] = np.argmax(prob)
            delta[t, j] = np.max(prob) + np.log(B[j, obs[t]])
    
    # 回溯
    path = np.zeros(T, dtype=int)
    path[T-1] = np.argmax(delta[T-1])
    for t in range(T-2, -1, -1):
        path[t] = psi[t+1, path[t+1]]
    
    return path, np.exp(np.max(delta[T-1]))
 
# 测试
path, prob = viterbi(obs, A, B, pi)
state_names = ['晴', '雨']
print(f"最优状态序列: {[state_names[i] for i in path]}")
print(f"概率: {prob:.6f}")

实际应用:词性标注

问题背景

给定一个句子,为每个词标注词性(如名词、动词、形容词等)。

HMM建模

  • 隐藏状态:词性标签(NN, VB, DT等)
  • 观测序列:句子中的词
  • 转移概率
  • 发射概率

示例

句子: "The cat sits on the mat"
观测:  The  cat  sits  on   the  mat
标签:  DT   NN   VBZ   IN   DT   NN

使用Viterbi算法找到最可能的标签序列。


HMM的局限性与扩展

HMM的局限

  1. 观测独立性假设:假设观测只与当前状态有关
  2. 一阶马尔可夫假设:假设状态只与前一状态有关
  3. 表达能力有限:难以建模复杂的序列依赖

扩展方向

模型改进
高阶HMM状态依赖前多个状态
条件随机场(CRF)放松观测独立性假设
双向LSTM建模长距离依赖

详见 Transformer与注意力机制

马尔可夫链理论扩展

HMM是马尔可夫链理论的重要应用。更一般的马尔可夫链理论见:

注意力机制与马尔可夫链

2025年的研究表明,Transformer中的注意力机制可以解释为离散时间马尔可夫链,详见:


参考

Footnotes

  1. L. R. Rabiner, “A Tutorial on Hidden Markov Models and Selected Applications in Speech Recognition”, Proceedings of the IEEE, 1989