[关闭]
@spiritnotes 2016-03-26T08:58:54.000000Z 字数 5107 阅读 1456

隐含马尔科夫模型(HMM)

机器学习 算法


马尔科夫模型

任何一次观测都和前面的所有观测有关,则有

简化

对其进行简化,假设其每次观测只与前面一次或者两次有关,则有
一阶马尔科夫模型


二阶马尔科夫模型

使用一阶简化模型后有

参数个数

接受观测具有K个状态,则有 有 K-1 个参数, 可为K个值,则有 K(K-1) 个参数。M 阶参数有 个。

隐马尔科夫模型

是关于时序的概率模型,描述由一个隐藏的马尔科夫链随机生成不可观测的状态随机序列,再由各个状态生成一个观测而产生观测随机序列的过程。

状态序列
隐藏的马尔科夫链随机生成的状态的序列
观测序列
每个状态生成一个观测,而由此产生的观测的随机序列
形式定义
Q是所有的状态集合,V是所有观测集合
I是长度为T的状态序列,O是对应的观测序列
A是状态转移矩阵
B是观测概率矩阵
是初始状态概率向量
其模型可以用三元符号表示

基本假设:

概率计算问题

给定模型和观测序列,计算在模型下观测序列O出现的概率

直接计算法

scala代码如下

  1. def calcProbDirect(output: Array[Int]): Double = {
  2. val len = output.length
  3. val stateLen = stateChange.length
  4. def rescCalc(outputIndex: Int, lastState: Int, currProb:Double):scala.collection.immutable.IndexedSeq[Double] ={
  5. if (outputIndex == 0){
  6. for (state <- 0 until stateLen;
  7. i <- rescCalc(outputIndex+1,state, pi(state)*ouputPorbs(state)(output(outputIndex))*currProb))
  8. yield i
  9. }
  10. else if (outputIndex == len-1) {
  11. for (state <- 0 until stateLen) yield currProb*stateChange(lastState)(state)*ouputPorbs(state)(output(outputIndex))
  12. }
  13. else {
  14. for (state <- 0 until stateLen;
  15. i <- rescCalc(outputIndex+1,state, currProb*stateChange(lastState)(state)*ouputPorbs(state)(output(outputIndex))))
  16. yield i
  17. }
  18. }
  19. rescCalc(0, 0, 1).sum
  20. }

前向算法

前向概率
给定模型,定义到时刻t部分观测序列为且状态为的概率为前向概率,记为
前向算法
1 初始值
2 递推,对所有

3 终止
  1. def calcProbForward(output: Array[Int]): Double = {
  2. val len = output.length
  3. val stateLen = stateChange.length
  4. def clacOutIndexProbForState(outputIndex:Int, state:Int) ={
  5. ouputPorbs(state)(output(outputIndex))
  6. }
  7. def forward(outputIndex: Int): Seq[(Int, Double)] ={
  8. if (outputIndex == 0) {
  9. (0 until stateLen zip pi).map{case (state, prob) => (state, prob*clacOutIndexProbForState(outputIndex, state))}
  10. }
  11. else {
  12. forward(outputIndex-1).flatMap {
  13. case (state, prob) => {
  14. ((0 until stateLen) zip stateChange(state)).map {
  15. case (nextState, changeRatio) => {
  16. (nextState, prob * changeRatio * clacOutIndexProbForState(outputIndex, nextState))
  17. }
  18. }
  19. }
  20. }.groupBy(_._1).map(line =>{(line._1, line._2.map(_._2).sum)}).toList
  21. }
  22. }
  23. forward(len-1).map(_._2).sum
  24. }

后向算法

后向概率
给定马尔科夫模型,定义在时刻t状态为的条件下,从t+1到T的部分观测序列为的概率为后向概率,记为
后向算法
1
2 对
3
  1. def calcProbBackWord(output: Array[Int]): Double = {
  2. val len = output.length
  3. val stateLen = stateChange.length
  4. def clacOutIndexProbForState(outputIndex:Int, state:Int) ={
  5. ouputPorbs(state)(output(outputIndex))
  6. }
  7. def backward(outputIndex: Int): Seq[(Int, Double)] ={
  8. if (outputIndex == len-1) {
  9. 0 until stateLen map ((_, 1.0))
  10. }
  11. else if (outputIndex == -1){
  12. backward(outputIndex+1).map{case(state, prob) => {(state, prob*pi(state)*clacOutIndexProbForState(outputIndex+1, state))}}
  13. }
  14. else {
  15. backward(outputIndex+1).flatMap {
  16. case (state, prob) => {
  17. val stateprobs = stateChange.map(line=> line(state))
  18. ((0 until stateLen) zip stateprobs).map {
  19. case (preState, changeRatio) => {
  20. //println(preState, state, prob, changeRatio, clacOutIndexProbForState(outputIndex+1, state), prob * changeRatio * clacOutIndexProbForState(outputIndex+1, state), outputIndex)
  21. (preState, prob * changeRatio * clacOutIndexProbForState(outputIndex+1, state))
  22. }
  23. }
  24. }
  25. }.groupBy(_._1).map(line =>{(line._1, line._2.map(_._2).sum)}).toList
  26. }
  27. }
  28. backward(-1).map(_._2).sum
  29. }

概率计算

利用前向算法与后向算法合并可得观测概率

给定模型和观测,在t时刻处于状态的概率

给定模型,在时刻t处于以及在t+1处于的概率

学习问题

已知观测序列,估计模型参数,在该模型下观测序列概率最大

监督学习方法

已知训练集中包含S个长度相同的观测序列和对应的状态序列,那么如下估计参数

转移概率 的估计
观测概率 的估计
初始状态概率
为S个样本中初始状态为的频率

Baum-Welch算法

预测问题

利用

语音识别

在语音识别中用户实际的本意可以表达为 而我们实际识别到的音轨可以表示为 ,于是需要判断其实际的本意则可以通过如下的概率表示

自动纠错

自动纠错与语音识别差不多,区别只在于

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注