维特比算法

69 阅读3分钟

维特比算法

背景

首先介绍HMM,隐马尔可夫模型。 HMM是指状态SS随时间tt不断转移,转移过程满足马尔科夫性P(St+1St)=P(St+1St,St1...)P(S_{t+1}|S_t)=P(S_{t+1}|S_t, S_{t-1}...),然而我们并不知道状态是多少,只知道每个时刻的观测值OtO_t,那么给定一个观测序列O1,O2,...OTO_1, O_2,...O_T,如何找到隐含的状态转移S1,...,STS_1,...,S_T呢?

建模

首先我们应该先明确所谓找到隐含的状态转移就是找到最有可能的状态转移,所以自然这是一个概率建模。我们一般会先确定相关的概率,首先最容易确定的是P(OtSt)P(O_t|S_t),一般假设当前的观测值只和当前状态有关,此外HMM的假设里也可以知道P(StSt1)P(S_t|S_{t-1}),这样有了这两类概率,我们就对整个模型有了定量描述。至于说具体这些概率值是多少,这取决于你的问题,domain expert可以发挥作用。后面应用中会具体介绍。

算法

一个naive的思路是暴力枚举所有可能的状态转移,对每一条转移序列计算概率P(O0S0)i=1TP(SiSi1)P(OiSi)P(O_0|S_0)\prod_{i=1}^T P(S_{i}|S_{i-1})P(O_i|S_i),如果设总状态有NN个,一共有TT步,那么路径数量可以达到NTN^T,不是一个好算法。

从最短路径得到启发,其实我们找的就是一个最短路径,甚至比最短路还要简单,因为他不像图那样有复杂拓扑结构。所以很自然这里面存在最优子结构,那就是:1 t1~t的最有可能的状态转移路径中一定包含了1 t11~t-1中最有可能的路径

有了上面的发现,就可以设计动态规划的递推公式了。首先明确状态,dp[t,s]dp[t, s]表示在第tt时刻,到达状态ss且观测为OtO_t的最有可能的路径概率,因此

dp[t,s]=P(Ots)maxs(dp[t1,s]P(Sts))dp[t, s] = P(O_t|s)\max_{s'} (dp[t-1, s']P(S_{t}|s'))

右侧的max其实是在枚举找上一轮到达ss状态最大可能的路径。

对于t=0t=0的初始情况,我们直接用dp[0,s]=P(O0s)dp[0,s]=P(O_0|s)来表示。 这样按照tt由小到大递推完,同时记录下每个tt选择max对应的状态ss',然后在从后往前得到状态转移路径即可。

伪代码如下

# p_trans是状态转移概率P(S|S'),p_observ是观察概率P(O|S)
# observs是观察序列
是观察P(O|s)
dp = np.zeros([T, N])
choice = np.zeros([T, N])
# 初始化
for s in range(N):
    dp[0, s] = p_observ(observs[0], s)
# 递推
for t in range(1, T):
    for s in range(N):
        dp[t, s] = INF
        cur_observ_prob = p_observ(observs[0], s)
        for s_ in range(N):
            if dp[t, s] < dp[t-1,s_] * cur_observ_prob: 
                dp[t, s] = dp[t-1, s_] * cur_observ_prob
                choice[t, s] = s_
# 递推找路径
last = np.argmax(dp[T-1])
path = [last]
cur = choice[T - 1, last]
for t in reversed(range(T-1)):
    prev = dp[t, cur]
    path.append(prev)
    cur = prev
return path.reverse()

应用

其实与其说是viterbi的应用,不如说是HMM的应用。

比如在时空领域,通常需要把GPS定位点和路网做匹配,这里observ就是gps坐标,state就是路网中一条特定的路段。那么一个坐标在某条路段的概率就是P(OS)P(O|S),这个可以用距离配合高斯分布估算概率。而状态转移概率P(SS)P(S|S')则是路网中从一段路转移到另一段路的概率,这里一半假设司机走最短路,所以可以按两个路段最短路的指数分布计算概率。当然这都是很直观的概率建模,你也可以考虑速度、方向、路段的其他信息等优化概率建模,这就是domain expert可以卷和水paper的地方了。。。

在语音识别领域,如何把一段音频转化成文字,可以认为observ是观测到的音频,状态转移是各个单词之间的转移概率。当然NLP的专家有一万种方法可以计算这里的概率。

总之其实模型一旦确定,框架就定死了,优化只不过是在调整里面的具体建模数值。从水文章的角度,HMM这么古老的东西肯定不行啦,但是如果domain里用到了时兴的技术或者对HMM框架有点小微调也许可以。