@R语言下的HMM,从理论到实践解答你的困惑(经典讲解二)
接着写评估问题
解决方法详解
第一个问题的算法分析
蛮力算法
- 解决第一个问题,可以采用蛮力算法。即例举出所有可能的隐藏状态序列,然后计算在每个隐藏状态序列下产生可观察序列的概率值,然后对所有可能状态求和。
步骤如下:
- step1 计算可观察序列 x ⃗ \vec{x} x的长度 n n n(这一步很关键,没有这一步下文没办法展开说明)
- step2 找出所有长度为 n n n的隐藏变量序列 y ⃗ i , i = 0 , 1 , 2 , . . . , k − 1 {\vec{y}^i},i = 0,1,2,...,k-1 yi,i=0,1,2,...,k−1,注意这里每一个元素都是一个序列,这一点一定要头脑清楚,我这里为了和其他向量区别,把角标写到右上方。假设可能的状态序列总共有k种,其实可以根据组合数算出来k值,这里略去,留作课后习题。
大部分的博客写 step3 基本就开始出错了,有的角标写错,有的叙述出错,有的角标错位,这些地方往往是体现专业基本功的地方。这些地方写错,真真是耽误别人理解。但是往往这些地方大量出错,甚至一些教程都不能准确写出这些细节。
-
step3 对任意一个隐藏变量序列 y ⃗ i \vec{y}^i yi 求解出现 可观察序列 x ⃗ \vec{x} x 的概率 P ( x ⃗ ∣ y ⃗ i , λ ) P(\vec{x}|\vec{y}^i,\lambda) P(x∣yi,λ)
计算方法为:
按照时间顺序从第0个位置算起
P ( x ⃗ ∣ y ⃗ i , λ ) = π y 0 i ∗ b y 0 i x 0 ∗ a y 0 i y 1 i ∗ b y 1 i x 1 ∗ a y 1 i y 2 i ∗ b y 2 i x 2 ∗ . . . P(\vec{x}|\vec{y}^i,\lambda)=\pi_{y^i_0}*b_{y^i_0x_0}*a_{y^i_0y^i_1}*b_{y^i_1x_1}*a_{y^i_1y^i_2}*b_{y^i_2x_2}*... P(x∣yi,λ)=πy0i∗by0ix0∗ay0iy1i∗by1ix1∗ay1iy2i∗by2ix2∗...
简写为
P ( x ⃗ ∣ y ⃗ i , λ ) = π y 0 i ∗ b y 0 i x 0 ∗ ∑ j = 0 n − 2 a y i i y j + 1 i ∗ b y j + 1 i x j + 1 P(\vec{x}|\vec{y}^i,\lambda)=\pi_{y^i_0}*b_{y^i_0x_0}*\sum_{j=0}^{n-2}{a_{y^i_iy^i_{j+1}}*b_{y^i_{j+1}x_{j+1}}} P(x∣yi,λ)=πy0i∗by0ix0∗j=0∑n−2ayiiyj+1i∗byj+1ixj+1 -
step4 对所有可能状态序列 y ⃗ i \vec{y}^i yi求和
∑
i
=
0
k
−
1
P
(
x
⃗
∣
y
⃗
i
,
λ
)
\sum_{i=0}^{k-1}{P(\vec{x}|\vec{y}^i,\lambda)}
i=0∑k−1P(x∣yi,λ)
即得最终所求概率值
P
(
x
⃗
∣
λ
)
P(\vec{x}|\lambda)
P(x∣λ)
这种蛮力算法复杂度很高。
借助序列之间有公共部分这个规律简化蛮力算法
前向-后向算法使用动态规划思想来简化运算,减少重复运算。
前向算法
前向算法是从头到尾计算,逐步完成计算。
这样理解:
第 0 个位置得到
x
⃗
\vec{x}
x中
x
0
x_0
x0得概率是隐含状态取各种可能情况(也就是取遍状态值集合中得每一个值)得概率和
P
x
0
=
P
(
y
0
=
s
0
∣
x
0
,
λ
)
+
P
(
y
0
=
s
1
∣
x
0
,
λ
)
+
P
(
y
0
=
s
2
∣
x
0
,
λ
)
+
P
(
y
0
=
s
3
∣
x
0
,
λ
)
+
P
(
y
0
=
s
4
∣
x
0
,
λ
)
\textcolor{blue}{P_{x_0}=P(y_0=s_0|x_0,\lambda)+\\ P(y_0=s_1|x_0,\lambda)+\\ P(y_0=s_2|x_0,\lambda)+\\ P(y_0=s_3|x_0,\lambda)+\\ P(y_0=s_4|x_0,\lambda)}
Px0=P(y0=s0∣x0,λ)+P(y0=s1∣x0,λ)+P(y0=s2∣x0,λ)+P(y0=s3∣x0,λ)+P(y0=s4∣x0,λ)
简写为
P
x
0
=
∑
i
=
0
4
P
(
y
0
=
s
i
∣
x
0
,
λ
)
\textcolor{blue}{P_{x_0}=\sum_{i=0}^{4}{P(y_0=s_i|x_0,\lambda)}}
Px0=i=0∑4P(y0=si∣x0,λ)
这一步产生五种情况,这五种情况都会向下一步变化,每种变化都可以在产生一个路径(注意这里又用了另一个名词:路径)
P
(
y
0
=
s
0
∣
x
0
,
λ
)
,
P
(
y
0
=
s
1
∣
x
0
,
λ
)
,
P
(
y
0
=
s
2
∣
x
0
,
λ
)
,
P
(
y
0
=
s
3
∣
x
0
,
λ
)
,
P
(
y
0
=
s
4
∣
x
0
,
λ
)
\textcolor{orange}{P(y_0=s_0|x_0,\lambda),\\ P(y_0=s_1|x_0,\lambda),\\ P(y_0=s_2|x_0,\lambda),\\ P(y_0=s_3|x_0,\lambda),\\ P(y_0=s_4|x_0,\lambda)}
P(y0=s0∣x0,λ),P(y0=s1∣x0,λ),P(y0=s2∣x0,λ),P(y0=s3∣x0,λ),P(y0=s4∣x0,λ)
为了方便引用:
给这些式子写一个统一格式;
P
(
y
0
=
s
i
∣
x
0
,
λ
)
=
P
x
0
(
s
i
)
,
i
=
0
,
1
,
2
,
3
,
4
P(y_0=s_i|x_0,\lambda)=P_{x_0}(s_i),i=0,1,2,3,4
P(y0=si∣x0,λ)=Px0(si),i=0,1,2,3,4
计算第1个位置概率值时还需要考虑前一个位置的情况:
P
x
0
,
x
1
=
P
(
y
1
=
s
0
∣
y
0
=
s
0
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
1
∣
y
0
=
s
0
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
2
∣
y
0
=
s
0
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
3
∣
y
0
=
s
0
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
4
∣
y
0
=
s
0
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
0
∣
y
0
=
s
1
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
1
∣
y
0
=
s
1
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
2
∣
y
0
=
s
1
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
3
∣
y
0
=
s
1
,
x
0
,
x
1
,
λ
)
+
P
(
y
1
=
s
4
∣
y
0
=
s
1
,
x
0
,
x
1
,
λ
)
+
.
.
.
\textcolor{blue}{P_{x_0,x_1}=P(y_1=s_0|y_0=s_0,x_0,x_1,\lambda)+\\ P(y_1=s_1|y_0=s_0,x_0,x_1,\lambda)+\\ P(y_1=s_2|y_0=s_0,x_0,x_1,\lambda)+\\ P(y_1=s_3|y_0=s_0,x_0,x_1,\lambda)+\\ P(y_1=s_4|y_0=s_0,x_0,x_1,\lambda)+\\ P(y_1=s_0|y_0=s_1,x_0,x_1,\lambda)+\\ P(y_1=s_1|y_0=s_1,x_0,x_1,\lambda)+\\ P(y_1=s_2|y_0=s_1,x_0,x_1,\lambda)+\\ P(y_1=s_3|y_0=s_1,x_0,x_1,\lambda)+\\ P(y_1=s_4|y_0=s_1,x_0,x_1,\lambda)+...}
Px0,x1=P(y1=s0∣y0=s0,x0,x1,λ)+P(y1=s1∣y0=s0,x0,x1,λ)+P(y1=s2∣y0=s0,x0,x1,λ)+P(y1=s3∣y0=s0,x0,x1,λ)+P(y1=s4∣y0=s0,x0,x1,λ)+P(y1=s0∣y0=s1,x0,x1,λ)+P(y1=s1∣y0=s1,x0,x1,λ)+P(y1=s2∣y0=s1,x0,x1,λ)+P(y1=s3∣y0=s1,x0,x1,λ)+P(y1=s4∣y0=s1,x0,x1,λ)+...
公式太长了,基本成型,简写之后就好处理了。全网能如此详细写明白这个过程的博客应该不多吧。
P x 0 , x 1 = ∑ i = 0 4 ∑ j = 0 4 P ( y 1 = s i ∣ y 0 = s j , x 0 , x 1 , λ ) \textcolor{blue}{P_{x_0,x_1}=\sum_{i=0}^{4}\sum_{j=0}^{4}P(y_1=s_i|y_0=s_j,x_0,x_1,\lambda)} Px0,x1=i=0∑4j=0∑4P(y1=si∣y0=sj,x0,x1,λ)
这里注意双重求和。都是对状态值遍历后求和。
其中 P ( y 1 = s i ∣ y 0 = s j , x 0 , x 1 , λ ) = P ( y 0 = s j ∣ x 0 , λ ) ∗ a s j s i ∗ b s i x 1 P(y_1=s_i|y_0=s_j,x_0,x_1,\lambda)=P(y_0=s_j|x_0,\lambda)*a_{s_js_i}*b_{s_ix_1} P(y1=si∣y0=sj,x0,x1,λ)=P(y0=sj∣x0,λ)∗asjsi∗bsix1
因此
P
x
0
,
x
1
=
∑
i
=
0
4
∑
j
=
0
4
P
(
y
1
=
s
i
∣
y
0
=
s
j
,
x
0
,
x
1
,
λ
)
=
∑
i
=
0
4
∑
j
=
0
4
P
(
y
0
=
s
j
∣
x
0
,
λ
)
∗
a
s
j
s
i
∗
b
s
i
x
1
=
∑
i
=
0
4
∑
j
=
0
4
P
x
0
(
s
j
)
∗
a
s
j
s
i
∗
b
s
i
x
1
\textcolor{blue}{P_{x_0,x_1}=\sum_{i=0}^{4}\sum_{j=0}^{4}P(y_1=s_i|y_0=s_j,x_0,x_1,\lambda) \\=\sum_{i=0}^{4}\sum_{j=0}^{4}P(y_0=s_j|x_0,\lambda)*a_{s_js_i}*b_{s_ix_1} \\=\sum_{i=0}^{4}\sum_{j=0}^{4}P_{x_0}(s_j)*a_{s_js_i}*b_{s_ix_1} }
Px0,x1=i=0∑4j=0∑4P(y1=si∣y0=sj,x0,x1,λ)=i=0∑4j=0∑4P(y0=sj∣x0,λ)∗asjsi∗bsix1=i=0∑4j=0∑4Px0(sj)∗asjsi∗bsix1
以此类推
P
x
0
,
x
1
,
.
.
.
,
x
t
=
∑
i
=
0
4
∑
j
=
0
4
P
x
0
,
x
1
,
.
.
.
,
x
t
−
1
(
s
j
)
∗
a
s
j
s
i
∗
b
s
i
x
t
\textcolor{red}{P_{x_0,x_1,...,x_t}=\sum_{i=0}^{4}\sum_{j=0}^{4}P_{x_0,x_1,...,x_{t-1}}(s_j)*a_{s_js_i}*b_{s_ix_t} }
Px0,x1,...,xt=i=0∑4j=0∑4Px0,x1,...,xt−1(sj)∗asjsi∗bsixt
至此,我们的前向算法初步完成。
后向算法
后向算法可以按照类似的思路写出来,为了文章紧凑不重复,这里略去。作为课后思考题吧。