隐马尔可夫模型问题有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
请按任意键继续...
原文地址:http://51jishurensheng.blog.51cto.com/10626705/1686733