隐马尔可夫python_隐马尔可夫模型原理和python实现

隐马尔可夫python_隐马尔可夫模型原理和python实现隐马尔可夫模型 HiddenMarkov HMM 是统计模型 它用来描述一个含有隐含未知参数的马尔可夫过程 其难点是从可观察的参数中确定该过程的隐含参数 隐马尔可夫模型注意包含以下参数 可见状态链 即观测序列 用表示 隐含状态链 隐含状态之间存在转换概率 transitionpr 一般用状态转移矩阵 A 表示 隐含状态和可见状态之间有一个概率叫做输出概率 emis

隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中确定该过程的隐含参数。

隐马尔可夫模型注意包含以下参数:可见状态链,即观测序列,用

隐马尔可夫python_隐马尔可夫模型原理和python实现 表示。

隐含状态链,隐含状态之间存在转换概率(transition probability),一般用状态转移矩阵A表示。

隐含状态和可见状态之间有一个概率叫做输出概率(emission probability),一般用输出观测矩阵B表示。

初始状态,描述初始各隐含状态的概率,用

隐马尔可夫python_隐马尔可夫模型原理和python实现 表示

隐马尔可夫python_隐马尔可夫模型原理和python实现隐马尔可夫模型各参数基本含义和关系

用一个例子来表述隐马尔可夫模型各参数的关系:假设三个盒子隐马尔可夫python_隐马尔可夫模型原理和python实现

按照如下方式进行取球:(1)开始,从三个盒子取球概率分别为0.2,0.4,0.4

(2)从第二次取球开始,设定,若上次从盒子1取球,则下次从三个盒子取球概率为0.5,0.2,0.3;若从盒子2取球,下次从三个盒子取球概率为0.3,0.5,0.2;若从盒子3,下次概率依次为0.2,0.3, 0.5,

重复三次后,得到球观测序列为{红,白,红}。

根据HMM定义,得到,观察集合:{红,白}

状态集合:{盒子1,盒子2,盒子3}

初始状态 [0.2,0.4,0.4]

状态转移概率矩阵隐马尔可夫python_隐马尔可夫模型原理和python实现

观测概率矩阵隐马尔可夫python_隐马尔可夫模型原理和python实现

需要注意观测序列和观测集合是两码事。

HMM求解概率—前向算法

首先说明HMM求观测序列概率的前向后向算法。以前向算法为例。

(1) 计算时刻1的观测为

隐马尔可夫python_隐马尔可夫模型原理和python实现 ,隐含序号为i的各个隐藏状态前向概率:

隐马尔可夫python_隐马尔可夫模型原理和python实现

例如,第一个球为红球,隐藏状态为一号盒子的概率:

隐马尔可夫python_隐马尔可夫模型原理和python实现

隐藏状态为二号盒子的概率:

隐马尔可夫python_隐马尔可夫模型原理和python实现

隐藏状态为三号盒子的概率:

隐马尔可夫python_隐马尔可夫模型原理和python实现

2) 递推时刻2,3,…T时刻观测为,隐含序号为i的各个隐藏状态前向概率的前向概率:

例如时刻2是白色球,隐藏状态是盒子1的概率为:

隐马尔可夫python_隐马尔可夫模型原理和python实现

(3)计算t时刻观测序列的概率

隐马尔可夫python_隐马尔可夫模型原理和python实现

HMM解码—维特比算法,

维特比算法针对的形式,如下图,作用是求第一列到第三列的最短路径。

隐马尔可夫python_隐马尔可夫模型原理和python实现

在HMM模型的解码问题中,一般给定模型状态转移矩阵A,输出观测概率矩阵B,初始状态概率。以及观测序列,求给定观测序列条件下,最可能出现的对应的隐藏状态序列I,即P(I|O)要最大化。例如本例,求三次摸球分别是哪些盒子。相当于已知结果(观测序列,逆推隐藏序列)

维特比算法为动态规划算法,基本思路是先正向计算最大概率,再根据最后一个结点回溯得到前面的结点。定义两个状态转移公式:

(1)时刻t隐藏状态为i所有可能的状态转移路径中的概率最大值。记为

隐马尔可夫python_隐马尔可夫模型原理和python实现

隐马尔可夫python_隐马尔可夫模型原理和python实现

(2)定义在时刻t隐藏状态为i概率最大的转移路径中第t−1个节点(前一个结点)的隐藏状态为

隐马尔可夫python_隐马尔可夫模型原理和python实现 ,用于回溯计算结点:

隐马尔可夫python_隐马尔可夫模型原理和python实现

输入:HMM模型

隐马尔可夫python_隐马尔可夫模型原理和python实现 观测序列O

输出:最有可能的隐藏状态序列I

1)初始化局部状态:

隐马尔可夫python_隐马尔可夫模型原理和python实现

