隐马尔可夫模型(二)--- viterbi算法

2. 根据可观察序列找到最可能的隐藏状态序列

 

需要理解的是这样的一个过程跟混淆矩阵所代表的一个过程的区别在于哪里?

混淆矩阵是我知道当前的海藻状态是dry,要得到当前可能的天气状况需要乘以混淆矩阵。

但是根据可观察序列找到最可能的隐藏状态序列不是由观察状态得到隐藏状态,而是由一个观察状态序列得到隐藏状态序列。目标是序列。

 

2.1.穷举搜索

            

可观察的序列已经给出(dry->damp->soggy),寻找最可能的隐藏序列就是找出上面说有可能路径中概率最大的。所以需要计算每一个路径的概率。

 

需要用到HMM中的状态转移矩阵。这种方法是可行,但是计算的代价很高。

 

2.2.使用递归降低复杂度

与之前的前向算法一样,先计算部分概率,然后在计算剩下的概率。与前向算法不同的是在t时刻最可能到达的某个状态的一条路径的概率,而不是所有的概率之和。

 

每一个状态都存在一个概率最大的路径,这个路径是最优路径。称之为部分最优路径,概率称之为部分概率。对于每一个时刻的每一个状态都存在这样一个路径和这样一个概率。

最后需要的得到的是t=T时刻的每一个状态的部分最优路径和这个路劲的部分概率。选择概率最大的状态的部分最优路径便是全局的最优路径。

 

1.初始状态t=1时刻部分概率

  这个时候不存路径,所以需要初始状态概率π={πi}乘以混淆矩阵。

                                                                                

 

2.计算t>1时刻的部分概率

采用的是递归的计算方法,所以在计算t时刻的部分概率,只需要知道t-1时刻的部分概率。

                                                              

 

计算所有到状态X的概率,找到其中最可能的路径,只可能是下列三种路径之一。

1.(状态序列),. . .,A,X

2.(状态序列),. . .,B,X

3.(状态序列),. . .,C,X

 

计算公式:Pr (到达A的最优路径) . Pr (X | A) . Pr (观察状态 | X)

                          

 

Pr(it-1):t-1时刻某一状态的部分概率

Pr(X|i):t时刻在t-1时刻状态为i的条件下,状态为x的概率。也就是HMM中的状态转移矩阵。

Pr(observationt |X):t时刻的观察状态在隐藏状态为x条件下的概率,也就是HMM中的混淆矩阵。

 

于是得到下列公式:

                                                                     

 

2.3后向指针

通过之前的过程,得出的是最优路径的概率,但是最优的路径是怎样的,还是不清楚,我们需要一个方法得到最优路径的每一个节点,这便需要用到后向指针。

                                                              

 

δt-1 (j):t-1时刻状态为j的最优概率

aij :由状态t-1时刻的状态j转移到t时刻状态i的状态转移概率

Argmaxj(δt-1 (j)aij ):找出t-1时刻的所有的状态转移到t时刻状态i的最大的值,便对应着最优路径节点。

 

 

 

2.4在matlab中使用viterbi算法

TRANS = [0.50 0.375 0.125;0.25 0.125 0.625;0.25 0.375 0.375];
EMIS = [0.60 0.20 0.15 0.05;0.25 0.25 0.25 0.25;0.05 0.10 0.35 0.50];
%seq是输出序列  
%States是状态序列
%[seq,states]=hmmgenerate(10,TRANS,EMIS);
seq = [1 1 1 1 2 3 1 1 1 1 ];
%函数hmmviterbi使用Viterbi算法计算模型给定输出序列seq最有可能通过的状态序列

 

viterbi算法解析

 

[currentState,logP] = hmmviterbi(seq,TRANS,EMIS);

numStates = size(tr,1);
checkTr = size(tr,2);
%判断是否是方阵
if checkTr ~= numStates
    error(message('stats:hmmviterbi:BadTransitions'));
end
 
% number of rows of e must be same as number of states
 
checkE = size(e,1);
%判断是否是方阵
if checkE ~= numStates
    error(message('stats:hmmviterbi:InputSizeMismatch'));
end
 
numEmissions = size(e,2);
customStatenames = false;
 
% deal with options
if nargin > 3
    okargs = {'symbols','statenames'};
    [symbols,statenames] = ...
        internal.stats.parseArgs(okargs, {[] []}, varargin{:});
    
    if ~isempty(symbols)
        numSymbolNames = numel(symbols);
        if ~isvector(symbols) || numSymbolNames ~= numEmissions
            error(message('stats:hmmviterbi:BadSymbols'));
        end
        [~, seq]  = ismember(seq,symbols);
        if any(seq(:)==0)
            error(message('stats:hmmviterbi:MissingSymbol'));
        end
    end
    if ~isempty(statenames)
        numStateNames = length(statenames);
        if numStateNames ~= numStates
            error(message('stats:hmmviterbi:BadStateNames'));
        end
        customStatenames = true;
    end
end
 
L = length(seq);
%判断输出序列是否有误,是否小于最小值,是否大于最大值(状态空间的个数),是否存在小数
if any(seq(:)<1) || any(seq(:)~=round(seq(:))) || any(seq(:)>numEmissions)
     error(message('stats:hmmviterbi:BadSequence', numEmissions));
end
%创建一个新的序列
currentState = zeros(1,L);
if L == 0
    return
end
%取对数
%为什么这里取对数,因为对数中的加法运算,相当于计算公式中的乘法运算
logTR = log(tr);
logE = log(e);
 
 
pTR = zeros(numStates,L);
%假设模型出于第0步的状态1
%创建一个矩阵,所有元素都为-Inf
v = -Inf(numStates,1);
 
v(1,1) = 0;
vOld = v;
 
%前一步状态为inner
%后一步状态法为states
for count = 1:L
    for state = 1:numStates
        % for each state we calculate
        % v(state) = e(state,seq(count))* max_k(vOld(:)*tr(k,state));
        bestVal = -inf;
        bestPTR = 0;
        % use a loop to avoid lots of calls to max
 
        for inner = 1:numStates 
            val = vOld(inner) + logTR(inner,state);
            if val > bestVal
                bestVal = val;
                %保存前一步状态,在后来的后向指针算法中要用到
                bestPTR = inner;
            end
        end
        %保存最大的状态转移概率
        % save the best transition information for later backtracking
        pTR(state,count) = bestPTR;
        % update v
        %取出混淆矩阵中状态为state,输出为seq(count)的元素
        v(state) = logE(state,seq(count)) + bestVal;
    end
    vOld = v;
end
 
%得出最优路径的概率和最终的状态
[logP, finalState] = max(v);
 
%下面要使用后向指针
currentState(L) = finalState;
for count = L-1:-1:1
    currentState(count) = pTR(currentState(count+1),count+1);
    if currentState(count) == 0
        error(message('stats:hmmviterbi:ZeroTransitionProbability', currentState( count + 1 )));
    end
end
 
if customStatenames
    currentState = reshape(statenames(currentState),1,L);
end

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CHAO_^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值