隐马尔科夫模型及Viterbi算法的应用
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4335810.html
一个例子:
韦小宝使用骰子进行游戏,他有两种骰子一种正常的骰子,还有一种不均匀的骰子,来进行出千。
开始游戏时他有2/5的概率出千。
对于正常的骰子A,每个点出现的概率都是1/6.
对于不均匀的骰子B,5,6两种出现的概率为3/10,其余为1/10.
出千的随机规律如下图所示:

我们观测到的投掷结果为:ob={1,3,4,5,5,6,6,3,2,6}
请判断韦小宝什么时候出千了?
我们可以这样建模$x_i$表示第$i$次投掷的骰子的种类,$y_i$表示第$i$次投掷出的点数,$\lambda$表示各个概率参数。
那么第$t$次使用第$i$种骰子投掷的概率$\delta_t(i)$等于
\begin{equation} \delta_t(i)=\max_{x_1,\dots,x_{t-1}}P(x_1,\dots,x_{t-1},x_t=i,y_1,\dots,y_t|\lambda) \end{equation}
其实$\delta_{t+1}(i)$可以由$\delta_t(i)$推倒得出:
\begin{eqnarray} \delta_{t+1}(i) &=& \max_{x_1,\dots,x_{t}}P(x_1,\dots,x_{t},x_{t+1}=i,y_1,\dots,y_{t+1}|\lambda)\\ &=& \max_j \delta_t(j)\alpha_{ji}\beta_i(y_{t+1})\end{eqnarray}
其中$\alpha_{ji}$表示从第$j$个骰子转移到第$i$个骰子的概率。
$\beta_i(y_{t+1})$表示使用第i个骰子投出点$y_{t+1}$的概率。
从而可以使用上述利用动态规划算法进行逐次递推计算。
得到的结果为:
| t | $y_t$ | $\delta_t(A)$ | $\Psi_t(A)$ | $\delta_t(B)$ | $\Psi_t(B)$ |
| 1 | 1 | 0.1 | A | 0.04 | A |
| 2 | 3 | 0.0133333 | A | 0.0036 | B |
| 3 | 4 | 0.00177778 | A | 0.000324 | B |
| 4 | 5 | 0.000237037 | A | 0.000106667 | A |
| 5 | 5 | 3.16049e-05 | A | 2.88e-05 | B |
| 6 | 6 | 4.21399e-06 | A | 7.776e-06 | B |
| 7 | 6 | 5.61866e-07 | A | 2.09952e-06 | B |
| 8 | 3 | 7.49154e-08 | A | 1.88957e-07 | B |
| 9 | 2 | 9.98872e-09 | A | 1.70061e-08 | B |
| 10 | 6 | 1.33183e-09 | A | 4.59165e-09 | B |
因为最后一步$\delta_t(B)$的值大于$\delta_t(A)$,所以一次使用B骰子的概率最大,从而一直向上回溯,得到的使用骰子的序列为:AAABBBBBBB
代码如下所示:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
using namespace std;
double initP[] = {0.6, 0.4};//骰子A,B的初始概率
double transferMatrix[][] = {{0.8, 0.2}, {0.1, 0.9}};//骰子之间的转移概率
double EmissionP[][]={{/6.0, /6.0, /6.0, /6.0, /6.0, /6.0},//骰子A的发射概率
{0.1, 0.1, 0.1, 0.1, 0.3, 0.3}};//骰子B的发射概率
double dp[][];//dp[i][j]第i步时,使用第j个骰子的最大概率
double dpS[][];//dpS[i][j]第i步时,使用第j个骰子,得到的最大概率时,使用的骰子种类, 0->A, 1->B
int ob[] = {, , , , , , , , , };//观测点数
bool diceArray[];//预测骰子使用序列
void Viterbi()
{
memset(dp,,sizeof(dp));
memset(dpS,,sizeof(dpS));
memset(diceArray,,sizeof(diceArray));
dp[][] = initP[]* EmissionP[][ob[]-];
dp[][] = initP[]* EmissionP[][ob[]-];
for( int i = ; i < ; i++ )//投掷次数
{
for( int j = ; j < ; j++ )//当前状态
{
for( int k = ; k < ; k++ )//上一个状态
{
double tempP = dp[i-][k] * transferMatrix[k][j] * EmissionP[j][ob[i]-] ;
if( dp[i][j] < tempP )
{
dp[i][j] = tempP;
dpS[i][j] = k;
}
}
}
}
int maxState = ;
if( dpS[][] < dpS[][] )
{
maxState = ;
}
for( int i = ; i >= ; i-- )
{
diceArray[i] = maxState;
maxState = dpS[i][maxState];
}
}
int main(int argc, char *argv[])
{
Viterbi();
cout<<"每步每个状态下的概率和骰子种类:"<<endl;
for( int i = ; i < ; i++ )
{
for( int j = ; j < ; j++ )
{
cout<<dp[i][j]<<" "<<dpS[i][j]<<" ";
}
cout<<endl;
}
cout<<"预测骰子种类,0->A, 1->B : "<<endl;
for( int i = ; i < ; i++ )
{
cout<<diceArray[i]<<" ";
}
cout<<endl;
}
/* result:
每步每个状态下的概率和骰子种类:
0.1 0 0.04 0
0.0133333 0 0.0036 1
0.00177778 0 0.000324 1
0.000237037 0 0.000106667 0
3.16049e-05 0 2.88e-05 1
4.21399e-06 0 7.776e-06 1
5.61866e-07 0 2.09952e-06 1
7.49154e-08 0 1.88957e-07 1
9.98872e-09 0 1.70061e-08 1
1.33183e-09 0 4.59165e-09 1
预测骰子种类,0->A, 1->B :
0 0 0 1 1 1 1 1 1 1
*/
隐马尔科夫模型及Viterbi算法的应用的更多相关文章
- HMM:隐马尔科夫模型-前向算法
http://blog.csdn.net/pipisorry/article/details/50722376 目标-解决HMM的基本问题之一:已知HMM模型λ及观察序列O,如何计算P(O|λ)(计算 ...
- 隐马尔可夫模型及Viterbi算法
隐马尔可夫模型(HMM,hidden Markov model)是可用于标注问题的统计学模型,描述由隐藏的马尔可夫链随机生成观测序列的过程,属于生成模型.HMM模型主要用于语音识别,自然语言处理,生物 ...
- HMM:隐马尔科夫模型-维特比算法
http://blog.csdn.net/pipisorry/article/details/50731584 目标-解决HMM的基本问题之二:给定观察序列O=O1,O2,-OT以及模型λ,如何选择一 ...
- 隐马尔科夫模型(HMM)的概念
定义隐马尔科夫模型可以用一个三元组(π,A,B)来定义:π 表示初始状态概率的向量A =(aij)(隐藏状态的)转移矩阵 P(Xit|Xj(t-1)) t-1时刻是j而t时刻是i的概率B =(bij) ...
- 隐马尔科夫模型(Hidden Markov Models)
链接汇总 http://www.csie.ntnu.edu.tw/~u91029/HiddenMarkovModel.html 演算法笔记 http://read.pudn.com/downloads ...
- 隐马尔科夫模型(Hidden Markov Models) 系列之三
转自:http://blog.csdn.net/eaglex/article/details/6418219 隐马尔科夫模型(Hidden Markov Models) 定义 隐马尔科夫模型可以用一个 ...
- 隐型马尔科夫模型(HMM)向前算法实例讲解(暴力求解+代码实现)---盒子模型
先来解释一下HMM的向前算法: 前向后向算法是前向算法和后向算法的统称,这两个算法都可以用来求HMM观测序列的概率.我们先来看看前向算法是如何求解这个问题的. 前向算法本质上属于动态规划的算法,也就是 ...
- 隐马尔科夫模型(hidden Markov Model)
万事开头难啊,刚开头确实不知道该怎么写才能比较有水平,这篇博客可能会比较长,隐马尔科夫模型将会从以下几个方面进行叙述:1 隐马尔科夫模型的概率计算法 2 隐马尔科夫模型的学习算法 3 隐马尔科夫模型 ...
- 隐马尔科夫模型python实现简单拼音输入法
在网上看到一篇关于隐马尔科夫模型的介绍,觉得简直不能再神奇,又在网上找到大神的一篇关于如何用隐马尔可夫模型实现中文拼音输入的博客,无奈大神没给可以运行的代码,只能纯手动网上找到了结巴分词的词库,根据此 ...
随机推荐
- ngrok 2016版
1. 先到http://www.ngrok.cc/下载客户端 2.进管理页面 注册登录 3.绑定域名 新增: 复制客户端id 打开该目录 按住shift 右键->在此处打开命令窗口 输入 sta ...
- Mybatis-Generator 自动生成Dao、Model、Mapping相关文档
最近在学习mybatis,结果在写Mapping的映射文件时insert语句一直报错,于是想看看标准的映射文件是什么样.百度到Mybatis-Generator 自动生成Dao.Model.Mappi ...
- Largest Rectangle in a Histogram 常用技巧 stack的运用
Largest Rectangle in a Histogram
- 02.Java多线程并发库API使用
1. 传统线程技术回顾 继承线程与实现Runnable的差异?为什么那么多人都采取第二种方式? 因为第二种方式更符合面向对象的思维方式.创建一个线程,线程要运行代码,而运行的代码都封装到 ...
- 【Shell脚本学习4】几种常见的Shell
上面提到过,Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本. Unix/Linux上常见的Shell脚本解释器有bash.sh.csh.ksh等,习惯上把它们称作一种Shell.我们常说 ...
- VMware系统运维(八)vCenter Server安装
1.终于开始安装vCenter Server了,需要配置数据源哦! 2.下一步 3.接受协议,下一步 4.输入许可密钥,也可以后面再输入,下一步 5.选择数据源,即我们前面配置的系统DSN,下一步 6 ...
- nginx 反向代理设置
假设对本机80端口的访问为一台服务器,对本机8000端口的访问为另一台服务器,下面这样写一个nginx的反向代理配置,就可以实现所有请求都转移 server {listen 0.0.0.0:80;se ...
- 剑指Offer07 斐波那契数列
/************************************************************************* > File Name: 07_Fibona ...
- hdu 4738 桥
题目:还是自己看题目吧 trick:当不连通时不需要人去炸.否则,当桥的费用为0时当然需要一个人去炸... #include <set> #include <map> #inc ...
- 转:android surface简单使用Demo
转: http://blog.csdn.net/listening_music/article/details/6860786 通过之前介绍的如何自定义View, 我们知道使用它可以做一些简单的动画效 ...