如何在MATLAB中从HMM的多序列中获得过渡和发射矩阵?

Naz*_*han 5 matlab training-data hidden-markov-models

我正在使用HMM在MATLAB中进行序列分类任务.我有13个序列及其相应的类.据我所知,hmmestimate()返回一个序列及其类的转换和发射矩阵.但我需要从所有这13个序列计算的最终转换和发射矩阵.我该怎么做 ?

mer*_*erv 1

该做什么...

一个真诚的、完全无干扰的建议是编写几个for循环来计算序列中存在的所有转换和状态发射对,然后对两个结果矩阵(转换和发射)中的行进行归一化,以便它们相加1. 这就是hmmestimate最终要做的事情,这可能就是你应该怎么做的。

也就是说,无论如何,让我们继续将方钉强行插入圆孔中......

并且,你可以做什么

如果您将序列连接在一起,那么就可以运行hmmestimate。这将给出正确的发射矩阵,但相邻序列之间的转换会扰乱转换概率。解决这个问题的一个技巧是用新的独特状态和相应的发射来增强每个序列。通过这样做,有关串联的所有信息将被归入可以丢弃的输出矩阵的子集。

例子

让我们生成一些数据,这样输入就清楚了。

% true transitions and emission probabilities
tr = [0.9 0.1; 0.05 0.95];
em = [0.9 0.1; 0.2 0.8];

num_seqs = 100;
seq_len = 100;

seqs = zeros(num_seqs,seq_len);
states = zeros(num_seqs,seq_len);

% generate some sequences
for i = 1:num_seqs
    [seqs(i,:), states(i,:)] = hmmgenerate(seq_len,tr,em);
end
Run Code Online (Sandbox Code Playgroud)

用来hmmestimate估计

请注意,MATLAB 将其状态表示为连续整数,因此我们需要使用下一个整数作为标记分隔符状态。在示例中,我们使用“3”。

% augment the sequences
seqs_aug = [3*ones(num_seqs,1) seqs];
states_aug = [3*ones(num_seqs,1) states];

% concatenate the rows, and estimate
% credit: http://stackoverflow.com/a/2731032/570918
[tr_aug,em_aug] = hmmestimate(reshape(seqs_aug.',1,[]),reshape(states_aug.',1,[]));

% subset the good parts
tr_hat = tr_aug(1:2,1:2);
em_hat = em_aug(1:2,1:2);

% renormalize
tr_hat = tr_hat./sum(tr_hat,2);
% NB: em_hat is already normalized
Run Code Online (Sandbox Code Playgroud)

rng(1)在生成上述数据之前使用,这给出

tr_hat % [0.9008 0.0992; 0.0490 0.9510]
em_hat % [0.9090 0.0910; 0.1950 0.8050]
Run Code Online (Sandbox Code Playgroud)