HMM算法


一、马尔科夫简述

在这里插入图片描述

二、HMM算法概述

在这里插入图片描述

三、隐马尔科夫模型(HMM)笔记(公式+代码)

参考

http://t.csdn.cn/KfRqp

隐马尔科夫模型(hidden Markov model,HMM)是可用于 标注问题的统计学习模型,描述由隐藏的马尔可夫链随机生成观测序列的过程,属于生成模型。隐马尔可夫模型在语音识别、自然语言处理、生物信息、模式识别等领域有着广泛的应用。

3.1基本概念

3.1.1

  • 隐马尔可夫模型是关于时序的概率模型,描述由一个隐藏的马尔可夫链随机生成不可观测的状态随机序列,再由各个状态生成一个观测从而产生观测随机序列的过程。
  • 隐藏的马尔可夫链随机生成的状态的序列,称为状态序列(state sequence;
  • 每个状态生成一个观测,而由此产生的观测的随机序列,称为观测序列(observation sequence。
  • 序列的每一个位置又可以看作是一个时刻。

一个不一定恰当的例子:你只知道一个人今天是散步了,逛街了,还是在家打扫卫生,推测今天的天气;这个人在下雨天可能在家打扫卫生,也有可能雨中散步,晴天可能去逛街,也有可能散步,或者打扫卫生
隐藏状态 Y(不可见):下雨,晴天 观察状态 X(可见): 散步,逛街,打扫房间
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1.2盒子和球模型

在这里插入图片描述
在这里插入图片描述

3.1.3观测序列生成过程

在这里插入图片描述

3.1.4HMM模型3个基本问题

在这里插入图片描述

3.2概率计算问题

在这里插入图片描述

3.2.1直接计算法

在这里插入图片描述

3.2.2前向算法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.2.1前向公式证明

在这里插入图片描述
在这里插入图片描述

3.2.2.2盒子和球例子

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.2.3前向算法Python代码
# -*- coding:utf-8 -*-
# python3.7
# @Time: 2019/12/17 22:33
# @Author: Michael Ming
# @Website: https://michael.blog.csdn.net/
# @File: hiddenMarkov.py
import numpy as np
class HiddenMarkov:
    def forward(self, Q, V, A, B, X, PI):   # 前向算法
        N = len(Q)  # 隐藏状态数量
        M = len(X)  # 观测序列大小
        alphas = np.zeros((N, M))   # 前向概率 alphas 矩阵
        T = M   # 时刻长度,即观测序列长度
        for t in range(T):  # 遍历每个时刻,计算前向概率 alphas
            indexOfXi = V.index(X[t])   # 观测值Xi对应的V中的索引
            for i in range(N):  # 对每个状态进行遍历
                if t == 0: # 计算初值
                    alphas[i][t] = PI[t][i] * B[i][indexOfXi]   # a1(i)=πi B(i,x1)
                    print("alphas1(%d)=p%dB%d(x1)=%f" %(i,i,i,alphas[i][t]))
                else:
                    alphas[i][t] = np.dot(
                        [alpha[t-1] for alpha in alphas],   #  取的alphas的t-1列
                        [a[i] for a in A]) *B[i][indexOfXi]    # 递推公式
                    print("alpha%d(%d)=[sigma alpha%d(i)ai%d]B%d(x%d)=%f"
                        %(t, i, t-1, i, i, t, alphas[i][t]))
                    print(alphas)
        P = sum(alpha[M-1] for alpha in alphas)  # 最后一列概率的和
        print("P=%f" % P)

Q = [1, 2, 3]
V = ['红', '白']
A = [[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]
B = [[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]
# X = ['红', '白', '红', '红', '白', '红', '白', '白']
X = ['红', '白', '红']    # 书上的例子
PI = [[0.2, 0.4, 0.4]]

hmm = HiddenMarkov()
hmm.forward(Q, V, A, B, X, PI)

关于numpy的一些操作:

>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> b
array([[ 7,  8],
       [ 9, 10],
       [11, 12]])
>>> np.dot(a[0],[B[1] for B in b])
64
>>> np.dot([A[0] for A in a],[B[1] for B in b])
132
>>> np.multiply(a[0],[B[1] for B in b])
array([ 8, 20, 36])
>>> np.multiply([A[0] for A in a],[B[1] for B in b])
array([ 8, 40, 84])

运行结果:(跟上面计算一致)

alphas1(0)=p0B0(x1)=0.100000
alphas1(1)=p1B1(x1)=0.160000
alphas1(2)=p2B2(x1)=0.280000
alpha1(0)=[sigma alpha0(i)ai0]B0(x1)=0.077000
[[0.1   0.077 0.   ]
 [0.16  0.    0.   ]
 [0.28  0.    0.   ]]
alpha1(1)=[sigma alpha0(i)ai1]B1(x1)=0.110400
[[0.1    0.077  0.    ]
 [0.16   0.1104 0.    ]
 [0.28   0.     0.    ]]
alpha1(2)=[sigma alpha0(i)ai2]B2(x1)=0.060600
[[0.1    0.077  0.    ]
 [0.16   0.1104 0.    ]
 [0.28   0.0606 0.    ]]
alpha2(0)=[sigma alpha1(i)ai0]B0(x2)=0.041870
[[0.1     0.077   0.04187]
 [0.16    0.1104  0.     ]
 [0.28    0.0606  0.     ]]
alpha2(1)=[sigma alpha1(i)ai1]B1(x2)=0.035512
[[0.1      0.077    0.04187 ]
 [0.16     0.1104   0.035512]
 [0.28     0.0606   0.      ]]
alpha2(2)=[sigma alpha1(i)ai2]B2(x2)=0.052836
[[0.1      0.077    0.04187 ]
 [0.16     0.1104   0.035512]
 [0.28     0.0606   0.052836]]
P=0.130218

3.2.3后向算法

在这里插入图片描述
在这里插入图片描述

3.2.3.1后向公式证明

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.3.2后向算法Python代码
import numpy as np
class HiddenMarkov:
    def backward(self, Q, V, A, B, X, PI):  # 后向算法
        N = len(Q)  # 隐藏状态数量
        M = len(X)  # 观测序列大小
        betas = np.ones((N, M))    # 后向概率矩阵 betas
        for i in range(N):
            print("beta%d(%d)=1" %(M, i))   # 后向概率初始为1
        for t in range(M-2, -1, -1):
            indexOfXi = V.index(X[t+1])     # 观测值Xi对应的V中的索引
            for i in range(N):
                betas[i][t] = np.dot(
                    np.multiply(A[i], [b[indexOfXi] for b in B]),   # A的i行 B的Xi列 = 行
                    [beta[t+1] for beta in betas])  # 递推公式
                realT = t+1 # 真实的时间,t从1开始
                realI = i+1 # 状态标号,从1开始
                print("beta%d(%d)=[sigma A%djBj(x%d)beta%d(j)]=("
                      %(realT, realI, realI, realT+1, realT+1), end='') # end,表示以该符号空开,不换行
                for j in range(N):
                    print("%.2f*%.2f*%.2f+" %(A[i][j], B[j][indexOfXi],betas[j][t+1]), end=' ')
                print("0)=%.3f" % betas[i][t])
        print(betas)
        indexOfXi = V.index(X[0])
        P = np.dot(
            np.multiply(PI, [b[indexOfXi] for b in B]),
            [beta[0] for beta in betas])
        print("P(X|lambda)=", end=" ")
        for i in range(N):
            print("%.1f*%.1f*%.5f+" % (PI[0][i], B[i][indexOfXi], betas[i][0]), end=" ")
        print("0=%f" % P)

Q = [1, 2, 3]
V = ['红', '白']
A = [[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]
B = [[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]
# X = ['红', '白', '红', '红', '白', '红', '白', '白']
X = ['红', '白', '红']    # 书上的例子
PI = [[0.2, 0.4, 0.4]]

hmm = HiddenMarkov()
hmm.backward(Q, V, A, B, X, PI)

运行结果:

beta3(0)=1
beta3(1)=1
beta3(2)=1
beta2(1)=[sigma A1jBj(x3)beta3(j)]=(0.50*0.50*1.00+ 0.20*0.40*1.00+ 0.30*0.70*1.00+ 0)=0.540
beta2(2)=[sigma A2jBj(x3)beta3(j)]=(0.30*0.50*1.00+ 0.50*0.40*1.00+ 0.20*0.70*1.00+ 0)=0.490
beta2(3)=[sigma A3jBj(x3)beta3(j)]=(0.20*0.50*1.00+ 0.30*0.40*1.00+ 0.50*0.70*1.00+ 0)=0.570
beta1(1)=[sigma A1jBj(x2)beta2(j)]=(0.50*0.50*0.54+ 0.20*0.60*0.49+ 0.30*0.30*0.57+ 0)=0.245
beta1(2)=[sigma A2jBj(x2)beta2(j)]=(0.30*0.50*0.54+ 0.50*0.60*0.49+ 0.20*0.30*0.57+ 0)=0.262
beta1(3)=[sigma A3jBj(x2)beta2(j)]=(0.20*0.50*0.54+ 0.30*0.60*0.49+ 0.50*0.30*0.57+ 0)=0.228
[[0.2451 0.54   1.    ]
 [0.2622 0.49   1.    ]
 [0.2277 0.57   1.    ]]
P(X|lambda)= 0.2*0.5*0.24510+ 0.4*0.4*0.26220+ 0.4*0.7*0.22770+ 0=0.130218
# 概率跟前向算法计算的是一致的

3.2.4一些概率与期望值

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3学习算法

在这里插入图片描述

3.3.1监督学习方法

在这里插入图片描述

3.3.2无监督Baum-Welch 算法

先跳过

4.1预测算法

4.1.1近似算法

在这里插入图片描述

4.1.2维特比Viterbi算法

在这里插入图片描述
viterbi 算法:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.1.3维特比算法python代码

import numpy as np
class HiddenMarkov:
    def viterbi(self, Q, V, A, B, X, PI):   # 维特比算法,求最优状态序列
        N = len(Q)  # 隐藏状态数量
        M = len(X)  # 观测序列大小
        deltas = np.zeros((N, M))
        psis = np.zeros((N, M))
        Y = np.zeros((1, M))    # 最优(概率最大)状态序列
        for t in range(M):
            realT = t+1 # 真实时刻,从1开始
            indexOfXi = V.index(X[t])   # 观测值Xi对应的V中的索引
            for i in range(N):
                realI = i+1 # 状态序号,从1开始
                if t == 0:
                    deltas[i][t] = PI[0][i]* B[i][indexOfXi]    # 初始值
                    psis[i][t] = 0
                    print("delta1(%d)=pi_%d * B%d(x1)=%.2f * %.2f=%.2f" %
                          (realI, realI, realI, PI[0][i], B[i][indexOfXi], deltas[i][t]))
                    print('psis1(%d)=0' % realI)
                else:
                    deltas[i][t] = np.max(
                        np.multiply([delta[t-1] for delta in deltas],[a[i] for a in A])) \
                                   * B[i][indexOfXi]    # 递推公式
                    print("delta%d(%d)=max[delta%d(j)Aj%d]B%d(x%d)=%.2f*%.2f=%.5f"
                          % (realT, realI, realT-1, realI, realI, realT,
                             np.max(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A])),
                             B[i][indexOfXi], deltas[i][t]))
                    psis[i][t] = np.argmax(
                        np.multiply([delta[t-1] for delta in deltas],[a[i] for a in A])) + 1    # 序号从1开始
                    print("psis%d(%d)=argmax[delta%d(j)Aj%d]=%d" %
                          (realT, realI, realT-1, realI, psis[i][t]))
        print(deltas)
        print(psis)
        Y[0][M-1] = np.argmax([delta[M-1] for delta in deltas]) +1  # 序号从1开始
        print("Y%d=argmax[deltaT(i)]=%d" %(M, Y[0][M-1]))   # 最优路径的终点
        for t in range(M-2, -1, -1):    # 逆序推导前面的路径
            Y[0][t] = psis[int(Y[0][t+1])-1][t+1] # 寻找前面路径
            print("Y%d=psis%d(Y%d)=%d" %(t+1, t+2, t+2, Y[0][t]))
        print("最大概率的状态序列Y是: ", Y)

Q = [1, 2, 3]
V = ['红', '白']
A = [[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]
B = [[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]
# X = ['红', '白', '红', '红', '白', '红', '白', '白']
X = ['红', '白', '红']    # 书上的例子
PI = [[0.2, 0.4, 0.4]]

hmm = HiddenMarkov()
hmm.viterbi(Q, V, A, B, X, PI)

运行结果:(与上面计算一致)

delta1(1)=pi_1 * B1(x1)=0.20 * 0.50=0.10
psis1(1)=0
delta1(2)=pi_2 * B2(x1)=0.40 * 0.40=0.16
psis1(2)=0
delta1(3)=pi_3 * B3(x1)=0.40 * 0.70=0.28
psis1(3)=0
delta2(1)=max[delta1(j)Aj1]B1(x2)=0.06*0.50=0.02800
psis2(1)=argmax[delta1(j)Aj1]=3
delta2(2)=max[delta1(j)Aj2]B2(x2)=0.08*0.60=0.05040
psis2(2)=argmax[delta1(j)Aj2]=3
delta2(3)=max[delta1(j)Aj3]B3(x2)=0.14*0.30=0.04200
psis2(3)=argmax[delta1(j)Aj3]=3
delta3(1)=max[delta2(j)Aj1]B1(x3)=0.02*0.50=0.00756
psis3(1)=argmax[delta2(j)Aj1]=2
delta3(2)=max[delta2(j)Aj2]B2(x3)=0.03*0.40=0.01008
psis3(2)=argmax[delta2(j)Aj2]=2
delta3(3)=max[delta2(j)Aj3]B3(x3)=0.02*0.70=0.01470
psis3(3)=argmax[delta2(j)Aj3]=3
[[0.1     0.028   0.00756]
 [0.16    0.0504  0.01008]
 [0.28    0.042   0.0147 ]]
[[0. 3. 2.]
 [0. 3. 2.]
 [0. 3. 3.]]
Y3=argmax[deltaT(i)]=3
Y2=psis3(Y3)=3
Y1=psis2(Y2)=3
最大概率的状态序列Y是:  [[3. 3. 3.]]

4.1.4 实战

链接

https://blog.csdn.net/qq_21201267/article/details/103624237
  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值