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

目录

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

前向概率

给定隐马尔可夫模型 λ \lambda λ,定义到时刻 t t t部分观测序列为 o 1 , o 2 , ⋯   , o t o_1,o_2,\cdots,o_t o1,o2,,ot且状态为 s i s_i si的概率为前向概率,记作 α t ( i ) = P ( o 1 , o 2 , ⋯   , o t , i t = s i ∣ λ ) \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)初值
α 1 ( i ) = π i b i ( o 1 ) ,          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 − 1 t=1,2,\cdots,T-1 t=1,2,,T1
α t + 1 ( i ) = [ ∑ j = 1 N α t ( j ) a j i ] b i ( o t + 1 ) ,          i = 1 , 2 , ⋯   , N 示例      t = 1 ,    i = 1 α 2 ( 1 ) = [ ∑ j = 1 N α 1 ( j ) a j 1 ] b 1 ( o 2 ) t = 1 ,    i = 2 α 2 ( 2 ) = [ ∑ j = 1 N α 1 ( j ) a j 2 ] b 2 ( o 2 ) t = 1 ,    i = 3 α 2 ( 3 ) = [ ∑ j = 1 N α 1 ( j ) a j 3 ] b 3 ( o 2 ) \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 = 1 N α 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 np

class 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 result

    def 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项目 前向概率计算笔记_第2张图片

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

你可能感兴趣的:(学习笔记,人工智能,深度学习,自然语言处理)