> 文章列表 > 【博学谷学习记录】超强总结,用心分享丨人工智能 AI项目 前向概率计算笔记

【博学谷学习记录】超强总结,用心分享丨人工智能 AI项目 前向概率计算笔记

【博学谷学习记录】超强总结,用心分享丨人工智能 AI项目 前向概率计算笔记

目录

    • 前向概率
      • 模型基础参数
      • 公式推导
      • 代码实现

前向概率

给定隐马尔可夫模型λ\\lambdaλ,定义到时刻ttt部分观测序列o1,o2,⋯,oto_1,o_2,\\cdots,o_to1,o2,,ot且状态为sis_isi的概率为前向概率,记作αt(i)=P(o1,o2,⋯,ot,it=si∣λ)\\alpha_t(i)=P(o_1,o_2,\\cdots,o_t,i_t=s_i|\\lambda)αt(i)=P(o1,o2,,ot,it=siλ)。可以递推地求出前向概率αt(i)\\alpha_t(i)αt(i)以及观测序列概率P(O∣λ)P(O|\\lambda)P(Oλ)

模型基础参数

【博学谷学习记录】超强总结,用心分享丨人工智能 AI项目 前向概率计算笔记

公式推导

(1)初值
α1(i)=πibi(o1),i=1,2,⋯,N\\alpha_1(i)=\\pi_i b_i (o_1),\\;\\;\\;\\;i=1,2,\\cdots,N α1(i)=πibi(o1),i=1,2,,N

第一个时刻,i代表不同的状态,pi表示初始概率,b为发射概率,如:从5个盒子中抽球,第一个抽到红球,i对应的就是1,b为红球在第一个盒子中被抽出来的概率(发射概率)
结果是5个数据,第i数据表示第1个时刻从第i球中抽出红球的概率

(2)递推 对t=1,2,⋯,T−1t=1,2,\\cdots,T-1t=1,2,,T1
αt+1(i)=[∑j=1Nαt(j)aji]bi(ot+1),i=1,2,⋯,N示例t=1,i=1α2(1)=[∑j=1Nα1(j)aj1]b1(o2)t=1,i=2α2(2)=[∑j=1Nα1(j)aj2]b2(o2)t=1,i=3α2(3)=[∑j=1Nα1(j)aj3]b3(o2)\\alpha_{t+1}(i)=\\left[\\sum_{j=1}^{N}\\alpha_t(j)a_{ji}\\right]b_i(o_{t+1}),\\;\\;\\;\\;i=1,2,\\cdots,N \\\\ \\\\ 示例\\;\\;t=1,\\;i=1\\\\ \\alpha_2(1)=\\left[\\sum_{j=1}^{N}\\alpha_1(j)a_{j1}\\right]b_1(o_2)\\\\ t=1,\\;i=2\\\\ \\alpha_2(2)=\\left[\\sum_{j=1}^{N}\\alpha_1(j)a_{j2}\\right]b_2(o_2)\\\\ t=1,\\;i=3\\\\ \\alpha_2(3)=\\left[\\sum_{j=1}^{N}\\alpha_1(j)a_{j3}\\right]b_3(o_2)\\\\ αt+1(i)=[j=1Nαt(j)aji]bi(ot+1),i=1,2,,N示例t=1,i=1α2(1)=[j=1Nα1(j)aj1]b1(o2)t=1,i=2α2(2)=[j=1Nα1(j)aj2]b2(o2)t=1,i=3α2(3)=[j=1Nα1(j)aj3]b3(o2)

第二个时刻则是前一个时刻求出的5个数据,每个数据乘转移概率和再乘当前时刻的发射概率
a(t)j表示上个时刻求出的5个值,aji表示从j状态转移到i状态的概率

(3)终止
P(O∣λ)=∑i=1NαT(i)P(O|\\lambda)=\\sum_{i=1}^{N}\\alpha_T(i) P(Oλ)=i=1NαT(i)

概率求和(算出的5个状态分别对应的值进行求和)

代码实现

随机从4个盒子中抽出5个球 ,求该序列的概率
前向概率计算函数:forward_probability()其中是通过矩阵运算,所以公式的求和的符号可能提现的不明显,可以输出运算后结果进而理解运算过程

import numpy as npclass HMM(object):def __init__(self, N, M, pi=None, A=None, B=None):self.N = N # 盒子数量self.M = M # 球颜色数量self.pi = pi # 初始概率向量self.A = A # 转移概率矩阵self.B = B # 观测概率矩阵def get_data_with_distribute(self, dist):# 根据给定的概率分布,返回一个索引return np.random.choice(np.arange(len(dist)), p=dist)def generate(self, T : int):# T 要生成的数据的数量# 根据给定额参数生成观测序列# 根据初始概率分布,获取从哪个盒子取第一个球z = self.get_data_with_distribute(self.pi) # 得到的是第一个盒子的编号# 从上一个盒子中根据观测概率选中一个球(颜色)x = self.get_data_with_distribute(self.B[z]) #x代表球的颜色,0红色 1白色result = [x]for _ in range(T-1):z = self.get_data_with_distribute(self.A[z]) # 得到下一个盒子x = self.get_data_with_distribute(self.B[z]) # 从该盒子中随机选中一个颜色result.append(x)return resultdef forward_probability(self, X):# 根据给定的观测序列X,计算观测序列出现的概率alpha = self.pi * self.B[:, X[0]]# print(type(alpha))for x in X[1:]:# print(alpha)# print(self.A)# print(np.matmul(alpha, self.A))alpha = np.matmul(alpha, self.A) * self.B[:, x]return alpha.sum()if __name__ == '__main__':pi = np.array([.25, .25, .25, .25])A = np.array([[0,  1,  0, 0],[.4, 0, .6, 0],[0, .4, 0, .6],[0, 0, .5, .5]])B = np.array([[.5, .5],[.3, .7],[.6, .4],[.8, .2]])assert len(A) == len(pi)assert len(A) == len(B)hmm = HMM(B.shape[0], B.shape[1], pi, A, B)seq = hmm.generate(5)print('抽出球的序列:', seq)print('概率值:', hmm.forward_probability(seq))

结果:白白红红白
【博学谷学习记录】超强总结,用心分享丨人工智能 AI项目 前向概率计算笔记

心得:通过理解公式后再去理解运算过程和代码会很简单,关于矩阵运算对应到公式起初理解困难,多思考,多打印结果值,理解每步后方可打通任督二脉