一.理论部分


由于网上很多都讲过马尔科夫的直接求解,但其时间复杂度太高了,在实际基本上不用,在这里,我就直入主题,了解我们最常用的前向算法。




(1)部分概率

下面这张图表示了一个观察序列(dry,damp,soggy)的一阶转移


前向最大匹配算法 Java实现 前向算法例题_机器学习








我们可以通过计算到达某个状态的所有路径的概率和来计算到达某个中间状态的概率。比如说,t=2时刻,cloudy的概率用三条路径的概率之和来表示:




前向最大匹配算法 Java实现 前向算法例题_matlab_02










我们用 αt(j) 来表示在 t 时刻是状态 j 的概率,αt(j)=Pr(观察状态 | 隐藏状态 j ) x Pr(t 时刻到达状态 j 的所有路径)。

最后一个观察状态的部分概率就表示了整个序列最后达到某个状态的所有可能的路径的概率和,比如说在这个例子中,最后一列的部分状态是通过下列路径计算得到的:




前向最大匹配算法 Java实现 前向算法例题_混淆矩阵_03








因为最后一列的部分概率是所有可能的路径的概率和,所以就是这个观察序列在给定 HMM 下的概率了。


(2)计算 t=1时候的部分概率

t=1 的时候,没有路径到某个状态,所以这里是初始概率,Pr(状态 j | t=0) = π(状态 j ),这样我们就可以计算 t=1 时候的部分概率为:

                       

前向最大匹配算法 Java实现 前向算法例题_混淆矩阵_04

 

因为在初始的时候,状态 j 的概率不仅和这个状态本身相关,还和观察状态有关,所以这里用到了混淆矩阵的值,k1 表示第一个观察状态,bjk1 表示隐藏状态是 j,但是观察成 k1 的概率。

(3) 计算 t>1 时候的部分概率

还是看计算部分概率的公式是:αt(j) = Pr(观察状态 | 隐藏状态 j) x Pr(t 时刻到达状态 j 的所有路径)。 这个公式的左边是从混淆矩阵中已知的,我只需要计算右边部分,很显然右边是所有路径的和:

前向最大匹配算法 Java实现 前向算法例题_matlab_05




需要计算的路径数是和观察序列的长度的平方相关的,但是 t 时刻的部分概率已经计算过了之前的所有路径,所以在 t+1 时刻只需要根据 t 时刻的概率来计算就可以了:



前向最大匹配算法 Java实现 前向算法例题_matlab_06

前向最大匹配算法 Java实现 前向算法例题_算法_07


前向最大匹配算法 Java实现 前向算法例题_混淆矩阵_08


(5)t=T时观察序列的概率

此等于T时刻所有局部概率之和,就是我们所需要的最终的观测概率

前向最大匹配算法 Java实现 前向算法例题_matlab_09


二.例子部分

例如:已知隐马尔科夫模型如下:

(天气):Sunny,Cloudy,Rainy;
  2、观察状态(海藻湿度):Dry,Dryish,Damp,Soggy;
  3、初始状态概率: Sunny(0.63), Cloudy(0.17), Rainy(0.20);
  4、状态转移矩阵:

前向最大匹配算法 Java实现 前向算法例题_机器学习_10


    

5、混淆矩阵:

前向最大匹配算法 Java实现 前向算法例题_matlab_11





   提取出来的值

        M= 4%隐藏状态数目;Q={1,2,…,N}    
    N= 3%观察状态数目; V={1,2,…,M}

    A:%状态转移矩阵A[1..N][1..N]. a[i][j] 是从t时刻状态i到t+1时刻状态j的转移概率
    0.500 0.375 0.125
    0.250 0.125 0.625
    0.250 0.375 0.375

 

    B:%混淆矩阵B[1..N][1..M]. b[j][k]在状态j时观察到符合k的概率
    0.60 0.20 0.15 0.05
    0.25 0.25 0.25 0.25
    0.05 0.10 0.35 0.50

    pi:%初始向量pi[1..N],pi[i] 是初始状态概率分布
    0.63 0.17 0.20

 

%观测序列的长度

%给出的观察序列“Dry,Damp,Soggy”相当于文中所说的kt.

 

 

 

所有的准备工作都做好了,下面来用matlab编写代码进行测试:

编写的matlab代码如下:



N=3;%隐藏状态数目;Q={1,2,…,N}    A对应的列数
M=4;%观察符号数目; V={1,2,…,M}   B对应的列数
A= [0.500 0.375 0.125;%状态转移矩阵A[1..N][1..N]. a[i][j] 是从t时刻状态i到t+1时刻状态j的转移概率
    0.250 0.125 0.625;
    0.250 0.375 0.375];
B=[0.60 0.20 0.15 0.05;%混淆矩阵B[1..N][1..M]. b[j][k]在状态j时观察到符合k的概率
   0.25 0.25 0.25 0.25;%也称为输出符号的概率分布矩阵
   0.05 0.10 0.35 0.50];
pai=[0.63 0.17 0.20];%初始向量pi[1..N],pi[i] 是初始状态概率分布
T=3;%观测序列的长度
O=[1 3 4];%给出的观察序列“Dry,Damp,Soggy”
 
%1。初始化
for i=1:N
    alpha(1,i)=pai(i)*B(i,O(1));
end
 
%2.递推求局部的中间值
for t=1:T-1
    for j=1:N
        sum0=0;
        for i=1:N
            sum0=sum0+alpha(t,i)*A(i,j);
        end
        alpha(t+1,j)=sum0*B(j,O(t+1));
    end
end
 
%3.最终
pprob=0;
    for i=1:N
        pprob=alpha(T,i)+pprob;
    end
 
    alpha
    pprob





运行的结果为:

前向最大匹配算法 Java实现 前向算法例题_matlab_12



看看到底我的代码编写是否有误?下面我们来通过具体的计算一步一步的验证代码。T=3

(1)计算初值(t=1)

(2)t=2时(套用递推公式)




前向最大匹配算法 Java实现 前向算法例题_机器学习_13


前向最大匹配算法 Java实现 前向算法例题_混淆矩阵_14



(3)t=3(T=t)时

前向最大匹配算法 Java实现 前向算法例题_机器学习_15


(1)最终

 Pprob=0.0016+0.0066+0.0188= 0.0270(与结果0.269其实是一样的,是计算过程中为保留精确小数的原因),所以过程验算的与结果一样


参考资料

(1)http://www.52nlp.cn/hmm-learn-best-practices-five-forward-algorithm-5