隱馬爾可夫模型(四)——隱馬爾可夫模型的評估問題(后向算法)


對於HMM的評估問題,利用動態規划可以用前向算法,從前到后算出前向變量;也可以采用后向算法,從后到前算出后向變量。

先介紹后向變量βt(i):給定模型μ=(A,B,π),並且在時間 時刻t 狀態為si 的前提下,輸出序列為Ot+1Ot+2...OT的概率,即

                                    βt(i)=P(Ot+1Ot+2...OT|qt=si,μ)

歸納過程

    假設仍然有3個狀態

                 

    當t=T時,按照定義:時間t  狀態q輸出為OT+1......的概率,從T+1開始的輸出是不存在的(因為T時刻是終止終止狀態),即T之后是空,是個必然事件,因此βt(i)=1,1≤1≤N

    當t=T-1時,

                          

                 βT-1(i)=P(OT|qT-1=si,μ) = ai1*b1(OT)*βT(1)  +  ai2*b2(OT)*βT(2)  +  ai3*b3(OT)*βT(3)

      ......

    當t=1時,

       β1(1)=P(O2O3...OT|q2=s1,μ) = a11*b1(O2)*β2(1) + a12*b2(O2)*β2(2) + a13*b3(O2)*β2(3)

       β1(2)=P(O2O3...OT|q2=s1,μ) = a21*b1(O2)*β2(1) + a22*b2(O2)*β2(2) + a23*b3(O2)*β2(3)

       β1(3)=P(O2O3...OT|q2=s1,μ) = a31*b1(O2)*β2(1) + a32*b2(O2)*β2(2) + a33*b3(O2)*β2(3)

       P(O1O2...OT|μ) =   

                             =  

                             =  

后向算法

    step1 初始化:βT(i)=1, 1≤1≤N

    step2 歸納計算:

                       1≤t≤T-1, 1≤i≤N

    step3 求終結和:

                   P(O|μ)=  

時間復雜度

    計算某時刻在某個狀態下的后向變量需要看后一時刻的N個狀態,此時時間復雜度為O(N),每個時刻有N個狀態,此時時間復雜度為N*O(N)=O(N2),又有T個時刻,所以時間復雜度為T*O(N2)=O(N2T)。

程序例證

             

后向算法

    計算P(O|M):

    step1:β4(1) = 1          β4(2) = 1          β4(3) = 1

    step2:β3(1) = β4(1)*a11*b1(white) + β4(2)*a12*b2(white) + β4(3)*a13*b3(white)

                     ...

    step3:P(O|M) = π11(1)*b1(O1) + π21(2)*b2(O1) + π31(3)*b3(O1)

程序代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
        float a[3][3] = {{0.5,0.2,0.3},{0.3,0.5,0.2},{0.2,0.3,0.5}};
        float b[3][2] = {{0.5,0.5},{0.4,0.6},{0.7,0.3}};
        float result[4][3];
        int list[4] = {0,1,0,1};
        result[3][0] = 1;
        result[3][1] = 1;
        result[3][2] = 1;
        int i,j,k, count = 3;
        for (i=2; i>=0; i--)
        {
            for(j=0; j<=2; j++)
            {
                result[i][j] = 0;
                for(k=0; k<=2; k++)
                {
                   result[i][j] += result[i+1][k] * a[j][k] * b[k][list[count]];
                }
            }
            count -= 1;
        }
       for (i=0; i<=3; i++)
        {
            for(j=0; j<=2; j++)
            {
                printf("b[%d][%d] = %f\n",i+1,j+1,result[i][j]);

            }
        }
        printf("backward:%f\n", result[0][0]*0.2*0.5+result[0][1]*0.4*0.4+result[0][2]*0.4*0.7);
        return 0;
}

運行結果

             


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM