Matlab统计学工具箱之(隐)马尔可夫模型:Markov Models


原文:https://chunqiu.blog.ustc.edu.cn/?p=454

目录

马尔科夫链

隐马尔科夫模型(HMM)

HMM简介

分析隐马尔科夫模型

产生测试序列

估计状态序列

估计状态转移矩阵和输出矩阵

估计后验状态概率

改变初始状态分布

 

马尔科夫链

         如下图的马尔科夫模型状态转移矩阵

 

         图中的方框代表你要建模过程的可能状态,箭头表示状态间的转移情况。箭头上的标签表示转移概率。在过程中的每一步,模型会产生一个输出(决定于所处的状态)然后转移到另一个状态。马尔科夫模型的一个重要特性是下一个状态只与当前的状态有关,与过去的转移无关。

         例如,对于一个顺序抛掷硬币的过程,存在两个状态:正和反。最近一次的投掷决定了模型当前的状态,下一次投掷决定了如何转移到下一状态。如果硬币是公平的,则转移概率都是二分之一,输出就是当前的状态。在更复杂的模型中,每一个状态可以以一个随机过程产生输出,如可以通过投掷骰子来决定输出。

         马尔科夫链是离散状态马尔科夫模型的数学描述。马尔科夫链如下定义:

l  一系列状态{1,2,…,M};

l  一个MXM的状态转移矩阵T,其中Tij表示从状态i到j的状态转移概率。矩阵每行的和为1,因为它表示从一个给定状态到其他各状态的所有转移概率的和。

l  一系列可能的输出{s1,s2,…,sN},默认时可以当做{1,2,…,N},N为可能输出的个数,当然你可以选择不同的数据集或符号来表示;

l  一个MXN的输出矩阵E,其中Eik表示模型在状态i时的输出sk的概率。

马尔科夫链的过程:从第0步的初始状态i0开始;然后以概率T1i1转移到状态i1,并以概率Ei1k1输出sk1;最后,以概率T1i1 Ei1k1 Ti1i2 Ei2k2 … Tir-1ir Eirk观察到状态i1i2…ir,同时输出sk1sk2…skr。

 

隐马尔科夫模型(HMM)

HMM简介

         隐马尔科夫模型是你只观察到输出,但不知道模型产生输出所经历的状态。隐马尔科夫模型分析就是从观察的数据恢复相关的状态序列。

         例如,考虑一个有2个状态6个可能输出的马尔科夫模型,模型中用到

n  一个红骰子,6个面,分别标号1~6;

n  一个绿骰子,12个面,5个面标号2~6,其他面标记1;

n  一个非均衡的红硬币,以0.9的概率掷出正,0.1的概率掷出反;

n  一个非均衡的绿硬币,以0.95的概率掷出正,0.05的概率掷出反。

模型以下面的规则产生一系列来自{1,2,3,4,5,6}的数字序列:

n  先掷红骰子,记下骰子的输出;

n  然后掷红硬币:

l  如果是正,则掷红骰子记下结果;

l  否则掷绿骰子记结果;

n  接下来的下一步,掷与上一步所用骰子同颜色的硬币,如果是正,则掷同颜色的骰子;否则掷另一个骰子。

模型的状态转移图如下

 

         这个模型中,通过掷与状态同颜色的骰子来决定输出,通过掷与状态同颜色的硬币来决定转移到哪一状态。

         状态转移矩阵为

 

         输出矩阵为

 

         这个模型是非隐的,因为你从硬币、骰子的颜色可以知道状态序列。如果假设有人产生了一系列输出,但不给你展示硬币和骰子,所有你能看到的只是输出序列。如果你开始看到1出现的次数比其他都多,你可能会假设模型处于绿状态,但你不能确定,因为你不能看到所掷骰子的颜色。

         隐马尔科夫模型提出了如下问题:

1)         给定输出序列,求最可能的状态序列?

2)         给定输出序列,你如何估计模型的转移概率和输出概率?

3)         模型得出给定序列的先验概率?

