Viterbi-Algorithm
维特比算法是一个特殊但应用最广的动态规划算法。利用动态规划,可以解决任何一个图中的最短路径问题。而维特比算法是针对一个特殊的图-篱笆网了(Lattice)的有向图最短路径问题而提出来的。它之所以重要,是因为凡是使用隐马尔科夫模型描述的问题都可以用它解码,包括当前的数字通信、语音识别、机器翻译、拼音转汉字、分词等。
背景
假定用户(盲打时)输入的拼音时
y
1
,
y
2
,
⋯
,
y
N
y_1,y_2,\cdots ,y_N
y1,y2,⋯,yN,对应的汉字是
x
1
,
x
2
,
⋯
,
x
N
x_1,x_2,\cdots,x_N
x1,x2,⋯,xN(虽然真正的输入法产品都是以词作为输入单位的,为了便于说明问题及简单起见,以字为单位来解释维特比算法),那么根据当前介绍的工具:
x
1
,
x
2
,
.
.
.
,
x
N
=
arg
max
x
∈
P
P
(
x
1
,
x
2
,
⋯
,
x
N
∣
y
1
,
y
2
,
⋯
,
y
N
)
=
arg
max
x
∈
X
∏
i
=
1
N
P
(
y
i
∣
x
i
)
P
(
x
i
∣
x
i
−
1
)
(1)
x_1,x_2,...,x_N=\arg\max\limits_{x∈P}P(x_1,x_2,\cdots,x_N|y_1,y_2,\cdots,y_N)=\arg\max\limits_{x∈X}\prod^N_{i=1}P(y_i|x_i)P(x_i|x_{i-1}) \tag{1}
x1,x2,...,xN=argx∈PmaxP(x1,x2,⋯,xN∣y1,y2,⋯,yN)=argx∈Xmaxi=1∏NP(yi∣xi)P(xi∣xi−1)(1)
输入的可见序列为
y
1
,
y
2
,
⋯
,
y
N
y_1,y_2,\cdots ,y_N
y1,y2,⋯,yN,而产生他们的隐含序列是
x
1
,
x
2
,
⋯
,
x
N
x_1,x_2,\cdots,x_N
x1,x2,⋯,xN。可以用下图描述这样一个过程:

这是一个相对简单的隐马尔科夫链,没用状态跳跃,也没有自环。 P ( x i ∣ x i − 1 ) P(x_i|x_{i−1}) P(xi∣xi−1)是状态之间的转移概率, P ( y i ∣ x i ) P(y_i|x_i) P(yi∣xi)是每个状态的产生概率。现在,这个马尔科夫链的每个状态的输出是固定,但是每个状态的值可以变化。比如输出读音”zhong”的字可以是”中”、”种“等多个字。我们不妨抽象一点,用符号 x i j x_{ij} xij表示状态 x i x_i xi的第 j j j个可能的值。如果把每个状态按照不同的值展开,就得到下面这个篱笆网络(Lattice)

在上图中,每个状态有3个或4个值,当然时间中它们可以有任意个值。
那么从第一个状态到最后一个状态的任何一条路径(Path)都可能产生我们观察到的输出序列Y。当然这些路径的可能性不一样,而我们要做的就是找到最可能的这条路径,并不是很难。但麻烦的是这样的路径组合数非常多,会让序列状态数的增长呈指数式增长。汉语中每个无声调的拼音对应13个左右的国标汉字,假定句子长为10个字,那么这个组合数为 1 3 10 ∼ 5 × 1 0 14 13^{10} \sim 5 × 10^{14} 1310∼5×1014,这个计算量就相当的大了。因此,需要一个最好能和状态数目成正比的算法,而这个算法在1967年首次提出,即维特比算法。
维特比算法基础
维特比利用动态规划的思想来求解概率最大路径(可理解为求图最短路径),使得复杂度正比于序列长度,复杂度
为
O
(
N
⋅
D
2
)
O(N\cdot D^2)
O(N⋅D2),N为长度,D为宽度,从而很好地解决了问题的求解。
维特比算法的基础可以概括为下面三点:
- 如果概率最大的路径P(或者说是最短路径)经过某个点,比如下图中的 x 22 x_{22} x22,那么这条路径上从起始点S到 x 22 x_{22} x22的这一段路径Q,一定是S到 x 22 x_{22} x22之间的最短路径。否则,用S到 x 22 x_{22} x22的最短路径R代替Q,便构成了一条比P更短的路径,这就和之前的假设矛盾了。
- 从S到E路径必定经过第i时刻的某个状态,假定第i时刻有k个状态,那么如果记录了从S到i个状态的所有k个节点(所有时刻的所有状态)的最短路径,最终的最短路径必经过其中的一条。这样,在任何时刻,只要考虑非常有限条候选路径即可。
- 结合以上两点,假定当我们从状态i进入到i+1时,从S到i上各个节点的最短路径已经找到,并且记录到这些节点上,那么在计算出从起点S到第i+1状态的某个结点的最短路径时,只要考虑从S到前一个状态i所有的k个节点的最短路径,以及从这k个节点到 x i + 1 , j x_{i+1},j xi+1,j的距离即可。

