隱馬爾可夫模型問題有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
請按任意鍵繼續...