隐马尔科夫模型(HMM)学习之 前向算法

   通常使用前向算法解决评估问题。所谓评估问题就是,已知一个HMM,还有一个观察序列,求在这个HMM下这个观察序列的几率。java


   咱们仍是举那个天气海藻的例子。假定初始几率PI,转移矩阵A,观察矩阵B都已知了,咱们如今有一个观察序列:dry,damp,soggy,求p(dry, damp, soggy | HMM)的几率。算法


咱们先列出已知的参数:数组


有三个隐藏状态:sunny,cloudy,rainyide


状态转移矩阵:spa

weather
yesterday
weather today

Sunny Cloudy Rainy
Sunny 0.500 0.375 0.125
Cloudy 0.250 0.125 0.625
Rainy 0.250 0.375 0.375



有四个观察状态:dry,dryish,damp,soggyblog


观察矩阵:get

hidden
states
observed states

Dry Dryish Damp Soggy
Sunny 0.60 0.20 0.15 0.05
Cloudy 0.25 0.25 0.25 0.25
Rainy 0.05 0.10 0.35 0.50


初始几率PI:it

Sunny 0.63
Cloudy 0.17
Rainy 0.20



已知的观察序列:dry,damp,soggyio

显然有3个观察时刻,假定t=0观察到 dry, t=1 观察到damp, t=2 观察到 soggytable


前向算法步骤:


1、 根据初始几率PI,观察矩阵,计算t=0时刻,p( dry(t=0) | (sunny, cloudy, rainy))的值,同时把计算出来的值保存到alpha这个二维数组中。


//  t=0    dry | sunny

alpha[0][0] = PI[0] * p(dry | sunny) = 0.63 * 0.60 = 0.378


// t=0    dry | cloudy

alpha[1][0] = PI[1] * p(dry | cloudy) = 0.17 * 0.25 = 0.0425


// t=0    dry | rainy

alpha[2][0] = PI[2] * p(dry | rainy) = 0.20 * 0.05 = 0.01



2、计算t=(i < T)的几率,保存到alpha数组


能够用下面的公式来归纳

其中,a表示转移矩阵,b表示观察矩阵,t表示当前观察序列的时刻,n表示的是有多少个隐藏状态。



3、当计算到最后一个时刻时,将最后这个时刻下三个状态的几率相加。


前向算法java代码以下:


package cn.yunzhisheng.hmm;


publicclass HMM {


publicint         M = 3;

// 转移矩阵

publicdouble[][] transferMatix = {

{0.500, 0.375, 0.125},

{0.250, 0.125, 0.625},

{0.250, 0.375, 0.375}

};

// 观察矩阵

publicdouble[][] observationMatix = {

{0.60, 0.20, 0.15, 0.05},

{0.25, 0.25, 0.25, 0.25},

{0.05, 0.10, 0.35, 0.50}

};

// 初始几率

publicdouble[] pi = {0.63, 0.17, 0.20};

// 前向算法

publicdouble forward(int[] seq){

// 保存中间计算结果的alpha矩阵

int T = seq.length;

double [][] alpha = newdouble[M][T];

double sum = 0.0;

double prob = 0.0;


// t = 0   用初始几率乘以相应观察矩阵的几率,保存到alpha的第一列中

for(int j = 0; j < M; j++){

   alpha[j][0] = pi[j] * observationMatix[j][seq[0]];

}


// 从t=1循环计算带T-1

for(int t = 1; t < T; t++){

// t时刻  M个隐藏状态

   for(int j = 0; j < M; j++){

   sum = 0.0;

       for(int i = 0; i < M; i++){

           // 根据t-1时刻的值 乘以转移矩阵的几率 获得t时刻的几率,而后将全部隐藏状态的几率相加

           sum += alpha[i][t-1] * transferMatix[i][j];

       }

     // sum 乘以 观察矩阵的几率  保存到alpha[j][t] 数组中

   alpha[j][t] = sum * observationMatix[j][seq[t]];

   }

}

// t = T-1 已是最后一个时刻,将3个状态的几率相加

for(int j = 0; j < M; j++){

prob += alpha[j][T-1];

}


return prob;

}



publicstaticvoid main(String[] args) {

HMM hmm = new HMM();

// 观察序列

int [] seq = {0, 2, 3};

// 前向算法

double p = hmm.forward(seq);

System.out.println(p);

}

}



计算出来的结果是:

0.026901406250000003

相关文章
相关标签/搜索