隐马尔可夫模型(一)

来源:互联网 发布:一元云购指定中奖源码 编辑:程序博客网 时间:2024/04/30 13:32

1. 隐马尔可夫模型的定义和构成

2. 隐马尔可夫模型的三个问题

3. 基于隐马尔可夫模型的分词算法实现


1.1. 介绍隐马尔科夫模型之前首先说一下几个重要的概念,

(1)马尔可夫假设:模型的当前状态仅仅依赖于前面n个状态,可以看到这种假设有可能会丢失信息。

(2)马尔可夫过程:状态间的转移仅仅依赖于前n个状态的过程,也就是当前的状态跟前n个状态之前的状态无关。

(3)马尔可夫链:时间和状态都是离散的马尔可夫过程叫做马尔可夫链,这里的重点是离散

(4)马尔科夫模型:独立于时间t的随机过程,也就是跟时间t没关系,状态跟具体哪个时刻没关系,t只用来说明状态的顺序


1.2 隐马尔可夫模型(hidden Markov model, HMM)

马尔可夫模型有时又叫做可视马尔可夫模型,因为状态是可以看到的,隐马尔可夫模型的状态是看不的,可以观察到的是一些观察值,这些观察值是由状态按照一定的概率产生的,所以可以看到这里有两个随机过程,一个是一个状态到另一个状态的随机,一个是状态到观察值的随机。

一个HMM由如下几个部分组成:

(1)状态的数目N

(2)观察值得数目M

(3)状态的概率转移矩阵A={aij},即从第i个状态到第j个状态的概率,且概率和为1。

(4)状态到观察值的概率B={bij},即从第i个状态到第j个观察值得概率,且概率和为1。

(5)第一次选择哪个状态的概率qi,即一个序列中第i个状态为第一个状态的概率,概率和为1。

例:一个暗室里有N个口袋,每个口袋中有M种不同颜色的球,一个人按照一定的概率分布(p1)随机的选取一个初始口袋,从中根据不同颜色的概率分布p2选取一个球,并报告该球的初始颜色,然后再根据口袋的概率分布p3选取另外一个口袋,根据不同颜色球的概率分布选取一个球并报告该球的颜色,重复这个过程。这里的N个口袋就是HMM的N个状态,M个颜色就是HMM的M个观察值,p1就是HMM的初始状态概率,p3就是HMM的状态转移概率A,p2HMM的状态到观察值的概率B

2. 隐马尔科夫模型的三个问题

2.1 估值问题,如何根据已知的参数,估计一个观察值的概率。就是在1.2中5个部分已知的情况下,估计一个观察值的概率。

例如:给定一个观察序列   和模型,计算在给定u的情况下,观察序列O的概率,即P(O|u)

解决方法:前向算法

具体的程序实现为:

/** * 前向算法 * @param phmm * @param O * @return:输出所有的前向概率,p(O|u)只要将T时刻的前向概率求和即可 */public static double [][] forward(HMMEntity phmm, int []O){int i,j;int t;double sum;int T = O.length;double [][] alpha = new double[T][phmm.getN()];//初始化,计算t1时刻所有状态的局部概率for(i=0;i<phmm.getN();i++){alpha[0][i] = phmm.getPi()[i] * phmm.getB()[i][O[0]]; System.out.println("alpha[0]["+i+"] = "+alpha[0][i]);}//递归计算每个时间点的局部概率for(t=0;t<T-1;t++){for(j=0;j<phmm.getN();j++){sum = 0.0;for(i=0;i<phmm.getN();i++){sum += alpha[t][i] * phmm.getA()[i][j];}alpha[t+1][j] = sum * phmm.getB()[j][O[t+1]];System.out.println("alpha["+(t+1)+"]["+j+"] = "+alpha[t+1][j]);}}return alpha;}

2.2 解码问题:给定一个观察序列和模型,如何快速有效的选择最优的状态序列,是的该状态序列最好的解释观察序列

解决方法:维特比算法

实现:

/** * 维特比算法 * @param phmm * @param O */public static int[] viterbi(HMMEntity phmm,int []O){int i,j;int t;int maxvalind;double maxval,val;int T = O.length;double[][] delta = new double[T][phmm.getN()];int[][]psi = new int[T][phmm.getN()];for(i=0;i<phmm.getN();i++){delta[0][i] = phmm.getPi()[i]* phmm.getB()[i][O[0]];psi[0][i] = 0;}for(t=1;t<T;t++){for(j=0;j<phmm.getN();j++){maxval = 0.0;maxvalind = 1;for(i=0;i<phmm.getN();i++){val = delta[t-1][i]*phmm.getA()[i][j];if(val > maxval){maxval = val;maxvalind = i;}}delta[t][j] = maxval*phmm.getB()[j][O[t]];psi[t][j] = maxvalind;}}double pprob = 0;int q[] = new int[T];for(i=0;i<phmm.getN();i++){if(delta[T-1][i]>pprob){pprob = delta[T-1][i];q[T-1] = i;}}for(t=T-2;t>=0;t--){q[t] = psi[t+1][q[t+1]];}return q;}

 

原创粉丝点击