4)         模型在序列某一位置是特定状态的后验概率?

分析隐马尔科夫模型

         与隐马尔科夫模型有关的统计工具箱函数如下

l  Hmmgenerate——从一个马尔科夫模型产生状态、输出序列;

l  Hmmestimate——从输出序列和已知的状态序列计算转移、输出序列概率的极大似然估计;

l  Hmmtrain——从输出序列计算转移、输出序列概率的极大似然估计;

l  Hmmviterbi——计算隐马尔科夫模型的最大可能状态序列;

l  Hmmdecode——计算输出序列的状态后验概率。

下面来讲如何使用这些函数分析隐马尔科夫模型。

产生测试序列

         下面的命令创建状态转移矩阵和输出矩阵

TRANS = [.9 .1; .05 .95;];

 

EMIS = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6;...

7/12, 1/12, 1/12, 1/12, 1/12, 1/12];

        要产生一组状态和输出的随机序列,使用函数hmmgenerate

[seq,states] = hmmgenerate(1000,TRANS,EMIS);

输出参数seq为输出序列,states为状态序列。

         Hmmgenerate函数第0步开始于状态1,然后第一步转移到状态i1,而i1作为states的第一个元素。如果要改变初始状态,看后面的改变初始状态分布一节。

估计状态序列

         给定状态转移矩阵TRANS和输出矩阵EMIS,函数hmmviterbi使用Viterbi算法计算产生给定输出序列seq的极大可能状态序列

likelystates = hmmviterbi(seq, TRANS, EMIS);

likelystates与seq长度相同。

         为了测试hmmviterbi的精确度,计算实际状态序列states与估计状态序列likelystates吻合的百分比

sum(states==likelystates)/1000

ans =

   0.8200

         在这个例子中,估计的状态和实际吻合达82%

估计状态转移矩阵和输出矩阵

函数hmmestimate和hmtrain可以用来根据给定的输出序列估计状态转移矩阵和输出矩阵。

使用hmmestimate

         此函数需要你知道产生输出序列的状态序列。基于输出序列和状态序列,如下估计转移矩阵和输出矩阵

[TRANS_EST, EMIS_EST] = hmmestimate(seq, states)

 

TRANS_EST =

0.8989    0.1011

0.0585    0.9415

 

EMIS_EST =

0.1721    0.1721    0.1749    0.1612    0.1803    0.1393

0.5836    0.0741    0.0804    0.0789    0.0726    0.1104

         与原始的序列对比

TRANS

TRANS =

0.9000    0.1000

0.0500    0.9500

 

EMIS

EMIS =

0.1667    0.1667    0.1667    0.1667    0.1667    0.1667

0.5833    0.0833    0.0833    0.0833    0.0833    0.0833

使用hmmtrain

         如果你不知道状态序列,但知道TRANS和EMIS矩阵的初始猜测,可以使用hmmtrain函数估计。

         假设已知TRANS和EMIS矩阵的初始猜测如下

TRANS_GUESS = [.85 .15; .1 .9];

EMIS_GUESS = [.17 .16 .17 .16 .17 .17;.6 .08 .08 .08 .08 08];

下面做矩阵估计

[TRANS_EST2, EMIS_EST2] = hmmtrain(seq, TRANS_GUESS, EMIS_GUESS)

 

TRANS_EST2 =

0.2286    0.7714

0.0032    0.9968

 

EMIS_EST2 =

0.1436    0.2348    0.1837    0.1963    0.2350    0.0066

0.4355    0.1089    0.1144    0.1082    0.1109    0.1220

         Hmmtrain函数使用迭代算法调整TRANS_GUESS和EMIS_GUESS,使得基于调整的矩阵产生更加类似于观察序列seq的输出。当两次迭代中矩阵的变化不大时迭代结束。

         如果如果算法在默认的最大迭代次数100次以内仍没结束,将返回迭代的最后结果并产生一个警告。这时可以通过增加最大迭代次数来增大迭代的次数

