\qquad 对于一个有很多分词可能的长句子,我们当然可以用暴力方法去计算出所有的分词可能的概率,再找出最优分词方法。但是用维特比算法可以大大简化求出最优分词的时间。
\qquad 大家一般知道维特比算法是用于隐式马尔科夫模型HMM解码算法的,但是它是一个通用的求序列最短路径的方法,不光可以用于HMM,也可以用于其他的序列最短路径算法,比如最优分词。
\qquad 维特比算法采用的是动态规划来解决这个最优分词问题的,动态规划要求局部路径也是最优路径的一部分。
\qquad
首先我们看一个简单的分词例子:“人生如梦境”。它的可能分词可以用下面的概率图表示:
\qquad
图中的箭头为通过统计语料库而得到的对应的各分词位置BEMS(开始位置,结束位置,中间位置,单词)的条件概率。比如
P
(
生
∣
人
)
=
0.17
P(生|人)=0.17
P(生∣人)=0.17。
\qquad 有了这个图,维特比算法需要找到从Start到End之间的一条最短路径。对于在End之前的任意一个当前局部节点,我们需要得到到达该节点的最大概率 δ \delta δ,和记录到达当前节点满足最大概率的前一节点位置 Ψ \Psi Ψ。
\qquad
首先我们初始化有:
δ
(
人
)
=
0.26
,
Ψ
(
人
)
=
s
t
a
r
t
\delta(人) = 0.26 ,\Psi(人) = start \\
δ(人)=0.26,Ψ(人)=start
δ
(
人
生
)
=
0.44
,
Ψ
(
人
生
)
=
s
t
a
r
t
\delta(人生) = 0.44, \Psi(人生) = start
δ(人生)=0.44,Ψ(人生)=start
\qquad
对于节点"生",它只有一个前向节点,因此有:
δ
(
生
)
=
δ
(
人
)
P
(
生
∣
人
)
=
0.26
∗
0.17
=
0.0442
,
Ψ
(
生
)
=
人
\delta(生) = \delta(人) P(生|人) = 0.26 * 0.17 = 0.0442, \Psi(生) = 人
δ(生)=δ(人)P(生∣人)=0.26∗0.17=0.0442,Ψ(生)=人
\qquad
对于节点"如",就稍微复杂一点了,因为它有多个前向节点,我们要计算出到“如”概率最大的路径:
δ
(
如
)
=
m
a
x
{
δ
(
生
)
P
(
如
∣
生
)
,
δ
(
人
生
)
P
(
如
∣
人
生
)
}
=
m
a
x
{
0.0442
∗
0.038
,
0.44
∗
0.72
}
=
m
a
x
{
0.0168796
,
0.3168
}
=
0.3168
,
Ψ
(
如
)
=
人
生
\begin{aligned} \delta(如) & = max\{ \delta(生)P(如|生),\delta(人生)P(如|人生)\} \\ & = max \{0.0442*0.038 ,0.44*0.72 \} \\ & = max \{0.0168796,0.3168 \} \\ & = 0.3168 \end{aligned} , \Psi(如) = 人生
δ(如)=max{δ(生)P(如∣生),δ(人生)P(如∣人生)}=max{0.0442∗0.038,0.44∗0.72}=max{0.0168796,0.3168}=0.3168,Ψ(如)=人生
\qquad
类似的方法可以用于其他节点如下:
δ
(
如
梦
)
=
δ
(
人
生
)
P
(
如
梦
∣
人
生
)
=
0.44
∗
0.55
=
0.242
,
Ψ
(
如
梦
)
=
人
生
\delta(如梦) = \delta(人生)P(如梦|人生) = 0.44 * 0.55 = 0.242,\Psi(如梦) = 人生
δ(如梦)=δ(人生)P(如梦∣人生)=0.44∗0.55=0.242,Ψ(如梦)=人生
δ
(
梦
)
=
δ
(
如
)
P
(
梦
∣
如
)
=
0.3168
∗
0.63
=
0.1996
,
Ψ
(
梦
)
=
如
\delta(梦) = \delta(如)P(梦|如) = 0.3168 * 0.63 = 0.1996,\Psi(梦) = 如
δ(梦)=δ(如)P(梦∣如)=0.3168∗0.63=0.1996,Ψ(梦)=如
δ
(
境
)
=
m
a
x
{
δ
(
梦
)
P
(
境
∣
梦
)
,
δ
(
如
梦
)
P
(
境
∣
如
梦
)
}
=
m
a
x
{
0.1996
∗
0.18
,
0.242
∗
0.13
}
=
m
a
x
{
0.0359
,
0.03146
}
=
0.0359
,
Ψ
(
境
)
=
梦
\begin{aligned} \delta(境) &= max \{ \delta(梦)P(境|梦) ,\delta(如梦)P(境|如梦)\} \\ &=max\{0.1996 * 0.18,0.242*0.13 \} \\ &=max\{ 0.0359 ,0.03146 \} \\ &=0.0359 \end{aligned},\Psi(境) = 梦
δ(境)=max{δ(梦)P(境∣梦),δ(如梦)P(境∣如梦)}=max{0.1996∗0.18,0.242∗0.13}=max{0.0359,0.03146}=0.0359,Ψ(境)=梦
δ
(
梦
境
)
=
δ
(
如
)
P
(
梦
境
∣
如
)
=
0.3168
∗
0.51
=
0.161568
,
Ψ
(
梦
境
)
=
如
\delta(梦境) = \delta(如)P(梦境|如) = 0.3168 * 0.51 = 0.161568,\Psi(梦境) = 如
δ(梦境)=δ(如)P(梦境∣如)=0.3168∗0.51=0.161568,Ψ(梦境)=如
\qquad
最后我们看看最终节点End:
δ
(
e
n
d
)
=
m
a
x
{
δ
(
境
)
P
(
e
n
d
∣
境
)
,
δ
(
梦
境
)
P
(
e
n
d
∣
梦
境
)
}
=
m
a
x
{
0.0359
∗
0.13
,
0.161568
∗
0.25
}
=
m
a
x
{
0.004667
,
0.040392
}
=
0.0404
,
Ψ
(
e
n
d
)
=
梦
境
\begin{aligned} \delta(end) &= max\{ \delta(境)P(end|境),\delta(梦境)P(end|梦境)\} \\ &=max\{0.0359 *0.13, 0.161568 * 0.25\} \\ &=max\{0.004667,0.040392\} \\ &=0.0404 \end{aligned},\Psi(end) = 梦境
δ(end)=max{δ(境)P(end∣境),δ(梦境)P(end∣梦境)}=max{0.0359∗0.13,0.161568∗0.25}=max{0.004667,0.040392}=0.0404,Ψ(end)=梦境
\qquad
由于最后的最优解为“梦境”,现在我们开始用
Ψ
\Psi
Ψ反推:
Ψ
(
e
n
d
)
=
梦
境
→
Ψ
(
梦
境
)
=
如
→
Ψ
(
如
)
=
人
生
\Psi(end) = 梦境 \rightarrow \Psi(梦境) = 如 \rightarrow \Psi(如) = 人生
Ψ(end)=梦境→Ψ(梦境)=如→Ψ(如)=人生
\qquad
从而最终的分词结果为"人生/如/梦境"。