求助:HMM的viterbi算法

12 views
Skip to first unread message

wang peter

unread,
May 19, 2011, 2:57:47 PM5/19/11
to 群成员, advanced-mac...@googlegroups.com
哪位高手给看一下,下面的HMM的viterbi算法没错吧,谢谢
首先,需要定义HMM的数据结构,也就是HMM的五个基本要素
typedef struct
{
int N; /* 隐藏状态数目;Q={1,2,…,N} */
int M; /* 观察符号数目; V={1,2,…,M}*/
double **A; /* 状态转移矩阵A[1..N][1..N]. a[i][j] 是从t时刻状态i到t+1时刻状态j的转移概率 */
double **B; /* 发射或混淆矩阵B[1..N][1..M],b[j][k]在状态j时发射字符k的概率。*/
double *pi; /* 初始向量pi[1..N],pi[i] 是初始状态概率分布 */
} HMM;
 
void Viterbi(HMM *phmm, int T, int *O, double **delta, int **psi, int *q,double *pprob)
{
  int i, j;   /* 状态索引 */
  int t;    /* 时间索引 */
    double val; /*求局部概率时的中间值*/
  double maxval,val; /*求局部概率时的中间值的最大值 */
    int maxvalind; /*最大值对应的状态i*/
  /* 1. 初始化:计算t=1时刻所有状态的局部概率: */
  for (i = 1; i <= phmm->N; i++)
    {
    delta[1][i] = phmm->pi[i]* phmm->B[i][O[1]];
        psi[1][i] =0;
 }
  
  /* 2. 归纳:递归计算每个时间点,t=2,… ,T时的局部概率 */
  for (t = 1; t < T; t++)
  {
    for (j = 1; j <= phmm->N; j++)
    {
      maxval = 0.0;
            maxvalind = 1;
      for (i = 1; i <= phmm->N; i++)
            {
        val= delta[t][i]* (phmm->A[i][j]);
                if(val>maxval)
    {
      maxval = val;
                    maxvalind = i;
    }
            }
   delta[t+1][j] = maxval*(phmm->B[j][O[t+1]]);
            psi[t+1][j] =maxvalind;
    }
  }
  /* 3. 终止*/
  *pprob = 0.0;
    q[T]=1;
  for (i = 1; i <= phmm->N; i++)
    {
     if(delta[T][i]>*pprob)
  {
     *pprob = delta[T][i];
     q[T]=i;
  }
 }
 /* 4. 路径(状状态序列)回溯*/
 for (t = T-1; t >= 1; t--)
    q[t]=psi[t+1][q[t+1]];   
}
Reply all
Reply to author
Forward
0 new messages