hmmtrain(seq,TRANS_GUESS,EMIS_GUESS,'maxiterations',maxiter)

maxiter是新设的最大迭代次数。

还可以改变默认的最小容忍值

hmmtrain(seq, TRANS_GUESS, EMIS_GUESS, 'tolerance', tol)

tol为新设的最小容忍值,增大它可以让算法更快的停止,但结果将不精确。

         两个因素将降低hmmtrain函数估计结果的可靠性:

l  算法收敛到一个局部极大值,但此极大值并不是真正的状态转移矩阵与输出矩阵的位置。对此,可以使用多个不同的初始猜测值来估计,使用最好的结果;

l  Seq序列太短,以至于不足以训练矩阵,对此,可以使用更长的seq序列。

估计后验状态概率

输出序列seq的后验状态概率是模型给出seq序列时所处状态的后验概率。可以使用hmmdecode函数计算后验状态概率:

PSTATES = hmmdecode(seq,TRANS,EMIS)

         随着序列长度的增加,序列的概率会趋向于0,所以一个足够长的序列的概率将小于计算机的最小精度,为了避免此问题,hmmdecode还返回了概率的对数值。

改变初始状态分布

         默认地,统计工具箱的隐马尔科夫模型函数是从状态1开始的。换句话说,初始状态的分布集中在状态1处,其他位置为0。如果想给初始状态赋予一个概率分布p=[p1,p2,…,pM],可以如下实现

  1. 创建一个M+1XM+1的辅助状态转移矩阵如下

 

其中的T是真正的状态转移矩阵,第一列包含M+1个0,向量p的和为1。

  1. 创建M+1XN的辅助输出矩阵如下

 

         如果状态转移矩阵与输出矩阵式TRANS和EMIS,可以使用如下命令创建辅助矩阵

TRANS_HAT = [0 p; zeros(size(TRANS,1),1) TRANS];

 EMIS_HAT = [zeros(1,size(EMIS,2)); EMIS];

 

原文:http://www.aiseminar.cn/bbs/forum.php?mod=viewthread&tid=596

此文讲述的内容在Matlab 7.0、7.5(R2007b)中均有――马尔可夫工具箱,主要内容如下。

简介:马尔可夫处理是随机处理的一个典型例子――此种处理根据特定的概率产生随机输出或状态序列。马尔可夫处理的特别之处在于它的无记忆性――他的下一个状态仅依赖他的当前状态,不考虑导致他们的历史。马尔可夫处理的模型在实际应用中使用非常广泛,从每日股票价格到染色体中的基因位置都有应用。

马尔可夫链

马尔可夫模型用状态图可视化描述如下。
<ignore_js_op> 

在图中,矩形代表你要描述的模型在处理中可能出现的状态,箭头描述了状态之间的转换。每个箭头上的标签表明了该转换出现的概率。在处理的每一步,模型都可能根据当前状态产生一种output或emission,然后做一个到另一状态的转换。马尔可夫模型的一个重要特点是:他的下个状态仅仅依赖当前状态,而与导致其成为当前状态的历史变换无关。

马尔可夫链是马尔可夫模型的一组离散状态集合的数学描述形式。马尔可夫链特征归纳如下:

1. 一个状态的集合{1, 2, ..., M}
2. 一个M * M的转移矩阵T,(i, j)位置的数据是从状态i转到状态j的概率。T的每一行值的和必然是1,因为这是从一个给定状态转移到其他所有可能状态的概率之和。
3. 一个可能的输出(output)或发布(emissions)的集合{S1, S2, ..., SN}。默认情况下,发布的集合是{1, 2, ..., N},这里N是可能的发布的个数,当然,你也可以选择一个不同的数字或符号的集合。
4. 一个M * N的发布矩阵E,(i, k)入口给出了从状态i得到发布的标志Sk的概率。

