第1关:隐马尔可夫模型基本思想
代码文件
import numpy as np
from hmmlearn import hmm
import math
from hmmlearn.hmm import GaussianHMM, GMMHMM
def getModel():
# 任务1:创建 GaussianHMM 模型,用变量名model1标记
# 创建 GMMHMM 模型,用变量名model2标记
model1 = GaussianHMM()
model2 = GMMHMM()
# 任务2:根据提示设置 model1 的参数
# 设置最大迭代次数为10
model1.n_iter = 10
# 设置隐藏状态数目为20
model1.n_components = 20
# 任务3:根据提示设置 model2 的参数
# 设置最小方差为 0.5
model2.min_covar = 0.5
# 设置随机数种子为 8
model2.random_state = 8
return model1, model2
题目描述
任务描述
本关任务:编写一个能够基于 Python 创建出隐马尔可夫模型的小程序。
相关知识
为了完成本关任务,你需要掌握:
1.HMM 模型的思想与原理;
2.如何构建 HMM 模型。
隐马尔可夫模型
隐马尔可夫模型(Hidden Markov Model,HMM)是一个统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中确定该过程的隐含参数。隐马尔可夫模型(HMM)可以用五个元素来描述,包括2个状态集合和3个概率矩阵:隐含状态 S
、可观测状态O
、初始状态概率矩阵π
、隐含状态转移概率矩阵 A
、观测状态转移概率矩阵 B
。
图 1 HMM 模型
如图1所示,有两个行数据,这两列数据分布的特点,第一行是X
行,表示状态序列,第二行是O
行,表示观测序列,X
行的某一个状态依赖于前一个状态,X
行的每一个都指向O
行其中的一个。因此,HMM 模型中涉及到以下定义:
- 状态序列: 隐藏的马尔科夫链随机生成的状态序列,称为状态序列(state sequence);
- 观测序列: 每个状态生成一个观测,而由此产生的观测的随机序列,称为观测序列(obeservation sequence);
- 马尔科夫模型: 马尔科夫模型是关于时序的概率模型,描述由一个隐藏的马尔科夫链随机生成不可观测的状态随机序列,再由各个状态生成一个观测而产生观测随机序列的过程。
模型表示
设Q是所有可能的状态的集合,V是所有可能的观测的集合。Q=q1,q2,…,qN,V=v1,v2,…,vM,其中,N是可能的状态数,M是可能的观测数。
I是长度为T的状态序列,O是对应的观测序列。 I=(i1,i2,…,iT),O=(o1,o2,…,oT)
A是状态转移矩阵:A=[aij]N×N i=1,2,…,N;j=1,2,…,N
其中,在时刻t,处于qi 状态的条件下在时刻t+1转移到状态qj 的概率: aij=P(it+1=qj∣it=qi)
B是观测概率矩阵:B=[bj(k)]N×M k=1,2,…,M;j=1,2,…,N
其中,在时刻t处于状态qj 的条件下生成观测vk 的概率: bj(k)=P(ot=vk∣it=qj)
π是初始状态概率向量:π=(πi) 其中,πi=P(i1=qi)
隐马尔科夫模型由初始状态概率向量π、状态转移概率矩阵A和观测概率矩阵B决定。π和A决定状态序列,B决定观测序列。因此,隐马尔科夫模型λ可以由三元符号表示,即:λ=(A,B,π)。A,B,π称为隐马尔科夫模型的三要素。
如何直接创建 HMM 模型?
在Python
中,我们可以直接调用第三方库hmmlearn
来创建 HMM 模型,其中提供了三种 HMM 的实现方式:GaussianHMM(观测状态连续型且符合高斯分布)、GMMHMM(观测状态连续型且符合混合高斯分布) 、MultinomialHMM(观测状态离散型)。
使用示例:
model = hmm.MultinomialHMM(n_components=n_states, n_iter=1000, tol=0.01)
模型参数:
n_components
:隐藏状态数目covariance_type
:协方差矩阵的类型min_covar
:最小方差,防止过拟合startprob_prior
:初始概率向量transmat_prior
:转移状态矩阵means_prior, means_weight
:均值covars_prior, covars_weight
:协方差algorithm
:所用算法random_state
:随机数种子n_iter
:最大迭代次数tol
:停机阈值verbose
:是否打印日志以观察是否已收敛params
:决定哪些参数在迭代中更新init_params
:决定哪些参数在迭代前先初始化
编程要求
根据提示,在右侧编辑器补充代码,根据提示完成对隐马尔可夫模型的创建,并指定相关的参数。
测试说明
平台会对你编写的代码进行测试:
测试输入:无
;
预期输出:
您创建的 GaussianHMM 模型中,最大迭代次数为10,隐藏状态数目为20
您创建的 GMMHMM 模型中,最小方差为0.5,随机数种子为8
模型按要求构建成功,任务完成!
开始你的任务吧,祝你成功!
第2关:HMM 模型的前向与后向算法
代码文件
import numpy as np
def Forward(transition_probability, emission_probability, pi, obs_seq):
"""
:param transition_probability: 状态转移矩阵
:param emission_probability: 发射矩阵
:param pi: 初始状态概率
:param obs_seq: 观测状态序列
:return: 返回结果
"""
transition_probability = np.array(transition_probability)
emission_probability = np.array(emission_probability)
pi = np.array(pi)
Row = transition_probability.shape[0]
Col = len(obs_seq)
F = np.zeros((Row, Col))
F[:, 0] = pi * np.transpose(emission_probability[:, obs_seq[0]])
for t in range(1, Col):
for n in range(Row):
F[n, t] = np.dot(F[:, t - 1], transition_probability[:, n]) * emission_probability[n, obs_seq[t]]
return F
def Backward(transition_probability, emission_probability, pi, obs_seq):
"""
:param transition_probability: 状态转移矩阵
:param emission_probability: 发射矩阵
:param pi: 初始状态概率
:param obs_seq: 观测状态序列
:return: 返回结果
"""
transition_probability = np.array(transition_probability)
emission_probability = np.array(emission_probability)
pi = np.array(pi)
Row = transition_probability.shape[0]
Col = len(obs_seq)
F = np.zeros((Row, Col))
F[:, (Col - 1):] = 1
for t in reversed(range(Col - 1)):
for n in range(Row):
F[n, t] = np.sum(F[:, t + 1] * transition_probability[n, :] * emission_probability[:, obs_seq[t + 1]])
return F
题目描述
任务描述
本关任务:编写一个隐马尔可夫模型概率计算的前向算法和后向算法的小程序。
相关知识
为了完成本关任务,你需要掌握:
1.前向算法的原理和计算方法;
2.后向算法的原理和计算方法。
HMM 模型的三个问题
隐马尔可夫模型(HMM)在实际应用中,一般会遇上三种问题:
1、概率计算问题 给定模型λ=(A,B,π)和观测序列O=o1,o2,…,oT,计算在模型λ下观测序列O出现的概率P(O∣λ)。
2、学习问题
已知观测序列O=o1,o2,…,oT,估计模型λ=(A,B,π),使P(O∣λ)最大。即用极大似然法的方法估计参数。
3、预测问题(也称为解码问题):
已知观测序列O=o1,o2,…,oT 和模型λ=(A,B,π),求给定观测序列条件概率P(I∣O)最大的状态序列I=(i1,i2,…,iT),即给定观测序列,求最有可能的对应的状态序列。
概率计算之前向算法
概率计算问题计算的是在模型λ下观测序列O出现的概率P(O∣λ)。前向概率指的是:给定模型λ,定义到时刻t部分观测序列为o1,o2,…,ot 且状态为qi 的概率为前向概率。记作:αt(i)=P(o1,o2,…,ot,it=qi∣λ)