隐马尔科夫模型(HMM)学习之 前向算法
2013-06-16 15:39
441 查看
一般使用前向算法解决评估问题。所谓评估问题就是,已知一个HMM,还有一个观察序列,求在这个HMM下这个观察序列的概率。
我们还是举那个天气海藻的例子。假定初始概率PI,转移矩阵A,观察矩阵B都已知了,我们现在有一个观察序列:dry,damp,soggy,求p(dry, damp, soggy | HMM)的概率。
我们先列出已知的参数:
有三个隐藏状态:sunny,cloudy,rainy
状态转移矩阵:
有四个观察状态:dry,dryish,damp,soggy
观察矩阵:
初始概率PI:
已知的观察序列:dry,damp,soggy
显然有3个观察时刻,假定t=0观察到 dry, t=1 观察到damp, t=2 观察到 soggy
前向算法步骤:
一、 根据初始概率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
二、计算t=(i < T)的概率,保存到alpha数组
可以用下面的公式来概括
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/10/cc1ff6a82ab2fa59a94f053526f367fa.gif)
其中,a表示转移矩阵,b表示观察矩阵,t表示当前观察序列的时刻,n表示的是有多少个隐藏状态。
三、当计算到最后一个时刻时,将最后这个时刻下三个状态的概率相加。
前向算法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-1for(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
本文出自 “移动开发” 博客,请务必保留此出处http://ikinglai.blog.51cto.com/6220785/1223070
我们还是举那个天气海藻的例子。假定初始概率PI,转移矩阵A,观察矩阵B都已知了,我们现在有一个观察序列:dry,damp,soggy,求p(dry, damp, soggy | HMM)的概率。
我们先列出已知的参数:
有三个隐藏状态:sunny,cloudy,rainy
状态转移矩阵:
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 |
观察矩阵:
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 |
Sunny | 0.63 |
---|---|
Cloudy | 0.17 |
Rainy | 0.20 |
显然有3个观察时刻,假定t=0观察到 dry, t=1 观察到damp, t=2 观察到 soggy
前向算法步骤:
一、 根据初始概率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
二、计算t=(i < T)的概率,保存到alpha数组
可以用下面的公式来概括
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/10/cc1ff6a82ab2fa59a94f053526f367fa.gif)
其中,a表示转移矩阵,b表示观察矩阵,t表示当前观察序列的时刻,n表示的是有多少个隐藏状态。
三、当计算到最后一个时刻时,将最后这个时刻下三个状态的概率相加。
前向算法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-1for(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
本文出自 “移动开发” 博客,请务必保留此出处http://ikinglai.blog.51cto.com/6220785/1223070
相关文章推荐
- HMM学习最佳范例五:前向算法2
- HMM模型学习之Forward算法
- HMM学习笔记_2(从一个实例中学习HMM前向算法)
- 隐马尔科夫模型(HMM)——工作学习中的一点体会
- HMM学习最佳范例五:前向算法3
- 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数
- HMM学习最佳范例四:隐马尔科夫模型
- 隐马尔科夫模型(HMM)学习笔记整理与思考
- GMM-hmm算法学习笔记
- HMM和维比特算法学习
- HMM学习最佳范例七:前向-后向算法
- 隐马尔科夫模型(HMM)学习之 概要
- HMM学习最佳范例五:前向算法4
- 分词算法模型学习笔记(一)——HMM
- HMM学习笔记_3(从一个实例中学习Viterbi算法)
- HMM学习最佳范例五:前向算法5
- HMM学习笔记_2(从一个实例中学习HMM前向算法)
- 基于隐马尔科夫模型(HMM)的地图匹配(Map-Matching)算法
- HMM学习最佳范例四:隐马尔科夫模型
- 隐马尔科夫模型HMM的前向算法和后向算法