马尔可夫链在第0步,从一个初始状态i0开始。接着,此链按照T(1, i1)概率转移到状态i1,且按概率E(i1, k1)概率发布一个输出S(k1)。因此,在前r步,状态序列(i1, i2, i3, ..., ir)和发布序列(Sk1, Sk2, ..., Skr)的可能的观测结果是
T(1, i1)E(i, k1), T(i1, i2)E(i2, k2), ..., T(ir-1, ir)E(ir, k)


隐马尔可夫模型

简介:隐马尔可夫模型相对马尔可夫模型的不同之处在于,你观测到一组发布序列,但是却不知道模型通过什么样的状态序列得到这样的发布。隐马尔可夫模型分析就是要从观测数据恢复出这一状态序列。

一个例子:考虑一个拥有2个状态和6个位置发布的马尔可夫模型。模型描述如下:

1. 一个红色骰子,有6个面,标记为1到6。
2. 一个绿色骰子,有12个面,有5个标记为2到6,余下的全标记为1。
3. 一个加权的红硬币,正面的概率是0.9,背面的概率是0.1。
4. 一个加权的绿硬币,正面的概率为0.95,背面的概率为0.05。

这个模型按照下面的规则从集合{1, 2, 3, 4, 5, 6}产生一个数字序列:

1. 从滚动红骰子开始,记下出现的数字,作为发布结果。
2. 投红硬币:
如果结果是正面,滚动红骰子,记下结果;
如果结果是背面,滚动绿骰子,记下结果。
3. 在下面的每一步,你都抛和前一步所投骰子相同颜色的硬币。如果硬币出现正面,滚和硬币相同颜色的骰子。如果硬币出现反面,改为投另种颜色的骰子。

这个模型的状态图如下,有两个状态,红和绿:
<ignore_js_op> 
通过投掷和状态一样颜色的骰子来解决输出(发布),通过抛同样颜色的硬币来决定状态的转移。

状态转移概率矩阵为:
>> T = [0.9 0.1; 0.05 0.95]
T =
    0.9000    0.1000
    0.0500    0.9500

输出或发布概率矩阵为:
>> E = [1/6 1/6 1/6 1/6 1/6 1/6; 7/12 1/12 1/12 1/12 1/12 1/12]
E =
    0.1667    0.1667    0.1667    0.1667    0.1667    0.1667
    0.5833    0.0833    0.0833    0.0833    0.0833    0.0833

这个模型并不是隐藏的,因为我们从硬币和骰子的颜色已经知道状态序列。假设,有其他人产生了一个发布结果,而没有向你展示硬币和骰子,你能看到的只有结果。当你看到1比其他数字多时,你也许猜测这个模型是在绿色状态,但是因为你不能看到被投骰子的颜色,所以你并不能确定。

隐马尔可夫模型提出了如下问题:

1. 给定一个输出序列,最有可能的状态过程是什么?
2. 给定一个输出序列,如何估计模型的转移和发布概率?
3. 如何求这个模型产生一个给定序列的先验概率?
4. 如何求这个模型产生一个给定序列的后验概率?


隐马尔可夫模型分析

统计工具箱包含5个与隐马尔可夫模型相关的函数:
hmmgenerate 从一个马尔可夫模型产生一个状态序列和输出序列;
hmmestimate 计算转移和输出的极大似然估计;
hmmtrain 从一个输出序列计算转移和输出概率的极大似然估计;
hmmviterbi 计算一个隐马尔可夫模型最可能的状态变化过程;
hmmdecode 计算一个给定输出序列的后验状态概率。

下面部分介绍如何使用这些函数来分析隐马尔可夫模型。

1. 产生一个测试序列

下面代码产生上面简介中模型的转移和输出矩阵:
TRANS = [.9 .1; .05 .95;];
EMIS = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6;...
7/12, 1/12, 1/12, 1/12, 1/12, 1/12];

要从模型产生一个随机的状态序列和输出序列,使用hmmgenerate:
[seq,states] = hmmgenerate(1000,TRANS,EMIS);

输出中,seq是输出序列,states是状态序列。hmmgenerate在第0步从状态1开始,在第一步转移到状态i1
,并返回i1作为状态的第一个入口。