为了记录中间变量,引入变量
δ
\delta
δ和
ψ
\psi
ψ。定义t时刻到状态为i的所有结点最大概率值(最短路径):
δ
t
(
i
)
=
max
P
(
i
t
=
i
,
i
t
−
1
,
⋯
,
i
1
,
o
t
,
⋯
,
o
1
∣
λ
)
,
i
=
1
,
2
,
⋯
,
N
\delta_t{(i)} = \max P(i_t=i,i_{t-1},\cdots,i_1,o_t,\cdots,o_1|\lambda),\ \ i=1,2,\cdots,N
δt(i)=maxP(it=i,it−1,⋯,i1,ot,⋯,o1∣λ), i=1,2,⋯,N
其中,
i
t
i_t
it表示最短路径,
o
t
o_t
ot表示观测符号,
λ
\lambda
λ表示模型参数。依据上式可以得出变量
δ
\delta
δ的递推式:
δ
t
+
1
(
i
)
=
m
a
x
[
δ
t
(
j
)
⋅
a
j
i
]
⋅
b
i
(
o
t
+
1
)
,
i
=
1
,
2
,
⋯
,
N
;
t
=
1
,
2
,
⋯
,
T
−
1
\delta_{t+1}(i)=max[\delta_t(j)\cdot a_{ji}]\cdot b_i(o_{t+1}), \ \ i=1,2,\cdots,N;t=1,2,\cdots,T-1
δt+1(i)=max[δt(j)⋅aji]⋅bi(ot+1), i=1,2,⋯,N;t=1,2,⋯,T−1
表示t时刻处于状态
j
j
j,t+1时刻转移到状态
i
i
i 且观测到符号
o
t
+
1
o_{t+1}
ot+1的最大概率。
定义
ψ
t
(
i
)
\psi_t(i)
ψt(i) 为时刻t到状态为i的概率最大路径的前一个时刻经过的结点,即它保存了最短路径所经过的结点:
ψ
t
(
i
)
=
arg
max
1
≤
j
≤
N
[
δ
t
−
1
(
j
)
⋅
a
j
i
]
\psi_t(i) = \arg\max\limits_{1\le j\le N}[\delta_{t-1}(j)\cdot a_{ji}]
ψt(i)=arg1≤j≤Nmax[δt−1(j)⋅aji]
可以看到,其实
ψ
\psi
ψ的值就是我们之前算的
δ
\delta
δ的前一项max的值所对应的状态!
举例
这里给出一个盒子和球的例子,跟我们之前在HMM中所讲的例子是一样的。
假设我们有3个盒子,每个盒子里都有红色和白色两种球,这三个盒子里球的数量分别是:
盒子 | 1 | 2 | 3 |
---|---|---|---|
红球数 | 5 | 4 | 7 |
白球数 | 5 | 6 | 3 |
按照下面的方法从盒子里抽球,开始的时候,从第一个盒子抽球的概率是0.2,从第二个盒子抽球的概率是0.4,从第三个盒子抽球的概率是0.4。以这个概率抽一次球后,将球放回。然后从当前盒子转移到下一个盒子进行抽球。规则是:如果当前抽球的盒子是第一个盒子,则以0.5的概率仍然留在第一个盒子继续抽球,以0.2的概率去第二个盒子抽球,以0.3的概率去第三个盒子抽球。如果当前抽球的盒子是第二个盒子,则以0.5的概率仍然留在第二个盒子继续抽球,以0.3的概率去第一个盒子抽球,以0.2的概率去第三个盒子抽球。如果当前抽球的盒子是第三个盒子,则以0.5的概率仍然留在第三个盒子继续抽球,以0.2的概率去第一个盒子抽球,以0.3的概率去第二个盒子抽球。如此下去,直到重复三次,得到一个球的颜色的观测序列:
O
=
{
红
,
白
,
红
}
O = \{红,白,红\}
O={红,白,红}
注意在这个过程中,观察者只能看到球的颜色序列,却不能看到球是从哪个盒子里取出的。
我们的观察集合是:
V
=
{
红
,
白
}
,
M
=
2
V=\{红,白\}, \ M=2
V={红,白}, M=2
我们的状态集合是:
Q
=
{
盒
子
1
,
盒
子
2
,
盒
子
3
}
,
N
=
3
Q = \{盒子1,盒子2,盒子3\}, \ N=3
Q={盒子1,盒子2,盒子3}, N=3
而观察序列和状态序列的长度为3.
初始状态分布为:
∏
=
(
0.2
,
0.4
,
0.4
)
T
\prod = (0.2,0.4,0.4)^T
∏=(0.2,0.4,0.4)T
状态转移概率分布矩阵为:
A
=
{
0.5
0.2
0.3
0.3
0.5
0.2
0.2
0.3
0.5
}
A = \left\{\begin{matrix} 0.5 & 0.2 & 0.3\\ 0.3 & 0.5 & 0.2 \\ 0.2 & 0.3 & 0.5 \end{matrix}\right\}
A=⎩⎨⎧0.50.30.20.20.50.30.30.20.5⎭⎬⎫
观测状态概率矩阵为:
B
=
{
0.5
0.5
0.4
0.6
0.7
0.3
}
B = \left\{ \begin{matrix} 0.5 & 0.5 \\ 0.4 & 0.6 \\ 0.7 & 0.3 \end{matrix}\right\}
B=⎩⎨⎧0.50.40.70.50.60.3⎭⎬⎫
我们已知球的颜色观测序列:
O
=
{
红
,
白
,
红
}
O = \{红,白,红\}
O={红,白,红}
试求最优状态序列。
求解:
首先需要得到三个隐藏状态在时刻1时对应的各自两个局部状态,此时观测状态为1:
δ
1
(
1
)
=
π
1
b
1
(
o
1
)
=
0.2
×
0.5
=
0.1
δ
1
(
2
)
=
π
2
b
2
(
o
1
)
=
0.4
×
0.4
=
0.16
δ
1
(
3
)
=
π
3
b
3
(
o
1
)
=
0.4
×
0.7
=
0.28
\delta_1(1) = \pi_1b_1(o_1) = 0.2\times0.5 = 0.1 \\ \delta_1(2) = \pi_2b_2(o_1) = 0.4\times0.4 = 0.16 \\ \delta_1(3) = \pi_3b_3(o_1) = 0.4\times0.7 = 0.28 \\
δ1(1)=π1b1(o1)=0.2×0.5=0.1δ1(2)=π2b2(o1)=0.4×0.4=0.16δ1(3)=π3b3(o1)=0.4×0.7=0.28
ψ 1 ( 1 ) = ψ 1 ( 2 ) = ψ 1 ( 3 ) = 0 \psi_1(1) = \psi_1(2) = \psi_1(3) = 0 ψ1(1)=ψ1(2)=ψ1(3)=0
现在开始递推三个隐藏状态在时刻2时对应的各自两个局部状态,此时观测状态为2:
δ
2
(
1
)
=
max
1
≤
j
≤
3
[
δ
1
(
j
)
a
j
1
]
b
1
(
o
2
)
=
max
1
≤
j
≤
3
[
0.1
×
0.5
,
0.16
×
0.3
,
0.28
×
0.2
]
×
0.5
=
0.028
max
1
≤
j
≤
3
[
δ
1
(
j
)
⋅
a
j
1
]
=
0.28
×
0.2
→
ψ
2
(
1
)
=
3
\delta_2(1) = \max\limits_{1\le j\le3}[\delta_1(j)a_{j1}]b_1(o_2) = \max\limits_{1\le j\le3}[0.1\times0.5,0.16\times0.3,0.28\times0.2]\times0.5=0.028 \\ \max\limits_{1\le j \le 3}[\delta_{1}(j)\cdot a_{j1}] = 0.28 \times 0.2 \ \rightarrow \ \psi_2(1) = 3 \\
δ2(1)=1≤j≤3max[δ1(j)aj1]b1(o2)=1≤j≤3max[0.1×0.5,0.16×0.3,0.28×0.2]×0.5=0.0281≤j≤3max[δ1(j)⋅aj1]=0.28×0.2 → ψ2(1)=3
δ 2 ( 2 ) = max 1 ≤ j ≤ 3 [ δ 1 ( j ) a j 2 ] b 2 ( o 2 ) = max 1 ≤ j ≤ 3 [ 0.1 × 0.2 , 0.16 × 0.5 , 0.28 × 0.3 ] × 0.6 = 0.0504 max 1 ≤ j ≤ 3 [ δ 1 ( j ) ⋅ a j 2 ] = 0.28 × 0.3 → ψ 2 ( 2 ) = 3 \delta_2(2) = \max\limits_{1\le j\le3}[\delta_1(j)a_{j2}]b_2(o_2) = \max\limits_{1\le j\le3}[0.1\times0.2,0.16\times0.5,0.28\times0.3]\times0.6=0.0504 \\ \max\limits_{1\le j \le 3}[\delta_{1}(j)\cdot a_{j2}] = 0.28 \times 0.3 \ \rightarrow \ \psi_2(2) = 3 \\ δ2(2)=1≤j≤3max[δ1(j)aj2]b2(o2)=1≤j≤3max[0.1×0.2,0.16×0.5,0.28×0.3]×0.6=0.05041≤j≤3max[δ1(j)⋅aj2]=0.28×0.3 → ψ2(2)=3
δ 2 ( 3 ) = max 1 ≤ j ≤ 3 [ δ 1 ( j ) a j 3 ] b 3 ( o 2 ) = max 1 ≤ j ≤ 3 [ 0.1 × 0.3 , 0.16 × 0.2 , 0.28 × 0.5 ] × 0.3 = 0.042 max 1 ≤ j ≤ 3 [ δ 1 ( j ) ⋅ a j 3 ] = 0.28 × 0.5 → ψ 2 ( 3 ) = 3 \delta_2(3) = \max\limits_{1\le j\le3}[\delta_1(j)a_{j3}]b_3(o_2) = \max\limits_{1\le j\le3}[0.1\times0.3,0.16\times0.2,0.28\times0.5]\times0.3=0.042 \\ \max\limits_{1\le j \le 3}[\delta_{1}(j)\cdot a_{j3}] = 0.28 \times 0.5 \ \rightarrow \ \psi_2(3) = 3 \\ δ2(3)=1≤j≤3max[δ1(j)aj3]b3(o2)=1≤j≤3max[0.1×0.3,0.16×0.2,0.28×0.5]×0.3=0.0421≤j≤3max[δ1(j)⋅aj3]=0.28×0.5 → ψ2(3)=3
继续递推三个隐藏状态在时刻3时对应的各自两个局部状态,此时观测状态为1:
δ
3
(
1
)
=
max
1
≤
j
≤
3
[
δ
2
(
j
)
a
j
1
]
b
1
(
o
3
)
=
max
1
≤
j
≤
3
[
0.028
×
0.5
,
0.0504
×
0.3
,
0.042
×
0.2
]
×
0.5
=
0.00756
max
1
≤
j
≤
3
[
δ
2
(
j
)
⋅
a
j
1
]
=
0.0504
×
0.3
→
ψ
3
(
1
)
=
2
\delta_3(1) = \max\limits_{1\le j\le3}[\delta_2(j)a_{j1}]b_1(o_3) = \max\limits_{1\le j\le3}[0.028\times0.5,0.0504\times0.3,0.042\times0.2]\times0.5=0.00756 \\ \max\limits_{1\le j \le 3}[\delta_{2}(j)\cdot a_{j1}] = 0.0504\times 0.3 \ \rightarrow \ \psi_3(1) = 2 \\
δ3(1)=1≤j≤3max[δ2(j)aj1]b1(o3)=1≤j≤3max[0.028×0.5,0.0504×0.3,0.042×0.2]×0.5=0.007561≤j≤3max[δ2(j)⋅aj1]=0.0504×0.3 → ψ3(1)=2
δ 3 ( 2 ) = max 1 ≤ j ≤ 3 [ δ 2 ( j ) a j 2 ] b 2 ( o 3 ) = max 1 ≤ j ≤ 3 [ 0.028 × 0.2 , 0.0504 × 0.5 , 0.042 × 0.3 ] × 0.4 = 0.01008 max 1 ≤ j ≤ 3 [ δ 2 ( j ) ⋅ a j 2 ] = 0.0504 × 0.5 → ψ 3 ( 2 ) = 2 \delta_3(2) = \max\limits_{1\le j\le3}[\delta_2(j)a_{j2}]b_2(o_3) = \max\limits_{1\le j\le3}[0.028\times0.2,0.0504\times0.5,0.042\times0.3]\times0.4=0.01008 \\ \max\limits_{1\le j \le 3}[\delta_{2}(j)\cdot a_{j2}] = 0.0504\times 0.5 \ \rightarrow \ \psi_3(2) = 2 \\ δ3(2)=1≤j≤3max[δ2(j)aj2]b2(o3)=1≤j≤3max[0.028×0.2,0.0504×0.5,0.042×0.3]×0.4=0.010081≤j≤3max[δ2(j)⋅aj2]=0.0504×0.5 → ψ3(2)=2
δ 3 ( 3 ) = max 1 ≤ j ≤ 3 [ δ 2 ( j ) a j 3 ] b 3 ( o 3 ) = max 1 ≤ j ≤ 3 [ 0.028 × 0.3 , 0.0504 × 0.2 , 0.042 × 0.5 ] × 0.7 = 0.0147 max 1 ≤ j ≤ 3 [ δ 2 ( j ) ⋅ a j 3 ] = 0.042 × 0.5 → ψ 3 ( 3 ) = 3 \delta_3(3) = \max\limits_{1\le j\le3}[\delta_2(j)a_{j3}]b_3(o_3) = \max\limits_{1\le j\le3}[0.028\times0.3,0.0504\times0.2,0.042\times0.5]\times0.7=0.0147 \\ \max\limits_{1\le j \le 3}[\delta_{2}(j)\cdot a_{j3}] = 0.042\times 0.5 \ \rightarrow \ \psi_3(3) = 3 \\ δ3(3)=1≤j≤3max[δ2(j)aj3]b3(o3)=1≤j≤3max[0.028×0.3,0.0504×0.2,0.042×0.5]×0.7=0.01471≤j≤3max[δ2(j)⋅aj3]=0.042×0.5 → ψ3(3)=3
此时已经到最后的时刻,我们开始准备回溯:
- 此时最大概率为 δ 3 ( 3 ) \delta_3(3) δ3(3),从而得到 i 3 ∗ = 3 i_3^*=3 i3∗=3
- 由于 ψ 3 ( 3 ) = 3 \psi_3(3)=3 ψ3(3)=3,所以 i 2 ∗ = 3 i^*_2=3 i2∗=3
- 又由于 ψ 2 ( 3 ) = 3 \psi_2(3)=3 ψ2(3)=3,所以 i 1 ∗ = 3 i^*_1=3 i1∗=3
从而可得到当观测序列为(红,白,红)时得到最终的最可能的隐藏状态序列为:
(
i
1
∗
,
i
2
∗
,
i
3
∗
)
=
(
3
,
3
,
3
)
(i^*_1,i^*_2,i^*_3) = (3,3,3)
(i1∗,i2∗,i3∗)=(3,3,3)
总结
维特比算法也是寻找序列最短路径的一个通用方法,和dijkstra算法有些类似,但是dijkstra算法并没有使用动态规划,而是贪心算法。同时维特比算法仅仅局限于求序列最短路径,而dijkstra算法是通用的求最短路径的方法。
总的来说,无论在语音识别、输入法打字中,输入都是按照流(Stream)的方式进行的,只要处理每个状态的时间比讲话,或者打字速度,那么无论输入有多长,解码过程永远就是实时的。