我在尝试使用Kevin Murphy的HMM工具箱时遇到了困难,工具箱。如果有使用过该工具箱的朋友能解答一些概念上的问题,将会对我帮助很大。我已经基本理解了HMM背后的理论,但如何实际实现和设置所有参数让我感到困惑。
我们有两个类别,因此需要两个HMM。假设训练向量是:class1 O1={4 3 5 1 2} 和 class O_2={1 4 3 2 4}。现在,系统需要将未知序列 O3={1 3 2 4 4} 分类为class1或class2。
- obsmat0 和 obsmat1 里应该填什么内容?
- 如何指定/语法设置转移概率 transmat0 和 transmat1?
- 在这种情况下,变量 data 是什么?
- 由于使用了五个独特的数字/符号,状态数 Q 是否为5?
- 输出符号数是否为5?
- 如何指定转移概率 transmat0 和 transmat1?
回答:
与其逐一回答每个问题,不如让我通过一个例子——通常在介绍隐马尔可夫模型时使用的天气例子,来演示如何使用HMM工具箱。
模型的状态是三种可能的天气类型:晴天、雨天和雾天。我们假设在任何一天,天气只能是这三种状态之一。因此,HMM的状态集是:
S = {sunny, rainy, foggy}
然而,在这个例子中,我们无法直接观察到天气(显然我们被锁在地窖里!)。我们唯一的证据是每天来看望我们的人是否带了伞。在HMM术语中,这些是离散的观察:
x = {umbrella, no umbrella}
HMM模型由三件事特征化:
- 先验概率:序列第一个状态的概率向量。
- 转移概率:描述从一种天气状态转移到另一种天气状态的概率矩阵。
- 发射概率:描述给定状态(天气)下观察到输出(带伞或不带伞)的概率矩阵。
接下来,我们要么被给定这些概率,要么需要从训练集中学习这些概率。一旦完成,我们就可以进行推理,例如计算观察序列相对于HMM模型(或一组模型,并选择最可能的一个)的似然性…
1) 已知模型参数
这里是一个示例代码,展示如何填充现有的概率来构建模型:
Q = 3; %# number of states (sun,rain,fog)O = 2; %# number of discrete observations (umbrella, no umbrella)%# prior probabilitiesprior = [1 0 0];%# state transition matrix (1: sun, 2: rain, 3:fog)A = [0.8 0.05 0.15; 0.2 0.6 0.2; 0.2 0.3 0.5];%# observation emission matrix (1: umbrella, 2: no umbrella)B = [0.1 0.9; 0.8 0.2; 0.3 0.7];
然后我们可以从这个模型中采样一组序列:
num = 20; %# 20 sequencesT = 10; %# each of length 10 (days)[seqs,states] = dhmm_sample(prior, A, B, num, T);
例如,第5个样例是:
>> seqs(5,:) %# observation sequenceans = 2 2 1 2 1 1 1 2 2 2>> states(5,:) %# hidden states sequenceans = 1 1 1 3 2 2 2 1 1 1
我们可以评估序列的对数似然性:
dhmm_logprob(seqs(5,:), prior, A, B)dhmm_logprob_path(prior, A, B, states(5,:))
或者计算维特比路径(最可能的状态序列):
vPath = viterbi_path(prior, A, multinomial_prob(seqs(5,:),B))
2) 未知模型参数
训练使用EM算法进行,最好使用一组观察序列来完成。
继续上面的例子,我们可以使用上面生成的数据来训练一个新模型,并将其与原始模型进行比较:
%# we start with a randomly initialized modelprior_hat = normalise(rand(Q,1));A_hat = mk_stochastic(rand(Q,Q));B_hat = mk_stochastic(rand(Q,O)); %# learn from data by performing many iterations of EM[LL,prior_hat,A_hat,B_hat] = dhmm_em(seqs, prior_hat,A_hat,B_hat, 'max_iter',50);%# plot learning curveplot(LL), xlabel('iterations'), ylabel('log likelihood'), grid on
请记住,状态顺序不必匹配。这就是为什么在比较两个模型之前我们需要对状态进行排列。在这个例子中,训练后的模型看起来与原始模型非常接近:
>> p = [2 3 1]; %# states permutation>> prior, prior_hat(p)prior = 1 0 0ans = 0.97401 7.5499e-005 0.02591>> A, A_hat(p,p)A = 0.8 0.05 0.15 0.2 0.6 0.2 0.2 0.3 0.5ans = 0.75967 0.05898 0.18135 0.037482 0.77118 0.19134 0.22003 0.53381 0.24616>> B, B_hat(p,[1 2])B = 0.1 0.9 0.8 0.2 0.3 0.7ans = 0.11237 0.88763 0.72839 0.27161 0.25889 0.74111
使用隐马尔可夫模型可以做更多的事情,例如分类或模式识别。你会有属于不同类别的不同观察序列集。你从训练每个集合的模型开始。然后给定一个新的观察序列,你可以通过计算其相对于每个模型的似然性来进行分类,并预测具有最高对数似然性的模型。
argmax[ log P(X|model_i) ] over all model_i