隐马尔可夫python_隐马尔可夫模型原理和python实现

例如本例,时刻1,第一个观测值为红球

隐马尔可夫python_隐马尔可夫模型原理和python实现 =0.2×0.5=0.1

隐马尔可夫python_隐马尔可夫模型原理和python实现 =0.4×0.4=0.16

隐马尔可夫python_隐马尔可夫模型原理和python实现 =0.4×0.7=0.28

2) 进行动态规划递推时刻t=2,3,…T时刻的局部状态:隐马尔可夫python_隐马尔可夫模型原理和python实现

递推三个隐藏状态在时刻2时的动态规划局部状态隐马尔可夫python_隐马尔可夫模型原理和python实现

递推三个隐藏状态在时刻3时的动态规划局部状态隐马尔可夫python_隐马尔可夫模型原理和python实现

(3)根据最大概率局部状态进行回溯,其中

隐马尔可夫python_隐马尔可夫模型原理和python实现

T=3时其中

隐马尔可夫python_隐马尔可夫模型原理和python实现 最大,回溯自

隐马尔可夫python_隐马尔可夫模型原理和python实现

到T=2时得到

隐马尔可夫python_隐马尔可夫模型原理和python实现 ,回溯到

隐马尔可夫python_隐马尔可夫模型原理和python实现

从而得到最终的最可能的隐藏状态序列为:(3,3,3)

代码:

class HMM(object):

def __init__(self):

self.A=array([(0.5,0.2,0.3),(0.3,0.5,0.2),(0.2,0.3,0.5)])

self.B=array([(0.5,0.5),(0.4,0.6),(0.7,0.3)])

self.pi=array([(0.2),(0.4),(0.4)])

self.o=[0,1,0]

self.t=len(self.o)#观测序列长度

self.m=len(self.A)#状态集合大小

self.n=len(self.B[0])#观测集合大小

def forward(self):

#t时刻部分观测序列为o1,o2,ot,状态为qi的概率用矩阵x表示,

#则矩阵大小行数为观测序列数,列数为状态个数

self.x=array(zeros((self.t,self.m))) #先计算出时刻1时,观测为o[0]的概率

for i in range(self.m): # 对隐藏集合遍历

self.x[0][i]=self.pi[i]*self.B[i][self.o[0]] # 初始某状态的概率*观测状态概率(输出状态为o1)

for j in range(1,self.t):

for i in range(self.m):

#前一时刻所有状态的概率乘以转移概率得到i状态概率

#i状态的概率*i状态到j观测的概率

temp=0

for k in range(self.m):

temp=temp+self.x[j-1][k]*self.A[k][i]

self.x[j][i]=temp*self.B[i][self.o[j]]

result=0

for i in range(self.m):

result=result+self.x[self.t-1][i]

print (u”前向概率矩阵及当前观测序列概率如下:”)

print (self.x)

print (result)

def viterbi(self):

# 维特比方法的对象是两个矩阵

#利用模型和观测序列找出最优的状态序列

#每个路径都有自己的概率,最大的概率用矩阵z记录,前一个状态用d矩阵记录

# self.t=len(self.o)#观测序列长度

# self.m=len(self.A)#状态集合大小

self.z=array(zeros((self.t,self.m))) # 3*3的矩阵

self.d=array(zeros((self.t,self.m)))

for i in range(self.m): # 初始状态

self.z[0][i]=self.pi[i]*self.B[i][self.o[0]]

self.d[0][i]=0

for j in range(1,self.t):

for i in range(self.m):

maxnum=self.z[j-1][0]*self.A[0][i]

node=1

for k in range(1,self.m): # 求最大转移概率

temp=self.z[j-1][k]*self.A[k][i]

if(maxnum

maxnum=temp

node=k

self.z[j][i]=maxnum*self.B[i][self.o[j]] # 转移序列状态

self.d[j][i]=node # 上个状态的结点

#找到T时刻概率的结点

print (“概率顺序”,self.d)

print (“路径概率”,self.z)

max_probability=self.z[self.t-1][0]

node_path = []

temp=0

for i in range(1,self.m):

if(max_probability < self.z[self.t-1][i]):

max_probability=self.z[self.t-1][i]

temp=i

i=self.t-1

temp = int(temp)

node_path.append(temp+1)

#self.d[t][p],t时刻状态为p的时候,t-1时刻的状态

#回溯,找到路径

while(i>=1):

#last_node.append(self.d[i][temp])

node_path.append(int (self.d[i][temp]+1))

temp = int (self.d[i][temp])

i=i-1

node_path.reverse()

print (u’路径节点分别为’)

print (“node_path”, node_path)

print (u’该路径概率为’+str(max_probability))

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/217590.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午9:14
下一篇 2026年3月18日 上午9:14


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号