隐马尔可夫模型:hmmlearn库的使用

hmmlearn库的使用

安装和使用

hmmlearn 一共实现了三种HMM模型类,按照数据的观测状态是离散的还是连续的可以划分为两类。GaussianHMM (高斯HMM模型)和GMMHMM(混合高斯模型)是观测状态为连续的模型。 MultinomialHMM(多项式分布HMM模型)是观测状态为离散的模型。这三种算法都可以被用来估计模型的参数。
Hmmlearn以前是scikit-learn项目中的一部分,现在已经是一个单独的python包,可以在安装好python的基础上,直接使用下述命令进行安装。

pip install hmmlearn

安装好对应的hmmlearn库之后,我们可以直接在python代码中进行导入。

from hmmlearn import hmm

⾼斯HMM模型

高斯HMM模型指的是假定序列的观测状态是符合高斯分布的。 隐藏状态的初始分布为 π {\boldsymbol{\pi}} π ,对应的参数为“startprob_”。 A {\bf{A}} A是隐藏状态转移概率矩阵,对应的参数为“transmat_”, 但是由于此时的观测状态是连续值, 因此无法直接给出观测状态概率矩阵 B {\bf{B}} B ,仅仅可以给出不同隐藏状态相对应的概率密度函数的参数。我们使用 Σ {\bf{\Sigma }} Σ表示服从高斯分布的协方差矩阵,使用 μ {\boldsymbol{\mu}} μ表示服从高斯分布的期望向量。在hmmlearn对应的GaussianHMM中, “covars”表示 Σ {\bf{\Sigma }} Σ ,“means”表示不同隐藏状态对应的 μ {\boldsymbol{\mu}} μ形成的矩阵。

1.	import numpy as np
2.	from hmmlearn import hmm  
3.	startprob = np.array([0.6, 0.3, 0.1, 0.0])  
4.	# The transition matrix, note that there are no transitions possible  
5.	# between component 1 and 3  
6.	transmat = np.array([[0.7, 0.2, 0.0, 0.1],  
7.	                     [0.3, 0.5, 0.2, 0.0],  
8.	                     [0.0, 0.3, 0.5, 0.2],  
9.	                     [0.2, 0.0, 0.2, 0.6]])  
10.	# The means of each component  
11.	means = np.array([[0.0,  0.0],  
12.	                  [0.0, 11.0],  
13.	                  [9.0, 10.0],  
14.	                  [11.0, -1.0]]) 
15.	# The covariance of each component  
16.	covars = .5 * np.tile(np.identity(2), (4, 1, 1))  
17.	  
18.	# Build an HMM instance and set parameters  
19.	model3 = hmm.GaussianHMM(n_components=4, covariance_type="full")  
20.	
21.	# Instead of fitting it from the data, we directly set the estimated  
22.	# parameters, the means and covariance of the components  
23.	model3.startprob_ = startprob  
24.	model3.transmat_ = transmat  
25.	model3.means_ = means  
26.	model3.covars_ = covars 

注意代码中的一个参数covariance_type,如果取值是“spherical”,那么 Σ {\bf{\Sigma }} Σ的非对角线元素的取值为0,并且对角线元素是相同的。 如果取值是“diag”则 Σ {\bf{\Sigma }} Σ的非对角元素的取值是0, 但对角线元素可以不同, “tied”表示隐藏状态所对应的观测状态的分布使用的 Σ {\bf{\Sigma }} Σ是相同的。 可以通过上述代码,进行三维比特算法的解码过程。由于上述案例使用的是三维观测序列,所以这里需要输入三行两列的矩阵,代码如下:

1.	seen = np.array([[1.1,2.0],[-1,2.0],[3,7]])  
2.	logprob, state = model3.decode(seen, algorithm="viterbi")  
3.	print(state)  

得到的结果为:
[0 0 1]

混合⾼斯分布HMM模型

对比高斯HMM模型, 混合高斯分布的HMM模型指假定序列的观测状态是符合混合高斯分布的,即混合模型,模型是符合高斯分布的。一般情况下,我们通常假定观测序列的状态是符合混合高斯分布的。他的大部分参数和GaussianHMM是一样的,因此在这里不做过的讲解。

1.	hmmlearn.hmm.GMMHMM(n_components=1,n_mix=1,startprob_prior=1.0,
2.	transmat_prior=1.0, covariance_type='diag', covars_prior=0.01, algorithm='viterbi', 
3.	random_state=None,n_iter=10,tol=0.01, verbose=False, params='stmcw',init_params='stmcw') 

对于GMMHMM与GuassianHMM中的不点主要有一下两个:
n_mix: 参数值表示的意思是混合高斯分布中,高斯分布的数量。如果n_min的取值为1,那么,GMMHMM退化为GaussianHMM模型。
means_prior, means_weight, covar_prior, covars_weight: 虽然参数的名称与GaussianHMM是相同的,但是他的维度数会因为n_mix的取值而改变。

多项式分布HMM模型

多项式分布HMM模型的使用是比较简单的,隐藏状态的初始分布为 π \boldsymbol{\pi} π,对应的参数为“startprob_”。 A {\bf{A}} A是隐藏状态转移概率矩阵,对应的参数为“transmit_” , B {\bf{B}} B是观测状态概率矩阵,对应的参数为“emissionprob_”。可以被用来解决HMM模型的解码问题和预测问题。对应于4.2节中求最可能的隐藏状态序列,我们使用hmmlearn库来进行求解。

1.	import numpy as np
2.	from hmmlearn import hmm  
3.	states = ["box 1", "box 2", "box3"]  
4.	n_states = len(states)  
5.	observations = ["red", "white"]  
6.	n_observations = len(observations)  
7.	pi = np.array([0.2, 0.4, 0.4])  
8.	A = np.array([  
9.	  [0.5, 0.2, 0.3],  
10.	  [0.3, 0.5, 0.2],  
11.	  [0.2, 0.3, 0.5]  
12.	])  
13.	 B = np.array([  
14.	  [0.5, 0.5],  
15.	  [0.4, 0.6],  
16.	  [0.7, 0.3]  
17.	])  
18.	model = hmm.MultinomialHMM(n_components=n_states)  
19.	model.startprob_= pi  
20.	model.transmat_= A  
21.	model.emissionprob_= B  
22.	seen_observe = np.array([[0,1,0]]).T  
23.	logprob, box = model.decode(seen_observe, algorithm="viterbi")  
24.	print("已知观测序列", ", ".join(map(lambda x: observations[x], seen_observe[:,0])))  
25.	print("最优隐藏状态", ", ".join(map(lambda x: states[x], box)))

对于多项式分布的HMM模型,也可以使用predict函数,预测结果是一样的,如下所示:

1.	box2 = model.predict(seen_observe)  
2.	print("已知观测序", ", ".join(map(lambda x: observations[x], seen_observe[:,0])))  
3.	print("最优隐藏状态", ", ".join(map(lambda x: states[x], box2)))  

上述结果与我们在HMM模型实例中给出的手动计算结果是一样的(参考其它隐马尔可夫模型博客给出)。

你可能感兴趣的:(人工智能,自然语言处理,人工智能,算法)