隐马尔可夫模型(一)

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;

	}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值