HMM条件下的 前向算法 和 维特比解码
来源:互联网 发布:网络超市加盟店排行榜 编辑:程序博客网 时间:2024/04/30 14:42
一、隐马尔科夫HMM假设:
有且只有3种天气:0晴天,1阴天,2雨天
各种天气间的隔天转化概率mp:
有2种活动: 0去公园,1不去公园
各种天气下进行各种活动的概率:
观察5天的活动序列:0 0 1 0 1 ;(0去公园,1不去公园)
第0天的天气概率pi:
定义几个宏及变量表示HMM:
#define T 5 //观察N天 #define M 3 //每天可能有M种天气 #define N 2 //动作种类,去公园+不去公园 float mp[M][M]; //相邻两天的天气转换概率 float w2a[M][N]; //weather to action,各天气下采取各动作的概率int O[T]; //N天观察到的天气序列 int bestPath[T][M];//bestPath[t][i]表示 (第t天处于第i种天气状态且出现“O0-Ot”观察序列的概率最大的)路径在时间t-1时刻的天气状态 float pi[M]; //一个M维向量,表示第一天各种天气出现的概率
二、前向算法--出现观察动作序列的概率
即求出现:“1去公园,2去公园,3不去公园,4去公园,5不去公园” 动作序列的概率。
这是一个求和问题,用DP思想的前向算法解决。
1、构造矩阵float sumP[T][M];
sumP[t][i]表示:在时间t,处于天气i,且出现观察动作序列O0-Ot的概率
2、填表求解过程:
//初始表for(i=0; i<M; i++){sumP[0][i] = pi[i]*w2a[ i ][ O[0] ];}//填表for(t=1; t<T; t++){for (i=0; i<M; i++){sumP[t][i]=0;for (j=0; j<M; j++){sumP[t][i] += sumP[t-1][j]*mp[j][i]*w2a[ i ][ O[t] ];}}}求观察序列出现概率:
float sumPP=0;for(i=1;i<M;i++){sumPP += sumP[T-1][i];}cout<<"使用前向算法算出,观察序列的出现概率为"<<sumPP<<endl;
三、维特比解码-哪种天气下出现观察动作序列的概率最大
在哪种天气序列下,出现观察序列的概率最大,并求 (出现该天气序列和观察动作序列事件)的最大概率。
这是最优化问题,DP思想求最大,采用维特比解码
1、构造矩阵maxP[T][M]
maxP[t][j], 算出第t天处于第i状态且出现观察序列O0~Ot的路径中,(出现天气路径和观察路径)概率最大的路径的概率。
bestPath[t][i],表示是第t天,天气状态为i状态出现观察序列O0~Ot的最大概率路径下(即取得maxP[t][i]),第t-1天的天气状态。
2、填表过程:
//初始表float maxpp=0;int maxPre=0; for(i=0;i<M;i++){maxP[0][i] = pi[i]*w2a[ i ][ O[0] ];if(maxP[0][i]>maxpp){bestPath[0][i]=-1;maxpp=maxP[0][i]; } }//后填表for(t=1;t<T;t++) //每一天 {for(i=0;i<M;i++)//maxP[t][j],要算出第t天处于第i状态且出现观察序列O0~Ot的路径中,(出现天气路径和观察路径)概率最大的路径的概率 {maxpp=0;maxPre=0;for(j=0;j<M;j++)//第t-1天,天气为第j状态 {float temp = maxP[t-1][j]*mp[j][i]*w2a[i][O[t]];if(temp > maxpp){maxpp = temp;maxPre = j; } }maxP[t][i] = maxpp;bestPath[t][i] = maxPre; } }
输出最大概率及其天气路径:
float maxEndP=0;int lastChoice;for(i=0; i<M; i++){if(maxP[T-1][i] > maxEndP) {maxEndP = maxP[T-1][i];lastChoice = i;}}cout<<"最大的概率为:"<<maxEndP<<endl; cout<<"所有路径中,出现观察序列概率的最大的天气路径为:"<<endl;cout<<lastChoice<<" ";for(t=T-1; t>0; t--){cout<<bestPath[t][lastChoice]<<" ";lastChoice = bestPath[t][lastChoice];}cout<<endl;
四、代码:
#include<iostream>using namespace std;#define T 5 //观察N天 #define M 3 //每天可能有M种天气 #define N 2 //动作种类,去公园+不去公园 float mp[M][M]; //相邻两天的天气转换概率 float w2a[M][N]; //weather to action,各天气下采取各动作的概率int O[T]; //N天观察到的天气序列 int bestPath[T][M];//bestPath[t][i]表示 (第t天处于第i种天气状态且出现“O0-Ot”观察序列的概率最大的)路径在时间t-1时刻的天气状态 float pi[M]; //一个M维向量,表示第一天各种天气出现的概率,【通常包含一个1,其余为0】 void initHMM(){int i,j,k;//输入天气转移概率 for(i=0; i<M; i++){for(j=0;j<M;j++){cin>>mp[i][j]; }} //输入各天气下,采取不同动作的概率 for(i=0; i<M; i++){for(j=0; j<N; j++){cin>>w2a[i][j]; } }//输入pifor(i=0; i<M; i++){cin>>pi[i]; } //输入观察序列for(i=0; i<T; i++){cin>>O[i]; } }/*维特比算法已知HMM模型,转移概率(天气转换概率),初始状态(第0天的天气或天气概率),各天气下采取各动作的概率,观察序列(动作序列)1.求出(使观察序列出现概率最大的)天气路径,即在那种天气序列下,出现观察序列的概率最大2.求出 (出现天气路径且出现观察序列的事件)的最大概率这是一种最优化问题,求最大,DP思想*/float viterbi(){float maxP[T][M];int i,j,t;//初始表float maxpp=0;int maxPre=0; for(i=0;i<M;i++){maxP[0][i] = pi[i]*w2a[ i ][ O[0] ];if(maxP[0][i]>maxpp){bestPath[0][i]=-1;maxpp=maxP[0][i]; } }//后填表for(t=1;t<T;t++) //每一天 {for(i=0;i<M;i++)//maxP[t][j],要算出第t天处于第i状态且出现观察序列O0~Ot的路径中,(出现天气路径和观察路径)概率最大的路径的概率 {maxpp=0;maxPre=0;for(j=0;j<M;j++)//第t-1天,天气为第j状态 {float temp = maxP[t-1][j]*mp[j][i]*w2a[i][O[t]];if(temp > maxpp){maxpp = temp;maxPre = j; } }maxP[t][i] = maxpp;bestPath[t][i] = maxPre; } }float maxEndP=0;int lastChoice;for(i=0; i<M; i++){if(maxP[T-1][i] > maxEndP) {maxEndP = maxP[T-1][i];lastChoice = i;}}cout<<"最大的概率为:"<<maxEndP<<endl; cout<<"所有路径中,出现观察序列概率的最大的天气路径(逆序)为:"<<endl;cout<<lastChoice<<" ";for(t=T-1; t>0; t--){cout<<bestPath[t][lastChoice]<<" ";lastChoice = bestPath[t][lastChoice];}cout<<endl;return maxEndP;} /*前向算法已知HMM模型,转移概率(天气转换概率),初始状态(第0天的天气或天气概率),各天气下采取各动作的概率,观察序列(动作序列)1.求出观察序列出现的概率为多大即,在给定的初始天气,转移天气概率,及天气动作概率的条件下,出现观察到的动作概率是多少这是一个加法求和问题,DP思想*/void forward(){float sumP[T][M];//sumP[t][i]表示:在时间t,处于天气i,且出现观察动作序列O0-Ot的概率int t,i,j,k;//初始表for(i=0; i<M; i++){sumP[0][i] = pi[i]*w2a[ i ][ O[0] ];}//填表for(t=1; t<T; t++){for (i=0; i<M; i++){sumP[t][i]=0;for (j=0; j<M; j++){sumP[t][i] += sumP[t-1][j]*mp[j][i]*w2a[ i ][ O[t] ];}}}float sumPP=0;for(i=1;i<M;i++){sumPP += sumP[T-1][i];}cout<<"使用前向算法算出,观察序列的出现概率为"<<sumPP<<endl;}int main(){initHMM();viterbi();forward();system("pause");}/*0.33333 0.33333 0.333330.33333 0.33333 0.333330.33333 0.33333 0.333330.75 0.250.4 0.60.25 0.750.5 0.3 0.20 0 1 0 1*/
五、运行结果:
0.33333 0.33333 0.33333
0.33333 0.33333 0.33333
0.33333 0.33333 0.33333
0.75 0.25
0.4 0.6
0.25 0.75
0.5 0.3 0.2
0 0 1 0 1
最大的概率为:0.00146479
所有路径中,出现观察序列概率的最大的天气路径为:
2 0 2 0 0
使用前向算法算出,观察序列的出现概率为0.0284842
- HMM条件下的 前向算法 和 维特比解码
- 自然语言处理2-隐马尔科夫模型(HMM)-forward algorithm(前向算法)和Viterbi(维特比算法)
- python+HMM之维特比解码
- HMM-维特比算法原理和实现
- HMM算法之维特比算法
- 隐马尔科夫(HMM)模型 前向后向(Forward_backward) 维特比 (viterbi)
- HMM之维特比算法
- HMM之维特比算法
- HMM:隐马尔科夫模型-维特比算法
- HMM学习,维特比算法
- HMM之维特比算法
- HMM之维特比算法
- HMM前向算法和后向算法的推导
- 隐马尔科夫模型之前向算法和维特比算法
- 维特比算法以及解码时的beamSearch
- 隐马尔可夫模型(HMM) - 4 - 预测算法(维特比算法)
- hmm-前向算法
- hmm-前向算法
- mysql半同步复制的实现
- 今日作息及食谱(6.21)
- Linux ARM系统调用实现
- Spring AOP 之编译期织入、装载期织入、运行时织入
- Mysql基础篇之触发器
- HMM条件下的 前向算法 和 维特比解码
- oracle job的管理
- Hadoop入门进阶步步高(六)-Hadoop1.x与Hadoop2的区别
- C++程序设计
- 一个简单的翻色棋游戏
- PAT1001. A+B Format
- UVa Live Archive 2519 - Radar Installation
- oracle 传输表空间
- JAVA开发的网页式看图软件