隐马尔可夫模型(HMM)的MATLAB实现——前向后向算法

由于研究需要,在网上找了不少关于隐马尔可夫模型的MATLAB程序,可能是没有耐下心去看,总之感觉看懂别人写的程序很费劲,所以就自己动手写了一下。

主要的参考书目是李航的《统计学习方法》,并实现了书中部分例题和习题的解答,关于隐马尔可夫模型的理论知识不再赘述,这方面的经典论文和网上的优秀博客很多,这里介绍两篇经典的论文:

1,Bilmes L,et al. A Gentle Tutorial of EM Algorithm and its Application to Parameter Estimation for Gaussian Mixture and Hidden Markov Models(1997)
 2,Rabiner L. A Tutorial on Hidden Markov Models and Selected Applications in Speech Recognition(1989)

下面按照HMM的三个问题:概率计算,参数学习和解码顺序介绍我的代码。

1,概率计算问题--前向后向算法

function [P1,P2,p1] = ForwardBackwardAlgo(A,B,Pi,O)
% 函数功能:前向后向算法,计算alpha值矩阵P1和beta值矩阵P2
%
% 参考文献:李航《统计学习方法》
%
% 思路:
% 给定模型lambda和观测序列O,在时刻t处于状态qi的概率,记做
% gamma_t(i) = P(it = qi|O,lambda) = P(it = qi,O|lambda) / P(O|lambda)
% P(it = qi,O|lambda) = alpha_t(i) * beta_t(i)
% 在这里,alpha矩阵表示前向概率矩阵,放在矩阵P1中,且为i*t阶
%         beta矩阵表示后向概率矩阵,放在矩阵P2中,且为i*t阶
%         
% 输入:隐马尔可夫模型lambda(A,B,Pi),观测序列O;
%       其中A为转移概率,B为观测概率(行数表示状态集合中的元的个数,列数表示观测集中的元的个数);
%       Pi为初始概率,P为1*2阶矩阵,存放所求概率P(it = qi,O|lambda)中it和qi的角标t和i,即P=[t,i]
%       【!!注意:初始概率Pi、观测序列O以及矩阵P均须为列矩阵】
% 输出:P1:alpha值构成的矩阵,为i*t阶
%       P2:beta值构成的矩阵,为i*t阶
%       p1:观测序列概率P(O|lambda)
%       
% 示例:(李航《统计学虚方法》P188习题10.1)
% 输入:
% A1 =
%     0.5000    0.1000    0.4000
%     0.3000    0.5000    0.2000
%     0.2000    0.2000    0.6000
% B1 =
%     0.5000    0.5000
%     0.4000    0.6000
%     0.7000    0.3000
% Pi =
%     0.2000
%     0.3000
%     0.5000
% O =
%      1
%      2
%      1
%      2
% 输出
% P1 =
%     0.1000    0.0770    0.0419    0.0211
%     0.1600    0.1104    0.0355    0.0252
%     0.2800    0.0606    0.0528    0.0138
% P2 =
%     0.1125    0.2461    0.4600    1.0000
%     0.1217    0.2312    0.5100    1.0000
%     0.1049    0.2577    0.4300    1.0000
% p1 =
%     0.0601
alpha_1 = zeros();
sum_alpha_j = zeros();
sum_beta_i = zeros();
% sum_p = zeros();
P1 = zeros();
A_size = size(A);
O_size = size(O);
N = A_size(1,1);
M = A_size(1,2);
K = O_size(1,1);
P2 = zeros(N,K);
%
% ---------------前向算法---------------
%求解初值
for i = 1:N
    alpha_1(i,1) = Pi(i,1) * B(i,O(1,1));
end
P1= alpha_1;
%递推求解前向概率,存放在矩阵P1中
for k = 1:K-1
    for j = 1:M
        for i = 1:N
           sum_alpha_j(i,1) = P1(i,k) .* A(i,j);
        end
        P1(j,k+1) = sum(sum_alpha_j) .* B(j,O(k+1,1));
    end
end
%计算观测概率P(O|lambda)
 p1 = sum(P1(:,K));
 %
% ----------------后向算法---------------
% 对最终时刻所有状态有beta_T(i) = 1
P2(:,K) = 1;
% 递推求解后向概率,存放在矩阵P2中
for k = K-1:-1:1
    for i = 1:M
        for j = 1:N
            sum_beta_i(j,1) = A(i,j) .* B(j,O(k+1,1)) .* P2(j,k+1);
        end
        P2(i,k) = sum(sum_beta_i);
    end
end
上述程序中的例子用的是后向概率的算法,程序中前向算法和后向算法可以单独拿出来进行计算,另外,李航《统计学习方法》中P189的习题10.2也可以计算得到,
其代码中调用上述程序函数,代码如下
function [p1,p2] = ForwardBackwardAppli(A,B,Pi,O,P)
% 函数功能:前向后向算法应用,计算P(it = qi|O,lambda)
%
% 参考文献:李航《统计学习方法》
%
% 思路:
% 给定模型lambda和观测序列O,在时刻t处于状态qi的概率,记做
% gamma_t(i) = P(it = qi|O,lambda) = P(it = qi,O|lambda) / P(O|lambda)
% P(it = qi,O|lambda) = alpha_t(i) * beta_t(i)
% 在这里,alpha矩阵表示前向概率矩阵,放在矩阵P1中,且为i*t阶
%         beta矩阵表示后向概率矩阵,放在矩阵P2中,且为i*t阶
%         
% 输入:隐马尔可夫模型lambda(A,B,Pi),观测序列O;
%       其中A为转移概率,B为观测概率(行数表示状态集合中的元的个数,列数表示观测集中的元的个数),Pi为初始概率;
%       P为1*2阶矩阵,存放所求概率P(it = qi,O|lambda)中it和qi的角标t和i,即P=[t,i]
%       【!!注意:初始概率Pi、观测序列O以及矩阵P均须为列矩阵】
% 输出:p1:观测序列概率P(O|lambda)
%       p2:所求概率P(it = qi|O,lambda)
%       
% 示例:(李航《统计学习方法》P189习题10.2)
% 输入:
% A1 =
%     0.5000    0.1000    0.4000
%     0.3000    0.5000    0.2000
%     0.2000    0.2000    0.6000
% B1 =
%     0.5000    0.5000
%     0.4000    0.6000
%     0.7000    0.3000
% Pi =
%     0.2000
%     0.3000
%     0.5000
% O3 =
%      1
%      2
%      1
%      1
%      2
%      1
%      2
%      2   
% P =
%      4
%      3
%
% 输出
% [a7,b7] = ForwardBackwardAlgo(A1,B1,Pi,O3,P)
% a7 =
%     0.0035
% b7 =
%     0.5370
P1 = zeros();
A_size = size(A);
O_size = size(O);
N = A_size(1,1);
M = A_size(1,2);
K = O_size(1,1);
P2 = zeros(N,K);
%
% 调用函数前向后向算法ForwardBackwardAlgo_1,计算得到alpha矩阵P1,beta矩阵P2观测序列O的概率p1
[P1,P2,p1] = ForwardBackwardAlgo(A,B,Pi,O);
%
% 计算所求值
p2 = P1(P(2,1),P(1,1)) * P2(P(2,1),P(1,1)) / p1;



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值