2. 估计状态序列

给定了转移和输出矩阵TRANS和EMIS,函数hmmviterbi使用Viterbi算法计算模型给定输出序列seq最有可能
通过的状态序列:
likelystates = hmmviterbi(seq, TRANS, EMIS);

likelystates是和seq一样长的序列。计算hmmvertibi的精度如下:
sum(states == likelystates) / length(states)
ans =
    0.8680

3. 估计转移和输出矩阵
函数hmmestimate和hmmtrain用于估计给定输出序列seq的转移和输出矩阵TRANS和EMIS。

使用hmmestimate
[TRANS_EST, EMIS_EST] = hmmestimate(seq, states)
TRANS_EST =
    0.9065    0.0935
    0.0406    0.9594
EMIS_EST =
    0.1452    0.1516    0.1581    0.1968    0.1581    0.1903
    0.5841    0.0754    0.0986    0.0812    0.0841    0.0768
由上面使用方式可知,hmmestimate函数需要事先知道了得到输出序列seq,以及得到此结果的状态变化序
列。

使用hmmtrain
如果不知道状态序列,但是知道TRANS和EMIS的初始猜测,那就可以使用hmmtrain来估计TRANS和EMIS。

假设已知如下初始猜测:
TRANS_GUESS = [.85 .15; .1 .9];
EMIS_GUESS = [.17 .16 .17 .16 .17 .17;.6 .08 .08 .08 .08 08];

TRANS和EMIS的估计如下:
[TRANS_EST2, EMIS_EST2] = hmmtrain(seq, TRANS_GUESS, EMIS_GUESS)
TRANS_EST2 =
    0.9207    0.0793
    0.0370    0.9630
EMIS_EST2 =
    0.1792    0.1437    0.1436    0.1855    0.1509    0.1971
    0.5774    0.0775    0.1042    0.0840    0.0859    0.0710

hmmtrain使用迭代算法来不断修改TRANS_GUESS和EMIS_GUESS,使得每一步修改得到的矩阵都更加可能产生观测序列seq。当前后两个两次迭代矩阵的变化在一个小的容错范围内时,迭代停止。如果算法无法达到容错的范围,则迭代到达一定次数时就会停止,并返回一个警告提示。默认的最大迭代次数为100。

如果算法达不到目标误差范围,则可以通过增加迭代次数和/或加大容错误差值来使其获得较合适结果:
改变迭代次数maxiter:hmmtrain(seq,TRANS_GUESS,EMIS_GUESS,'maxiterations',maxiter)
改变容错误差tol:hmmtrain(seq, TRANS_GUESS, EMIS_GUESS, 'tolerance', tol)

影响hmmtrain输出的矩阵可靠性的两点因素:
(1)算法收敛于局部极值,这点可以使用不同的初始猜测矩阵来尝试解决;
(2)序列seq太短而无法很好的训练矩阵,可以尝试使用较长的序列。

4. 估计后验状态概率(不太理解)
一个输出序列seq的后验状态概率是在特定状态下的模型产生在seq中一个输出的条件概率。假定seq已经给出,你可以使用hmmdecode得到后验状态概率。

PSTATES = hmmdecode(seq,TRANS,EMIS)

输出为一个M * N的矩阵。M是状态的个数,L是seq的长度。PSTATES(i, j)是模型在状态i时,产生seq第j个输出的条件概率。

参考文献:
[1] Matlab R2007b帮助文档,http://www.aiseminar.cn/bbs,jink2005简译!
 
 
----------------------------------------------------------------------------------------------------------------
统计工具箱包含5个与隐马尔可夫模型相关的函数:
hmmgenerate 从一个马尔可夫模型产生一个状态序列和输出序列;
hmmestimate 计算转移和输出的极大似然估计;
hmmtrain 从一个输出序列计算转移和输出概率的极大似然估计;
hmmviterbi 计算一个隐马尔可夫模型最可能的状态变化过程;
hmmdecode 计算一个给定输出序列的后验状态概率。

