通常使用前向算法解決評估問題。所謂評估問題就是,已知一個HMM,還有一個觀察序列,求在這個HMM下這個觀察序列的機率。java
咱們仍是舉那個天氣海藻的例子。假定初始機率PI,轉移矩陣A,觀察矩陣B都已知了,咱們如今有一個觀察序列:dry,damp,soggy,求p(dry, damp, soggy | HMM)的機率。算法
咱們先列出已知的參數:數組
有三個隱藏狀態:sunny,cloudy,rainyide
狀態轉移矩陣:spa
yesterday |
|
||||
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
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