HMM基于两大假设:
(1)齐次马尔科夫假设:存在于状态之间,即假设隐藏的马尔可夫链在任意时刻t的状态只依赖于其前一时刻t-1的状态,与其他无关。
(2)观测独立性假设:存在于发射概率中,即t时刻的观测只依赖于该时刻的马尔科夫链的状态,与其他时刻的无关。
HMM的三大问题:
HMM的三元符号表示:
lambda = (A, B, Pi)
其中: A为转移概率,即状态i转移到状态j的概率;B为观测概率或者发射概率;Pi为初始状态概率
另外: 在代码中会提到O,为观测序列
(1)概率计算问题:给定 lambda和O,求P(O | lambda)的概率, 方法:前向算法,后向算法以及前后向结合的算法(本文主要提供前向算法代码)
(2)学习(参数)问题:EM算法
(3)预测问题:viterbi算法
HMM中前向算法:
(1)前向算法原理:(来源:李航老师的统计学习方法)
输入:隐式马尔可夫模型lambda,以及观测序列O
输出:P(O | lambda)
算法过程:
算法可根据李航老师书中盒子和球的模型例子进行理解,此处提供实现代码:
import numpy as np
# 转移概率:a,观测概率:b,初始概率:pi 观测序列:o
A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])
B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])
PI = np.array([0.2, 0.4, 0.4])
O = np.array([0,1,0])
def hmm_forward(A, B, PI, O):
n = np.shape(PI)[0] # 状态个数,即三个盒子
m = np.shape(O)[0] # 观测序列长度
alpha = np.zeros((m, n))
for i in range(n):
alpha[0][i] = PI[i] * B[i][O[0]]
for t in range(1,m):
for i in range(n):
temp = 0.0
for j in range(n):
temp = temp + alpha[t-1][j] * A[j][i]
temp = temp * B[i][O[t]]
alpha[t][i] = temp
print(alpha)
return alpha
if __name__ == '__main__':
alpha = hmm_forward(A, B, PI, O)
p = 0.0
for i in range(3):
p += alpha[2][i]
print(p)
peace & love