下面部分介绍如何使用这些函数来分析隐马尔可夫模型。

1. 产生一个测试序列

下面代码产生上面简介中模型的转移和输出矩阵:
TRANS = [.9 .1; .05 .95;];
EMIS = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6;...
7/12, 1/12, 1/12, 1/12, 1/12, 1/12];

要从模型产生一个随机的状态序列和输出序列,使用hmmgenerate:
[seq,states] = hmmgenerate(1000,TRANS,EMIS);

输出中,seq是输出序列,states是状态序列。hmmgenerate在第0步从状态1开始,在第一步转移到状态i1
,并返回i1作为状态的第一个入口。

2. 估计状态序列

给定了转移和输出矩阵TRANS和EMIS,函数hmmviterbi使用Viterbi算法计算模型给定输出序列seq最有可能
通过的状态序列:
likelystates = hmmviterbi(seq, TRANS, EMIS);

likelystates是和seq一样长的序列。计算hmmvertibi的精度如下:
sum(states == likelystates) / length(states)
ans =
    0.8680

3. 估计转移和输出矩阵
函数hmmestimate和hmmtrain用于估计给定输出序列seq的转移和输出矩阵TRANS和EMIS。

使用hmmestimate
[TRANS_EST, EMIS_EST] = hmmestimate(seq, states)
TRANS_EST =
    0.9065    0.0935
    0.0406    0.9594
EMIS_EST =
    0.1452    0.1516    0.1581    0.1968    0.1581    0.1903
    0.5841    0.0754    0.0986    0.0812    0.0841    0.0768
由上面使用方式可知,hmmestimate函数需要事先知道了得到输出序列seq,以及得到此结果的状态变化序
列。

使用hmmtrain
如果不知道状态序列,但是知道TRANS和EMIS的初始猜测,那就可以使用hmmtrain来估计TRANS和EMIS。

假设已知如下初始猜测:
TRANS_GUESS = [.85 .15; .1 .9];
EMIS_GUESS = [.17 .16 .17 .16 .17 .17;.6 .08 .08 .08 .08 08];

TRANS和EMIS的估计如下:
[TRANS_EST2, EMIS_EST2] = hmmtrain(seq, TRANS_GUESS, EMIS_GUESS)
TRANS_EST2 =
    0.9207    0.0793
    0.0370    0.9630
EMIS_EST2 =
    0.1792    0.1437    0.1436    0.1855    0.1509    0.1971
    0.5774    0.0775    0.1042    0.0840    0.0859    0.0710

hmmtrain使用迭代算法来不断修改TRANS_GUESS和EMIS_GUESS,使得每一步修改得到的矩阵都更加可能产生观测序列seq。当前后两个两次迭代矩阵的变化在一个小的容错范围内时,迭代停止。如果算法无法达到容错的范围,则迭代到达一定次数时就会停止,并返回一个警告提示。默认的最大迭代次数为100。

如果算法达不到目标误差范围,则可以通过增加迭代次数和/或加大容错误差值来使其获得较合适结果:
改变迭代次数maxiter:hmmtrain(seq,TRANS_GUESS,EMIS_GUESS,'maxiterations',maxiter)
改变容错误差tol:hmmtrain(seq, TRANS_GUESS, EMIS_GUESS, 'tolerance', tol)

影响hmmtrain输出的矩阵可靠性的两点因素:
(1)算法收敛于局部极值,这点可以使用不同的初始猜测矩阵来尝试解决;
(2)序列seq太短而无法很好的训练矩阵,可以尝试使用较长的序列。

4. 估计后验状态概率(不太理解)
一个输出序列seq的后验状态概率是在特定状态下的模型产生在seq中一个输出的条件概率。假定seq已经给出,你可以使用hmmdecode得到后验状态概率。

PSTATES = hmmdecode(seq,TRANS,EMIS)

输出为一个M * N的矩阵。M是状态的个数,L是seq的长度。PSTATES(i, j)是模型在状态i时,产生seq第j个输出的条件概率。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM