维特比算法质量差(HMM)

问题描述 投票:3回答:1

最近,我一直在尝试研究隐马尔可夫模型和Viterbi算法。我找到了一个名为hmmlearn(http://hmmlearn.readthedocs.io/en/latest/tutorial.html)的库,以帮助我为两个状态(具有高斯发射)生成一个状态序列。然后,我想使用Viterbi重新确定状态序列。我的代码有效,但是可以预测大约5%的状态错误(取决于高斯发射的均值和方差)。 hmmlearn库具有.predict方法,该方法也使用Viterbi确定状态序列。

我现在的问题是,hmmlearn的Viterbi算法比我的手写算法好得多(错误率低于5%,而我的5%)。我在代码中找不到任何重大问题,所以我不确定为什么会这样。下面是我的代码,在该代码中,我首先生成状态和观测序列Z和X,使用hmmlearn预测Z,最后使用我自己的代码预测Z:

# Import libraries
import numpy as np
import scipy.stats as st
from hmmlearn import hmm

# Generate a sequence
model = hmm.GaussianHMM(n_components = 2, covariance_type = "spherical")
model.startprob_ = pi
model.transmat_ = A
model.means_ = obs_means
model.covars_ = obs_covars

X, Z = model.sample(T)

## Predict the states from generated observations with the hmmlearn library
Z_pred = model.predict(X)

# Predict the state sequence with Viterbi by hand
B = np.concatenate((st.norm(mean_1,var_1).pdf(X), st.norm(mean_2,var_2).pdf(X)), axis = 1)
delta = np.zeros(shape = (T, 2))
psi = np.zeros(shape= (T, 2))

### Calculate starting values
for s in np.arange(2):
    delta[0, s] = np.log(pi[s]) + np.log(B[0, s])
    psi = np.zeros((T, 2))

### Take everything in log space since values get very low as t -> T
for t in range(1,T):
    for s_post in range(0, 2):
        delta[t, s_post] = np.max([delta[t - 1, :] + np.log(A[:, s_post])], axis = 1) + np.log(B[t, s_post])
        psi[t, s_post] = np.argmax([delta[t - 1, :] + np.log(A[:, s_post])], axis = 1)

### Backtrack
states = np.zeros(T, dtype=np.int32)
states[T-1] = np.argmax(delta[T-1])

for t in range(T-2, -1, -1):
    states[t] = psi[t+1, states[t+1]]

我不确定代码中是否存在重大错误,或者hmmlearn是否仅使用更完善的Viterbi算法。通过观察错误预测的状态,我已经注意到,排放概率B的影响似乎太大,因为即使导致转移到另一个状态的概率非常低,它也会导致状态变化太频繁。

我是python的新手,请原谅我难看的代码。预先感谢您提供的任何提示!

编辑:如您在代码中所见,我很愚蠢,使用方差而不是标准差来确定排放概率。解决此问题后,我得到的结果与已实施的Viterbi算法相同。

python hidden-markov-models hmmlearn viterbi
1个回答
0
投票

您是否解决了您提到的错误?我也有同样的问题,如果您分享您的发现,我将不胜感激。

© www.soinside.com 2019 - 2024. All rights reserved.