隐马尔可夫模型 HMM 是一种概率图模型,由隐马尔可夫链随机生成观测序列的过程。HMM 中有几个概念:
- 状态 (States):
- 一组有限的“隐藏状态”表示底层的过程。这些状态是不可直接观察的。
- 示例: 天气状态(晴天、雨天、多云)或语音中的音素。
- 观察 (Observations):
- 一组有限的观察值对应于隐藏状态。这些是可见的输出。
- 示例: 温度(作为天气的观察值)或语音音频特征。
- 转移概率 (Transition Probabilities, A):
- 从一个状态转移到另一个状态的概率。
- 表示为一个矩阵,其中 A i j A_{ij} Aij 是从状态 i 转移到状态 j 的概率。
- 发射概率 (Emission Probabilities, B):
- 在给定隐藏状态下观察到某个输出的概率。
- 表示为一个矩阵,其中 B i j B_{ij} Bij 是在状态 i 下观察到 j 的概率。
- 初始概率 (Initial Probabilities, π \pi π):
- 系统在每个状态开始的概率。
状态之间的装换和状态到观察序列的转换,当前值只与上一个值有关,也就是 t 时间点的值只依赖 t-1 时间点的值。HMM 有三个重要问题,概率计算问题、参数估计问题和序列标注问题。
HMM 中, 状态序列与观察序列之间的概率可以通过以下公式进行描述:
观察序列: ( O = O 1 , O 2 , … , O T ) ( O = O_1, O_2, \ldots, O_T ) (O=O1,O2,…,OT), 状态序列: ( Q = q 1 , q 2 , … , q T ) ( Q = q_1, q_2, \ldots, q_T ) (Q=q1,q2,…,qT)
P ( O , Q ∣ λ ) = π q 1 b q 1 ( O 1 ) ∏ t = 2 T a q t − 1 , q t b q t ( O t ) P(O, Q | \lambda) = \pi_{q_1} b_{q_1}(O_1) \prod_{t=2}^T a_{q_{t-1}, q_t} b_{q_t}(O_t) P(O,Q∣λ)=πq1bq1(O1)∏t=2Taqt−1,qtbqt(Ot)
π
q
1
\pi_{q_1}
πq1 : 状态初始化概率
q
1
q_1
q1 .
a
q
t
−
1
,
q
t
a_{q_{t-1}, q_t}
aqt−1,qt : 状态转换概率
q
t
−
1
q_{t-1}
qt−1 to
q
t
q_t
qt .
b
q
t
(
O
t
)
b_{q_t}(O_t)
bqt(Ot) : 观察概率
O
t
O_t
Ot in state
q
t
q_t
qt .
λ
\lambda
λ : 模型参数
(
A
,
B
,
π
)
( A, B, \pi )
(A,B,π).
概率计算问题
已知状态序列和参数,找到观察序列,通过前向算法计算(Forward Algorithm)。
α t ( i ) = ( ∑ j = 1 N α t − 1 ( j ) a j , i ) b i ( O t ) \alpha_t(i) = \left( \sum_{j=1}^N \alpha_{t-1}(j) a_{j,i} \right) b_i(O_t) αt(i)=(∑j=1Nαt−1(j)aj,i)bi(Ot)
参数估计问题
已知观察序列和状态序列,找到参数,通过 Baum-Welch Algorithm 进行求解。该算法为 EM。
- E:计算前向变量
(
γ
t
(
i
)
)
和
(
ξ
t
(
i
,
j
)
)
( \gamma_t(i) ) 和 ( \xi_t(i, j) )
(γt(i))和(ξt(i,j))
γ t ( i ) = α t ( i ) β t ( i ) ∑ j = 1 N α t ( j ) β t ( j ) \gamma_t(i) = \frac{\alpha_t(i) \beta_t(i)}{\sum_{j=1}^N \alpha_t(j) \beta_t(j)} γt(i)=∑j=1Nαt(j)βt(j)αt(i)βt(i)
ξ t ( i , j ) = α t ( i ) a i , j b j ( O t + 1 ) β t + 1 ( j ) ∑ i = 1 N ∑ j = 1 N α t ( i ) a i , j b j ( O t + 1 ) β t + 1 ( j ) \xi_t(i, j) = \frac{\alpha_t(i) a_{i,j} b_j(O_{t+1}) \beta_{t+1}(j)}{\sum_{i=1}^N \sum_{j=1}^N \alpha_t(i) a_{i,j} b_j(O_{t+1}) \beta_{t+1}(j)} ξt(i,j)=∑i=1N∑j=1Nαt(i)ai,jbj(Ot+1)βt+1(j)αt(i)ai,jbj(Ot+1)βt+1(j) - M:计算最终参数
状态转换概率
a i , j = ∑ t = 1 T − 1 ξ t ( i , j ) ∑ t = 1 T − 1 γ t ( i ) a_{i,j} = \frac{\sum_{t=1}^{T-1} \xi_t(i, j)}{\sum_{t=1}^{T-1} \gamma_t(i)} ai,j=∑t=1T−1γt(i)∑t=1T−1ξt(i,j)
观察序列概率
b i ( k ) = ∑ t = 1 , O t = k γ t ( i ) ∑ t = 1 T γ t ( i ) b_i(k) = \frac{\sum_{t=1, O_t = k} \gamma_t(i)}{\sum_{t=1}^T \gamma_t(i)} bi(k)=∑t=1Tγt(i)∑t=1,Ot=kγt(i)
初始化概率
π i = γ 1 ( i ) \pi_i = \gamma_1(i) πi=γ1(i)
序列标注问题
已知观察序列和参数,找到状态序列,通过维特比算法计算(Viterbi Algorithm)。
δ t ( i ) = max j ( δ t − 1 ( j ) a j , i ) b i ( O t ) \delta_t(i) = \max_{j} \left( \delta_{t-1}(j) a_{j,i} \right) b_i(O_t) δt(i)=maxj(δt−1(j)aj,i)bi(Ot)
HMM 代码实现
#安装依赖
pip install hmmlearn
import numpy as np
from hmmlearn import hmm
# 定义隐马尔科夫模型 (HMM)
model = hmm.MultinomialHMM(n_components=2, random_state=42, n_trials=1)
# 隐藏状态 (0 = 雨天, 1 = 晴天)
states = ["Rainy", "Sunny"]
# 可观察的输出 (0 = 散步, 1 = 购物, 2 = 打扫)
observations = ["Walk", "Shop", "Clean"]
# 转移概率
# P(从雨天转移到雨天, 从雨天转移到晴天, 从晴天转移到雨天, 从晴天转移到晴天)
model.startprob_ = np.array([0.6, 0.4]) # 初始状态的概率
model.transmat_ = np.array([
[0.7, 0.3], # 雨天的转移概率
[0.4, 0.6] # 晴天的转移概率
])
# 发射概率
# P(散步|雨天), P(购物|雨天), P(打扫|雨天)
# P(散步|晴天), P(购物|晴天), P(打扫|晴天)
model.emissionprob_ = np.array([
[0.1, 0.4, 0.5], # 雨天的发射概率
[0.6, 0.3, 0.1] # 晴天的发射概率
])
# 定义一组观察序列 (例如:散步, 购物, 散步)
# 将观察值编码为整数 (散步 = 0, 购物 = 1, 打扫 = 2)
obs_seq = np.array([[0], [1], [0], ]).reshape(-1, 3)
# 使用维特比算法预测最可能的状态序列
logprob, state_sequence = model.decode(obs_seq, algorithm="viterbi")
# 显示结果
print("观察到的序列:", [observations[o[0]] for o in obs_seq]) # 显示观察到的活动
print("预测的状态序列:", [states[s] for s in state_sequence]) # 显示预测的隐藏状态
总结
HMM 是一个时间序列算法,由状态转换为观察序列,HMM常用于时间序列的场景,例如,图片生成的扩散模型。