创建时间:2024-09-24
首发时间:2024-10-03
最后编辑时间:2024-10-03
作者:Geeker_LStar
你好呀~这里是 Geeker_LStar 的人工智能学习专栏,很高兴遇见你~
我是 Geeker_LStar,一名高一学生,热爱计算机和数学,我们一起加油~!
⭐(●’◡’●) ⭐
en…() 上一篇讲了聚类,然后我说这一篇要上强度()()
So!!! hidden Markov model 来喽()这玩意的确不太好搞()但是我会把它讲明白的!!
(烷氮,我感觉应该先讲 GMM 再讲 HMM,这样衔接会比较顺畅。。。
(好吧无所谓了,后面再写 GMM 也行,先启动吧!
(HMM 会分两篇写,这是第一篇~!
Let get start now!
HMM 简介
隐马尔可夫模型,hidden Markov model,简称 HMM 或者喝么么(什么鬼) 。
HMM 是概率图模型的一种(关于概率图模型我后面会开一篇讲),主要用于时序任务。 其实在 RNN 等深度学习方法出来以前,HMM 在 NLP 领域用的还是蛮多的,很多经典的任务比如命名实体识别之类的它都能做,而且效果也不错。
关键是,HMM 的数学推导非常 perfect,当中有不少 impressive 的算法!!!
话不多说我们开始好吧()
刚才说了,HMM 主要用于时间序列任务,不过这说的其实不完全。严谨地说,HMM 主要用于有隐藏状态的时间序列任务。并且,这个时间序列还需要满足马尔可夫性,即每个隐藏状态只和上一个时间步的隐藏状态有关,而和更早的隐藏状态无关。简言之,依赖链的长度为 1.
好吧,这么说太抽象了,so 举个例子:
现在你面前有两个盒子。盒子 A 装有 1 个红球 2 个白球,盒子 B 装有 1 个白球 2 个红球,每次摸完球都会放回去。
结合以上条件,考虑以下三个问题:
1)已知在第一次摸球的时候,从盒子 A 摸球的概率是 0.4,从盒子 B 摸球的概率是 0.6;在盒子 A 摸完球后跳到盒子 B 摸球的概率是 0.3,在盒子 B 摸完球后跳到盒子 A 摸球的概率是 0.8。现在已知五次摸球的结果是:红、白、红、白、白。求在上述条件下,这个序列出现的概率。
2)现在已知一些摸球的数据,求使得这些数据出现概率最大的以下参数——第一次摸球的时候从盒子 A 摸和从盒子 B 摸的概率、从盒子 A 跳到盒子 B 摸球的概率 / 从盒子 B 跳到盒子 A 摸的概率、在盒子 A / B 中摸出红球 / 白球的概率(注意最后这个包含了四个条件)。
3)已知在第一次摸球的时候,从盒子 A 摸球的概率是 0.4,从盒子 B 摸球的概率是 0.6;在盒子 A 摸完球后跳到盒子 B 摸球的概率是 0.3,在盒子 B 摸完球后跳到盒子 A 摸球的概率是 0.8。现在已知五次摸球的结果是:红、白、红、白、白。求在上述条件下,这五次分别都是在哪个盒子中摸的球?(给出概率最大的序列)(这个和第一个题的题干是完全一样的,只是问题换了一下)
噢好的,我们注意到,在三个问题中,“下一次在哪个盒子里摸球” 仅仅取决于 “这一次在哪个盒子里摸球”,而和 “上一次 / 上上次在哪个盒子里摸球” 完全无关。这种当前状态只依赖于前一个时间步状态的性质就被称为马尔可夫性。同时,在这个例子中,从哪个盒子中摸球是不可观测的,但是它影响摸球结果,这就是 HMM 中的隐藏状态——不可被观测,但是会影响可观测的结果。
呃好的,emm 希望这个例子没有起到反面作用(就是让你更懵了),我个人感觉这里说的还算清楚,如果感觉有点绕可以多看几遍,或者三个问题分开看。
提炼一下:
概念 | 定义 | 示例 |
---|---|---|
隐藏状态 (State) | 不可观测的状态,影响观测结果 | 盒子 A 或盒子 B |
可观测结果 (Observation) | 可以直接观测的结果 | 摸到的红球或白球 |
初始概率 (Initial Probability) | 状态序列开始时每个状态的概率 | 从盒子 A 摸球的概率是 0.4,从盒子 B 摸球的概率是 0.6 |
状态转移概率 (Transition Probability) | 从一个状态转移到另一个状态的概率 | 从盒子 A 跳到盒子 B 的概率是 0.3 |
观测概率 (Observation Probability) | 在某一状态下观测到特定结果的概率 | 在盒子 A 中摸出红球的概率是 1/3 |
❗以上这五个就是 HMM 最重要的五个概念!! 记住它们!!
那么,提炼出这五个概念,上面的三个问题就可以重写了,重写后的问题将会非常简单。
为了方便,我们把初始概率、状态转移概率和观测概率这三个概率统称为参数。
1)已知参数和观测序列,求该参数下该观测序列出现的概率。
2)已知多个观测序列,求使得这些观测序列出现概率最大的参数。
3)已知参数和观测序列,求在该参数和观测序列,最有可能的状态序列。
嗯,这里放一张图,图中的状态是天气,观测是心情;指向太阳和云的箭头代表状态转移概率,指向心情符号的箭头代表观测概率(注意这个图里省略了初始概率)。这也是一个 HMM 的例子,或许图会更直观。
豪德!我相信现在你已经对 HMM 有了一个初步的认知了!因为总是用文字其实也不太有助于理解,so 我们还是来写数学符号吧!
为了防止我写到后面开始放飞自我乱用符号,首先我们来规定一些 notation。
我们假定,在后续的所有例子中,一共有 N N N 种状态, M M M 种观测,时间步为 T T T.
我们把这
T
T
T 个时间步的状态构成的序列称为状态序列,记作
I
=
(
i
1
,
i
2
,
.
.
.
,
i
T
)
I=(i_1, i_2, ... , i_T)
I=(i1,i2,...,iT),其中
i
k
i_k
ik 为第
k
k
k 个时间步下的状态;把这
T
T
T 个时间步的观测构成的序列称为观测序列,记作
O
=
(
o
1
,
o
2
,
.
.
.
,
o
T
)
O=(o_1, o_2, ..., o_T)
O=(o1,o2,...,oT),其中
o
k
o_k
ok 为第
k
k
k 个时间步下的观测。
注意,
I
I
I 是无法被观测的,但
I
I
I 会对
O
O
O 造成影响。所以,HMM 是一个含有隐变量的模型,remember this。
我们把初始参数记作
λ
\lambda
λ,它代表了各个状态成为初始状态的概率;
状态转移概率记作
A
A
A,
A
A
A 是一个
N
∗
N
N*N
N∗N 的矩阵,它记录了从一个状态转换到另一个状态的概率;
观测概率记作
B
B
B,
B
B
B 是一个
N
∗
M
N*M
N∗M 的矩阵,它记录了在特定状态下出现特定观测的概率。
还是用摸球的例子,在这个例子中,具体的参数如下:
第一,初始概率
λ
\lambda
λ:
λ
=
[
0.4
,
0.6
]
\lambda = [0.4, 0.6]
λ=[0.4,0.6]
λ
\lambda
λ 向量的第
i
i
i 个分量表示初始时从第
i
i
i 个状态开始的概率。
其中,0.4 代表在第一次摸球的时候,有 40% 的概率从盒子 A 中摸;0.6 代表在第一次摸球时,有 60% 的概率从盒子 B 中摸。
第二,状态转移概率
A
A
A:
A
=
[
0.7
0.3
0.2
0.8
]
A =\begin{bmatrix} 0.7 & 0.3 \\ 0.2 & 0.8 \end{bmatrix}
A=[0.70.20.30.8]
A
A
A 是一个
N
∗
N
N*N
N∗N 的矩阵,矩阵的第
i
i
i 行第
j
j
j 列代表了从状态
i
i
i 转移到状态
j
j
j 的概率,记作
α
i
j
\alpha_{ij}
αij.
对应到例子,第一行第一列代表了在盒子 A 摸球后,下次继续在盒子 A 摸球的概率;而第一行第二列代表了从盒子 A 摸球后转移到盒子 B 摸球的概率。第二行也是同理。
第三,观测概率
B
B
B:
A
=
[
1
/
3
2
/
3
2
/
3
1
/
3
]
A =\begin{bmatrix} 1/3 & 2/3 \\ 2/3 & 1/3 \end{bmatrix}
A=[1/32/32/31/3]
B
B
B 是一个
N
∗
M
N*M
N∗M 的矩阵(在这里
N
=
M
N=M
N=M),矩阵的第
i
i
i 行第
j
j
j 列代表了在状态
i
i
i 下观测到观测
j
j
j 的概率,记作
b
i
(
j
)
b_i(j)
bi(j).
对应到例子,第二行第一列代表了在状态 “盒子 B” 下出现观测 “红球” 的概率是 2/3。
okaya!! 现在我们已经规定好了符号,我们可以返回去看看那三个问题了。这次用数学语言写。
-
第一个问题,又叫评估问题,是指在已知参数 λ \lambda λ 和观测序列 O O O 的情况下,求该观测序列在该参数下出现的概率,即 P ( O ∣ λ ) P(O|\lambda) P(O∣λ)。
-
第二个问题,又叫学习问题,是指在已知多个观测序列 O 1 , O 2 , . . . , O n O_1, O_2, ..., O_n O1,O2,...,On 的情况下,求使得这些观测序列出现概率最大的参数 λ \lambda λ,即最大化 P ( O ∣ λ ) P(O|\lambda) P(O∣λ)。注意这是一个含有隐变量(状态序列 I 1 , I 2 , . . . , I n I_1, I_2, ..., I_n I1,I2,...,In)的参数估计问题,可以采用 EM 算法解决。
-
第三个问题,又叫解码问题,是指在已知参数 λ \lambda λ 和观测序列 O O O 的情况下,求在该参数下,该观测序列最有可能对应的状态序列,即求使得 P ( I ∣ O ) P(I|O) P(I∣O) 最大的 I I I。
豪德!!那么现在,你已经对 HMM 的任务流程和三个主要问题了解了,我们接下来就来分别看看这三个问题吧!!
这一篇会讲第一个也就是评估问题,学习问题和解码问题会放到下一篇~!
评估问题
豪嘟,我们先从评估问题说起。
HMM 的评估问题,即给定模型参数 λ = ( A , B , π ) \lambda = (A, B, \pi) λ=(A,B,π) 和观测序列 O = ( o 1 , o 2 , . . . , o T ) O = (o_1, o_2, ..., o_T) O=(o1,o2,...,oT),计算在参数 λ \lambda λ 下观测序列 O O O 出现的概率 P ( O ∣ λ P(O|\lambda P(O∣λ)。
errrr 这怎么算()
啊我猜有一个 straight forward 的方法是很容易想到的——观测序列的长度不是
T
T
T 嘛,那对应的状态序列的长度也就是
T
T
T,那我们只要枚举出所有长度为
T
T
T 的状态序列(因为它们是不可观测的,所以只能枚举),然后挨个计算每个状态序列下观测序列出现的可能性,然后再把所有的状态序列下观测序列出现的可能性加起来就可以了()
呃,好的,对于一个深受剥(暴)蒜(算)之苦的人来说()这个方法是一种思路,,,但是 emmm 总之最好不要用()
为什么呢?只需计算一下这种方法的时间复杂度,然后就什么都明白了。
我们一共有
T
T
T 个时间步(长度),每个时间步有
N
N
N 种可能的状态,那么我们一共要计算
N
T
N^T
NT 种状态,然后对于每一种状态,还要计算在这种状态下产生对应观测的概率。
嗯,,,那么时间复杂度就是
O
(
N
T
)
O(N^T)
O(NT)。
布什戈门,又是指数级别的时间复杂度,这要干嘛啊()
嗯,可以非常明确的看到,这么做是万万不能的()
所以,除了这种做法,有没有什么更好的做法,既可以在给定参数的情况下计算观测序列出现的概率,又可以避免如此高的时间复杂度?
那显然是有的。
我们来分析一下,现在的问题出在哪里。
假设我们现在有 4 个时间步,每个时间步可能的状态有三个(A/B/C)。按照上面的计算方法,我们需要分析 3^4 种可能的状态序列。这里我随便放三个:
1)ABCA
2)ABCB
3)ABBA
嗯,按照上面的方法,在计算的时候,我们分别计算这三种状态序列的情况下,观测序列出现的情况。
但是,你可能会想,eemm,在计算状态序列(1)的时候,我们不是已经计算出了当第一个时间步的状态为 A,第二个时间步的状态为 B 的时候,前两个观测 o 1 , o 2 o_1, o_2 o1,o2 出现的概率了嘛,但是在计算状态序列(2)的时候,明明(2)的前两个状态和(1)都是一样的,换句话说,在状态序列为(2)的情况下,明明 o 1 , o 2 o_1, o_2 o1,o2 出现的概率和在(1)的情况下都是一样的,然鹅我们还要再算一遍,这不纯浪费计算资源嘛()
是的,这正是这个算法的缺陷所在——它包含大量的重复计算,哪怕两个状态序列只有最后一位不同,我们也得把它俩分别从头计算。这导致了很高的时间复杂度。
soooo…既然我们知道了问题在哪,那不就有解决问题的方向了嘛!想办法去掉这些重复计算就好了呀!
豪德,本着这样的思想,我们接下来介绍两个算法——前向算法和后向算法。
前向算法和后向算法的核心思想差不多,这里先用前向算法的例子,因为正着推的过程更好理解。
前向算法的核心是,让第
k
k
k 时间步的概率的计算包含前
k
−
1
k-1
k−1 步的所有概率的结果,如此递推,直到最后一个时间步
T
T
T。
简言之,前 k − 1 k-1 k−1 步计算出来的结果直接给到第 k k k 步的所有可能状态,也就是说,无论第 k k k 步的状态是 α 1 \alpha_1 α1 还是 α 2 \alpha_2 α2 还是什么(对应不同的状态序列),都会使用前 k − 1 k-1 k−1 步的结果进行后续计算。这样,在面对重复序列的时候,重复的部分我们就只需要计算一次了(计算出来直接给到后面,进行递推计算),这将大大降低时间复杂度,具体的复杂度会在后面计算。
well 这么说着可能比较不好理解,我们还是直接来看例子 & 式子吧,可能讲完公式你就 get 了()。
噢等等,刚才一直在说前向算法,后向算法也是一个道理,只不过是从后往前递推,讲完前向,后向就好理解了。
前向算法
豪德,还是先贴一遍会用到的数学表示 & 问题。
参数
λ
=
(
A
,
B
,
π
)
\lambda=(A,B,\pi)
λ=(A,B,π),共有
T
T
T 个时间步;
长度为
T
T
T 的不可见的状态序列
I
=
(
i
1
,
i
2
,
.
.
.
,
i
T
)
I=(i_1, i_2, ..., i_T)
I=(i1,i2,...,iT);
长度为
T
T
T 的可见的观测序列
O
O
O =
(
o
1
,
o
2
,
.
.
.
,
o
T
)
(o_1, o_2, ...,o_T)
(o1,o2,...,oT).
前提:每个时间步对应的观测由该时间步的状态决定,每个时间步的状态只由上一个时间步的状态决定。
求:在时间步 t t t 时,满足观测序列 ( o 1 , o 2 , . . . , o t ) (o_1, o_2, ..., o_t) (o1,o2,...,ot) 且在时间步 t t t 处于状态 i i i 的概率?
yes,上面这个问题求得就是在时间步 t t t 时,状态 i i i 的前向概率。注意状态是不可见的,所以我们通过递推的方式来计算。
先把公式放在这,后面解释。
α
t
(
i
)
=
[
∑
j
=
1
N
α
t
−
1
(
j
)
α
j
i
]
b
i
(
o
t
)
,
i
=
1
,
2
,
.
.
.
,
N
\alpha_{t}(i)=\bigg[\sum_{j=1}^{N}\alpha_{t-1}(j)\alpha_{ji}\bigg]b_i(o_{t}), \ \ i=1,2,...,N
αt(i)=[j=1∑Nαt−1(j)αji]bi(ot), i=1,2,...,N
解释一下参数。
α
t
(
i
)
\alpha_t(i)
αt(i) 是在
t
t
t 时间步时状态为
i
i
i 的概率,它是通过右边的式子计算出来的。
接下来来看一下右边的式子,先看中括号里面的,求和符号后面。
α
t
−
1
(
j
)
\alpha_{t-1}(j)
αt−1(j) 和 等号左边的
α
t
(
i
)
\alpha_t(i)
αt(i) 是完全一样的格式,它的意思是在
t
−
1
t-1
t−1 时间步时状态为
j
j
j 的概率;然后是
α
j
i
\alpha_{ji}
αji,这个前面说过,是从状态
i
i
i 转移到状态
j
j
j 的转移概率。
豪德,那么, α t − 1 ( j ) α j i \alpha_{t-1}(j)\alpha_{ji} αt−1(j)αji 表示的就是,在 t − 1 t-1 t−1 时刻处在 j j j 状态,且在 t t t 时刻由 j j j 状态转换到 i i i 状态的概率。
嗯,然后,前面还有个求和符号,这又是什么意思呢?
你看嗷,求和符号是从
j
=
1
j=1
j=1 开始遍历的,一直遍历到
N
N
N,然后对于每一个
j
j
j,都会做相同的运算。也就是说,这个求和负责把从【上一个时间步的第 1 个到第
N
N
N 个状态】转移到【当前时间步的状态
i
i
i】的概率加起来了。
嗯,上图,看图就很明白了!!
这个图是用时间步 t t t 和 t + 1 t+1 t+1 为例的,我们用 t − 1 t-1 t−1 和 t t t 为例也是一样的。因为前一个时间步和当前时间步的递推关系是一样的。
(哦,这个图的
i
,
j
i,j
i,j 和我公式里用的是反着的,不过 no matter.
式子中的
α
t
−
1
(
j
)
\alpha_{t-1}(j)
αt−1(j) 代表的就是图上的
a
t
(
j
)
a_t(j)
at(j),即在前一个时间步时处于状态
j
j
j 的概率。而图上的
α
j
i
\alpha_{ji}
αji 和公式里也是一样的,代表从状态
i
i
i 转移到状态
j
j
j 的概率。至于那个求和,就是把图上所有的箭头的概率(
α
t
−
1
(
j
)
α
j
i
\alpha_{t-1}(j)\alpha_{ji}
αt−1(j)αji)加起来,也就是在当前时间步
t
t
t 处于状态
i
i
i 的概率。
好的,关于这个公式,最核心的你已经理解了,不过我们不要忘了后面还有一部分。
再贴一遍式子:
α
t
(
i
)
=
[
∑
j
=
1
N
α
t
−
1
(
j
)
α
j
i
]
b
i
(
o
t
)
,
i
=
1
,
2
,
.
.
.
,
N
\alpha_{t}(i)=\bigg[\sum_{j=1}^{N}\alpha_{t-1}(j)\alpha_{ji}\bigg]b_i(o_{t}), \ \ i=1,2,...,N
αt(i)=[j=1∑Nαt−1(j)αji]bi(ot), i=1,2,...,N
嗯,在计算完在当前时间步
t
t
t 处于状态
i
i
i 的概率,也就是中括号里面那一坨之后,后面还有一个部分,
b
i
(
o
t
)
b_i(o_{t})
bi(ot)。
notation 那部分说过,这个表示在状态
i
i
i 下,出现时间步
t
t
t 的观测
o
t
o_t
ot 的概率。
啊现在整个式子应该不难理解了吧,我们计算出了在时间步 t t t 时候处于状态 i i i 的概率,然后又乘了一个在状态 i i i 下出现时间步 t t t 的观测 o t o_t ot 的概率,那不就等于我们算出了,在满足直到时间步 t t t 的所有观测序列 o 1 , o 2 , . . . , o t o_1, o_2, ..., o_t o1,o2,...,ot 的情况下,在时间步 t t t 处于状态 i i i 的概率!!!
也就是说,我们推出来前向概率啦!
嗯,你可能会问,诶中括号里面那坨怎么就算出在时间步 t t t 的时候处于状态 i i i 的概率了?或者说,这个能理解,但是 α t − 1 ( j ) \alpha_{t-1}(j) αt−1(j) 是怎么冒出来的?
这就又要说到马尔可夫性和递推这两件事情了。
马尔可夫性,即时间步
t
t
t 的状态只依赖于时间步
t
−
1
t-1
t−1 的状态,
别忘了,我们是递推呀,换言之,时间步 t − 1 t-1 t−1 时候每个状态的前向概率 α t − 1 ( j ) \alpha_{t-1}(j) αt−1(j) 也是用的和计算时间步 t t t 时刻某个状态 i i i 的前向概率一样的算法。
well,我不如直接把递推公式贴在这里,我估计这样你绝对就懂了()
从第一个时间步开始吧。在第一个时间步处于状态
i
i
i 且观测为
o
1
o_1
o1 的概率为:
α
1
(
i
)
=
π
(
i
)
b
i
(
o
1
)
\alpha_{1}(i)=\pi(i)b_i(o_1)
α1(i)=π(i)bi(o1)
好的,我们利用这个结果接着计算第二个时间步。
对于第二个时间步处于状态
i
i
i 且符合观测序列
o
1
,
o
2
o_1, o_2
o1,o2 的前向概率,还是用这个递推公式进行计算。
可以看到,在第二个时间步的前向概率计算中,我们已经用上了第一个时间步的计算结果
α
1
(
j
)
\alpha_1(j)
α1(j)。
α
2
(
i
)
=
[
∑
j
=
1
N
α
1
(
j
)
α
j
i
]
b
i
(
o
2
)
,
i
=
1
,
2
,
.
.
.
,
N
\alpha_{2}(i)=\bigg[\sum_{j=1}^{N}\alpha_1(j)\alpha_{ji}\bigg]b_i(o_{2}), \ \ i=1,2,...,N
α2(i)=[j=1∑Nα1(j)αji]bi(o2), i=1,2,...,N
嗯,然后就这么递推下去,当然时间步特定状态的前向概率总是依赖于上一时间步的所有前向概率;同时,当前时间步的所有前向概率都会影响下一时间步特定状态的前向概率。
公式:
α
t
−
1
(
i
)
=
[
∑
j
=
1
N
α
t
−
2
(
j
)
α
j
i
]
b
i
(
o
t
−
1
)
,
i
=
1
,
2
,
.
.
.
,
N
\alpha_{t-1}(i)=\bigg[\sum_{j=1}^{N}\alpha_{t-2}(j)\alpha_{ji}\bigg]b_i(o_{t-1}), \ \ i=1,2,...,N
αt−1(i)=[j=1∑Nαt−2(j)αji]bi(ot−1), i=1,2,...,N
α t ( i ) = [ ∑ j = 1 N α t − 1 ( j ) α j i ] b i ( o t ) , i = 1 , 2 , . . . , N \alpha_{t}(i)=\bigg[\sum_{j=1}^{N}\alpha_{t-1}(j)\alpha_{ji}\bigg]b_i(o_{t}), \ \ i=1,2,...,N αt(i)=[j=1∑Nαt−1(j)αji]bi(ot), i=1,2,...,N
嗯,然后再放个图,没有什么特殊原因,只是因为我觉得它长得比较好看():
en,可以忽略图上的文字,只看那些线,我觉得现在你已经非常理解前向算法的递推是怎么回事了,同时,你应该也明白为什么这种计算方法可以大大节省时间开销了。
我们后面会计算这种算法的时间复杂度,不过现在,趁着刚好理解这个递推,我们来继续看看后向算法吧!!
((vocal 说实话我感觉这块的东西有点那种只可意会不可言传的感觉()(或者说我语文水平太烂了
后向算法
其实后向算法和前向算法的本质完全一样,只不过前向算法是从前往后推(或者说,想一想那幅图,箭头是从前一个时间步指向后一个时间步的),而后向算法是从后往前推,反映到图上就是箭头是从后一个时间步指向前一个时间步的。
okay,还是先放公式。
β t ( i ) = ∑ j = 1 N α i j b j ( o t + 1 ) β t + 1 ( j ) , i = 1 , 2 , . . . , N \beta_{t}(i) = \sum_{j=1}^N\alpha_{ij}b_j(o_{t+1})\beta_{t+1}(j), \ \ i=1,2,...,N βt(i)=j=1∑Nαijbj(ot+1)βt+1(j), i=1,2,...,N
一样的,先讲参数。
等号左边,
β
t
(
i
)
\beta_{t}(i)
βt(i),代表在时间步
t
t
t 时处于状态
i
i
i 的后向概率。说的更细一点,代表在时间步
t
t
t 处于状态
i
i
i 且从时间步
t
+
1
t+1
t+1 到
T
T
T 的观测序列为
(
o
t
+
1
,
o
t
+
2
,
.
.
.
,
o
T
)
(o_{t+1}, o_{t+2}, ..., o_T)
(ot+1,ot+2,...,oT) 的概率。
yes 没错,可以把后向概率和前向概率看成两个互补的东西,它们唯一的交集都是要求在时间步 t t t 的时候处于状态 i i i。前向概率考虑从第一个时间步到第 t t t 个时间步的观测概率,后向概率考虑从第 t + 1 t+1 t+1 个时间步到第 T T T 个时间步的观测概率。
后面我们会看到,这样的计算方法会带来极大的好处。
aeerr 我们继续来看参数,这次看等号右边。
β
t
+
1
(
j
)
\beta_{t+1}(j)
βt+1(j) 就不用说了,和等号左边一样,只是代表后一个时间步的后向概率,用于递推,递推逻辑和前向算法一样。
呃怎么感觉其实参数和前向算法里的几乎一样,,啊好吧它们的逻辑都一样那参数肯定也很相似。。
不过还是说一下吧, a i j a_{ij} aij 代表从时间步 t t t 的状态 i i i 转换到时间步 t + 1 t+1 t+1 的状态 j j j 的概率, b j ( o t + 1 ) b_j(o_{t+1}) bj(ot+1) 代表在状态 j j j 下,出现时间步 t + 1 t+1 t+1 的观测 o t + 1 o_{t+1} ot+1 的概率。
我觉得有了前向算法的铺垫,后向算法的公式也就很好理解了。
然后放图,《看图说话》(不是) 。
其实我个人感觉这个图有点小瑕疵——它的箭头应该对着第 t t t 个时间步的小圈圈,而不是第 t + 1 t+1 t+1 个时间步的小圈圈。这样可以更好地表达出 “从最后一个时间步向第一个时间步递推” 的感觉(啊当然这只是我个人的看法)。
你发现了吗,从图的结构来看,如果说前向算法是汇集上一个时间步的所有状态的概率,那么后向算法就是汇集下一个时间步的所有状态的概率。它也是概率复用的、递推的。
嗯,不过我们还是好好把递推写一遍吧,这次从最后一个时间步出发,往前汇聚。
对于最后一个时间步,因为后面不再有时间步了,所以最后一个时间步的后向概率为 1:
β
T
(
i
)
=
1
\beta_{T}(i) = 1
βT(i)=1
然后,我们往前推一个,第
T
−
1
T-1
T−1 个时间步。
第
T
−
1
T-1
T−1 个时间步的后向概率等于在第
T
−
1
T-1
T−1 个时间步处于状态
i
i
i 且在第
T
−
1
,
T
T-1, T
T−1,T 个时间步的观测为
(
o
T
−
1
,
o
T
)
(o_{T-1}, o_T)
(oT−1,oT) 的概率:
β
T
−
1
(
i
)
=
∑
j
=
1
N
α
i
j
b
j
(
o
t
+
1
)
∗
1
,
i
=
1
,
2
,
.
.
.
,
N
\beta_{T-1}(i) = \sum_{j=1}^N\alpha_{ij}b_j(o_{t+1})*1, \ \ i=1,2,...,N
βT−1(i)=j=1∑Nαijbj(ot+1)∗1, i=1,2,...,N
最后那个 1 就是第 T T T 个时间步的后向概率。
然后,继续往前推:
β
t
(
i
)
=
∑
j
=
1
N
α
i
j
b
j
(
o
t
+
1
)
β
t
+
1
(
j
)
,
i
=
1
,
2
,
.
.
.
,
N
\beta_{t}(i) = \sum_{j=1}^N\alpha_{ij}b_j(o_{t+1})\beta_{t+1}(j), \ \ i=1,2,...,N
βt(i)=j=1∑Nαijbj(ot+1)βt+1(j), i=1,2,...,N
β t − 1 ( i ) = ∑ j = 1 N α i j b j ( o t ) β t ( j ) , i = 1 , 2 , . . . , N \beta_{t-1}(i) = \sum_{j=1}^N\alpha_{ij}b_j(o_{t})\beta_{t}(j), \ \ i=1,2,...,N βt−1(i)=j=1∑Nαijbj(ot)βt(j), i=1,2,...,N
嗯!还是那种一层一层往前递推的感觉!!
嘿嘿嘿现在有没有感觉明白了很多!!!
联合算法
嗯,前面已经讲完了前向算法和后向算法,也计算出了在某个时间步的时候出现某个观测的前向概率和后向概率。但是我们先停一下——我们为什么要算这个来着???
哦,好像是因为,我们想算在给定参数的情况下某个特定序列的出现概率,但是直接计算又太耗时间,对吧。所以我们采用前向算法和后向算法实现 “概率复用”(豪德,概率复用这个词是我发明的,学 Vue 组件复用学的),即直接把前面计算出来的概率分别给到后面的每一个可能状态,避免了每次都重复计算。
嗯。,,,那么现在,我们已经得到了【在某个时间步时,某个状态出现的前向概率和后向概率】,我们怎么计算整个序列可能出现的概率??
well,首先,我们之前已经讲过了,前向算法和后向算法是互补的,一个计算 t t t 时间步为特定状态时, t t t 时间步及以前时间步的观测序列出现的概率;一个计算 t t t 时间步为特定状态时, t + 1 t+1 t+1 及以后时间步的观测序列出现的概率。
那么,一个非常符合 intuition 的做法是,把前向概率和后向概率相乘,看看会得到什么。即:
α t ( i ) β t ( i ) \alpha_t(i)\beta_t(i) αt(i)βt(i)
展开,得到:
[ ∑ j = 1 N α t − 1 ( j ) α j i ] b i ( o t ) ∗ ∑ j = 1 N α i j b j ( o t + 1 ) β t + 1 ( j ) , i = 1 , 2 , . . . , N \bigg[\sum_{j=1}^{N}\alpha_{t-1}(j)\alpha_{ji}\bigg]b_i(o_{t})*\sum_{j=1}^N\alpha_{ij}b_j(o_{t+1})\beta_{t+1}(j), \ \ i=1,2,...,N [j=1∑Nαt−1(j)αji]bi(ot)∗j=1∑Nαijbj(ot+1)βt+1(j), i=1,2,...,N
啊中间那个 * 没有什么特殊含义,就是正常的乘号,只是为了把前半部分前向概率和后半部分后向概率分隔开 (但是又不想打大括号) 。
呃,好的,我想这个公式一定不讨人喜欢()so 我们还是放个图吧。
或者说,我们采用自然语言描述 (NL 描述啊不是) 也可以。
前向概率,计算的是参数为
λ
\lambda
λ 时,观测序列
O
O
O 中前
t
t
t 个时间步的观测出现的概率;限制条件是时间步
t
t
t 的状态为
i
i
i.
后向概率,计算的是参数为
λ
\lambda
λ 时,观测序列
O
O
O 的第
t
+
1
t+1
t+1 个时间步到最后一个时间步的观测出现的概率;限制条件是时间步
t
t
t 的状态为
i
i
i.
那把它们相乘,我们得到什么?
obviously,我们得到了,在参数
λ
\lambda
λ 下且第
t
t
t 个时间步的状态为
i
i
i 的时候,观测序列
O
O
O 出现的概率!(噢,这里再提一下,所有这些都是建立在马尔可夫性的基础上的,没有这个大前提就什么也没有。
用数学公式表示就是:
P ( o 1 , o 2 , . . . , o t ∣ i t = i , λ ) ∗ P ( o t + 1 , o t + 2 , . . . , o T ∣ ) = P ( O ∣ i t = i , λ ) P(o_1, o_2, ..., o_t|i_t=i, \lambda)*P(o_{t+1}, o_{t+2}, ..., o_T|)=P(O|i_t=i, \lambda) P(o1,o2,...,ot∣it=i,λ)∗P(ot+1,ot+2,...,oT∣)=P(O∣it=i,λ)
make sense.
嗯!!这是一个令人激动的结论!
那么,既然我们可以通过 α t ( i ) β t ( i ) \alpha_t(i)\beta_t(i) αt(i)βt(i) 计算出来在参数 λ \lambda λ 下,观测序列 O O O 出现且在时间步 t t t 的状态为 i i i 概率(什么绕口令((),那么我们只要遍历所有的状态(所有可能的 i i i),然后把对应状态下的 α t ( i ) β t ( i ) \alpha_t(i)\beta_t(i) αt(i)βt(i) 的结果加起来,就可以得到整个序列出现的概率了!!
好的,非常完美,我们得到了:
P
(
O
∣
λ
)
=
∑
i
=
1
N
α
t
(
i
)
β
t
(
i
)
P(O|\lambda)=\sum_{i=1}^{N}\alpha_t(i)\beta_t(i)
P(O∣λ)=i=1∑Nαt(i)βt(i)
yeeees! 我们通过这种更巧的方法算出了整个序列出现的概率!
当然,如果我们想展开其中一项,也是可以的(至于为什么要展开,后面很快就会说)。
我们把从
t
t
t 到
t
+
1
t+1
t+1 那一项展开,式子变成:
P
(
O
∣
λ
)
=
∑
i
=
1
N
α
t
(
i
)
α
i
j
b
j
(
o
t
+
1
)
β
t
+
1
(
j
)
P(O|\lambda)=\sum_{i=1}^{N}\alpha_t(i)\alpha_{ij}b_j(o_{t+1})\beta_{t+1}(j)
P(O∣λ)=i=1∑Nαt(i)αijbj(ot+1)βt+1(j)
对应下面这个图:
嗯,其实如果我们想的话,可以把整个式子都展开,不过通常不会遇到。
好嘞,现在来填坑,之前说要算时间复杂度来着。
前向算法和后向算法是对称的,所以它们时间复杂度的计算方式也一样,在这里以前向算法为例。
在前向算法中,对于每一个时间步,我们有 N N N 个状态;而对于每个状态,我们要计算它前一个时间步的 N N N 个状态,即 ∑ j = 1 N α t − 1 ( j ) α j i \sum_{j=1}^{N}\alpha_{t-1}(j)\alpha_{ji} ∑j=1Nαt−1(j)αji。也就是说,在每一个时间步,我们需要做 N 2 N^2 N2 次计算。(就跟套两层循环一样,对于一个状态,要计算 N N N 次,而我们在每个时间步有 N N N 个状态,所以需要 N ∗ N N*N N∗N 次。
同时,我们一共有 T T T 个时间步,so 我们还需要在 N 2 N^2 N2 的基础上再乘个 T T T.
综上,前向算法的时间复杂度为 O ( N 2 T ) O(N^2T) O(N2T),后向算法也是。
嗯!我们可以看出,前后向算法的时间复杂度是平方级的,比传统剥蒜法的指数级好了很多!
okay!不知道你是不是也觉得这两个算法蛮不错的捏~?
豪德!那这篇就先讲这一个问题吧!前向和后向这两个算法都是比较精妙的,下一篇我们还会遇到两个精妙的算法~!
哦对啦,下一篇讲的两个问题之一的【学习问题】的解决思路其实就是 EM 算法,不妨先去看看这篇:
【初中生讲机器学习】15. EM 算法一万字详解!一起来学!
okay! 那这篇就到这里啦!我们下篇再见!!keep follow!
哇!现在是 2024.10.12,下篇来啦!:
【高中生讲机器学习】21. 隐马尔可夫模型好难?看过来!(下篇)
这篇文章介绍了 HMM,讲解了 HMM 中的评估问题,并给出了完整的数学推导,希望对你有所帮助!⭐
欢迎三连!!一起加油!🎇
——Geeker_LStar