隱馬爾科夫模型(HMM)學習之 viterbi算法

   viterbi算法主要解決已知HMM和觀察序列,找到最可能的隱藏狀態,也就是所說的解碼問題。解碼在語音識別中的應用就是,根據一段聲音序列,找到最有可能對應的文字序列。
html


   仍是天氣和水藻的這個例子,咱們運用viterbi算法找出dry,damp,soggy對應的天氣狀況。全部的已知條件和以前那個前向算法都是一直的,不一樣之處就是求解的過程。java


1.  根據初始機率和觀察機率,計算t=0時刻的機率值,保存在delta數組的第一列算法


2.  計算t=i 時刻(i < T)狀態j (j < M)下機率的值,選出最大的機率值maxVal,乘以觀察機率保存到delta數組 中,而後將相應的索引值保存到path數組中。數組


3.  在t = T -1時刻,選出最大的那個機率值,最大機率值保存在prob中,同時用k記下對應的行號,並將k存入list的頭部ide


4.  t從 T - 1開始循環到t=1,由於當前t時刻path數組中的值保存的是t-1時刻的行號,所以循環的取出該值,最後就是所要求的隱藏狀態的路徑了。網站



java版viterbi算法:spa

package cn.yunzhisheng.hmm;htm


import java.util.LinkedList;索引

import java.util.List;get


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};



public List<Integer> viterbi(int[] seq){

int T = seq.length;

// 保存計算的機率

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

// 保存最佳路徑

int [][] path = newint[M][T];

// 當前機率的值

double val = 0.0;

// 保存當前最大機率的值

double maxVal = 0.0;

// t-1時刻最大機率的索引

int maxIndex = 0;

// t = 0 用初始機率乘以相應觀察矩陣的機率,保存到delta的第一列中

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

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

}

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

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

maxVal = 0.0;

maxIndex= 0;

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

val = delta[i][t-1] * transferMatix[i][j];

if(val > maxVal){

// 保存最大機率

maxVal= val;

// 保存t-1時刻的索引

maxIndex = i;

}

}

// 將機率保存在delta數組中

delta[j][t] = maxVal * observationMatix[j][seq[t]];;

path[j][t] = maxIndex;

}

}

// 對最後一列,比較機率,找到最大機率的索引

double prob = 0.0;

int k = 0;

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

if(delta[j][T-1] > prob){

prob = delta[j][T-1];

k = j;

}

}

System.out.println("prob=" + prob);

LinkedList<Integer> list = new LinkedList<Integer>();

list.addFirst(k);

int row = k;

for(int t = T-1; t > 0; t--){

int v = path[row][t];

list.addFirst(v);

row = v;

}


return list;

}



publicstaticvoid main(String[] args) {

HMM hmm = new HMM();

// 觀察序列

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

// 前向算法

//double p = hmm.forward(seq);

//System.out.println(p);

// 維特比算法

List<Integer> weather = hmm.viterbi(seq);

System.out.println(weather);

}

}


運行結果:

prob=0.01107421875

[0, 1, 2]


即最終的隱藏狀態是:sunny,cloudy,rainy


注:http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/viterbi_algorithm/s3_pg3.html 這個網站計算有問題,它把狀態矩陣給弄反了


個人計算結果和 umdhmm是同樣的,同時手工計算的也是這個結果。

相關文章
相關標籤/搜索