hmmlearn 一共实现了三种HMM模型类,按照数据的观测状态是离散的还是连续的可以划分为两类。GaussianHMM (高斯HMM模型)和GMMHMM(混合高斯模型)是观测状态为连续的模型。 MultinomialHMM(多项式分布HMM模型)是观测状态为离散的模型。这三种算法都可以被用来估计模型的参数。
Hmmlearn以前是scikit-learn项目中的一部分,现在已经是一个单独的python包,可以在安装好python的基础上,直接使用下述命令进行安装。
pip install hmmlearn
安装好对应的hmmlearn库之后,我们可以直接在python代码中进行导入。
from hmmlearn import 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模型指假定序列的观测状态是符合混合高斯分布的,即混合模型,模型是符合高斯分布的。一般情况下,我们通常假定观测序列的状态是符合混合高斯分布的。他的大部分参数和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模型的使用是比较简单的,隐藏状态的初始分布为 π \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模型实例中给出的手动计算结果是一样的(参考其它隐马尔可夫模型博客给出)。