隱馬爾可夫模型的forward算法的c實現

    

    隱馬爾可夫模型問題有3個,即評估、解碼、學習。其中評估問題描述爲給定一個隱馬爾可夫模型參數和一個觀察序列,求該觀察序列的概率。我們使用前向算法(forward algorith)來解決這個問題。其c代碼如下:

hmm.h文件


#ifndef _HMM_H_

#define _HMM_H_


//宏定義

#define NN 3

#define MM 4

#define length 3


typedef struct {

int N;  /* 隱藏狀態數目;Q={0,1,2,…,N-1} */

int M; /* 觀察符號數目; V={0,1,2,…,M-1}*/


/* 狀態轉移矩陣A[0..NN-1][0..NN-1]. a[i][j] 是從t時刻狀態i到t+1時刻狀態j的轉移概率 */

double(*A)[NN] ;  


/* 混淆矩陣B[0..N-1][0..M-1]. b[j][k]在狀態j時觀察到符合k的概率。*/

double(*B)[MM];


/* 初始向量pi[0..N-1],pi[i] 是初始狀態概率分佈 */

double*pi;

} HMM;


double Forward(HMM *phmm,int T,int *O);


#endif



hmm.c文件

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include "hmm.h"

/*
 函數參數說明:
 *phmm:已知的HMM模型;T:觀察符號序列長度;*O:觀察序列;
*/
double alpha[length][NN];     //前向算法局部概率變量

double Forward(HMM *phmm,int T,int *O)
{
       int     i, j;     /* 狀態索引 */
       int     t;        /* 時間索引 */
double sum;     /*求局部概率時的中間值 */  
double pprob;//返回的值

 /* 1. 初始化:計算t=0時刻所有狀態的局部概率alpha: */
       for (i = 0; i <= (phmm->N)-1; i++)
               alpha[0][i] = phmm->pi[i]* phmm->B[i][O[0]];

         /* 2. 歸納:遞歸計算每個時間點,t=2,… ,T時的局部概率 */

       for (t = 0; t < T-1; t++) //這循環裏算T-1次,前面初始化算了1次,共T次
{
               for (j = 0; j <= (phmm->N)-1; j++) //在給定的時刻,所有狀態分別到其他所有狀態的轉移概率之和
{
                       sum = 0.0;
                       for (i = 0; i <= (phmm->N)-1; i++)//在給定的時刻和給定狀態,其他所有狀態到給定狀態的轉移概率之和
{
sum += alpha[t][i]* (phmm->A[i][j]);
}                                
                       alpha[t+1][j] = sum*(phmm->B[j][O[t+1]]);//計算t+1時刻看到觀察序號O[t+1]的所有狀態的局部概率alpha
               }
       }

        /* 3. 終止:觀察序列的概率等於T時刻所有局部概率之和*/
       pprob = 0.0;
       for (i = 0; i <= (phmm->N)-1; i++)
               pprob += alpha[T-1][i];
return pprob;
}

main.c文件

#include <stdio.h>
#include <stdlib.h>
#include "hmm.h"

double A[NN][NN]={              
                {0.500,0.375,0.125},
    {0.250,0.125,0.625},
    {0.250,0.375,0.375}
              };
double B[NN][MM]={              
                  {0.60,0.20,0.15,0.05},
          {0.25,0.25,0.25,0.25},
          {0.05,0.10,0.35,0.50}
               };
double pi[NN]={0.63,0.17,0.20};

HMM hmm1={NN,MM,A,B,pi};

int Seq[length]={0,2,3};

int main(int argc, char *argv[])
{  
 double pprob=0.0;
     pprob = Forward(&hmm1, length, Seq);
 printf("the probabilty of observing a sequence given a HMM model parameter:\n");
 printf("%.12f\n",pprob);
}


運行結果如下:

the probabilty of observing a sequence given a HMM model parameter:

0.026901406250

請按任意鍵繼續...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章