Skip to content

马尔可夫链

马尔可夫链因俄国数学家Andrey Andreyevich Markov得名, 为状态空间中从一个状态到另一个状态转换的随机过程, 该过程要求具备"无记忆"的性质, 下一状态的概率分布只能由当前状态决定, 在时间序列中和它前面的事件无关, 这种特定类型的"无记忆性"称作马尔可夫性质.

马尔可夫假设

马尔可夫假设是马尔可夫链的基础.公式可以表示为p(X)=i=1np(StSt1)p(X)=\prod_{i=1}^n p(S_t|S_{t-1}). 它说明, 当前状态StS_{t}只依赖于上一个状态St1S_{t-1}, 而与之前的状态S1,...,St2S_{1}, ..., S_{t-2}无关. 对于其余状态也是同理的.

上述只是一阶马尔可夫假设, 即假定当前的状态仅依赖于前面一个状态. 由此衍生出kk阶马尔可夫假设, 即假设当前状态依赖于最近的kk个状态, 即p(X)=i=1np(StSt1,...,Stk)p(X)=\prod_{i=1}^n p(S_t|S_{t-1}, ..., S_{t-k}). 这个概率又叫作状态转移概率.

例子

通过今天的天气预测明天的天气. 假设今天是雨天☔️, 预测明天的天气, 符合(一阶)马尔可夫假设. 下面是形象的概率图.

我们可以看到, 从雨天到晴天的概率是0.30.3, 从雨天到阴天的概率是0.30.3, 从雨天到雨天的概率是0.40.4, 所以明天大概率还是雨天. 我们可以将上图用一个矩阵来表示.

S=[S11S12S1NS21S22S2NS31S32S3NSN1SN2SNN] S = \begin{bmatrix} S_{11} & S_{12} & \cdots & S_{1N} \\ S_{21} & S_{22} & \cdots & S_{2N} \\ S_{31} & S_{32} & \cdots & S_{3N} \\ \vdots & \vdots & \ddots & \vdots \\ S_{N1} & S_{N2} & \cdots & S_{NN} \\ \end{bmatrix}

其中Sij=p(St=jSt1=i)S_{ij}=p(S_t=j|S_{t-1}=i), 表示从iijj的转移概率. 那么, 我们可不可以从任意的初始状态开始, 推导出后面的所有状态呢? 假设起始概率为πi\pi_i, 表示马尔可夫链从状态ii开始.

给你一个小小的练习, 计算下列天气变化的可能性:

  • 晴天 -> 晴天 -> 多云 -> 多云
  • 多云 -> 晴天 -> 多云 -> 雨天

隐马尔可夫模型

在普通的马尔可夫模型中, 系统的状态是完全可见的. 也就是说, 每个时刻系统处于哪个状态是已知的, 可以直接观测到. 而在隐马尔可夫模型, HMM中, 系统的状态是隐藏的, 无法直接观测到, 但是受状态影像的某些变量是可见的. 每一个状态在可能输出的序号上都有一概率分布, 因此输出符号的序列能够透露出状态序列的一些信息.

例子

假设现在我们漂到了一个岛上, 这里没有天气预报, 只有一片片的海藻, 而这些海藻的状态如干燥, 潮湿等和天气的变换有一定的关系, 既然海藻是能看到的, 那它就是观测状态, 天气信息看不到就是隐藏状态.

再举一个例子, 如下图所示是一个普通马尔可夫模型.

HMM就是在这个基础上, 加入了一个隐藏状态和观测状态的概念.

图中, X的状态是不可见的, 而Y的状态是可见的. 我们可以将X看成是天气情况, 而Y看成是某个人穿的衣物类型, 如下图所示.

我们的任务就是从这个人穿的衣物类型预测天气变化. 在这里, 有两种类型的概率:

  • 转移概率: transition probabilities, 从一个隐藏状态到另一个隐藏状态的概率
  • 观测概率: emission probabilities, 从一个隐藏状态到一个观测变量的过程

注意⚠️, HMM模型做了两个很重要的假设:

  1. 齐次马尔可夫链假设: 当前的隐藏状态之和前一个隐藏状态有关
  2. 观测独立性假设: 某个观测状态只和生成它的隐藏状态有关, 和别的观测状态无关

下图给出了一个可能的观测状态和隐藏状态之间的关系, 这个就是HMM所要达到的最终效果.

可视化表达:

参数

HMM的参数可以表示为λ=(A,B,π)\lambda = (\bm{A}, \bm{B}, \bm{\pi}), 定义隐状态的可能的取值的数量为NN, 如雨天, 阴天, 晴天, N=3N=3. 观测变量的可能的取值的数量为MM, 如穿夹克, 穿棉袄, M=2M=2.

  • 初始状态概率向量π\bm{\pi}. 它是一个长度为NN的向量, 其中πi\pi_i表示在初始时刻t=1t=1时处于隐状态ii的概率, 所有的初始状态满足i=1Nπi=1\sum_{i=1}^N \pi_i=1
  • 状态转移概率矩阵A\bm{A}, A=[aij]\bm{A}=[a_{ij}], 它是一个N×MN\times M的矩阵. aija_{ij}表示在时刻tt处于隐状态ii时, 下一时刻t+1t+1转移到隐状态jj的概率, 所有的转移概率满足j=1Naij=1\sum_{j=1}^N a_{ij}=1
  • 观测概率矩阵B\bm{B}, B=[bj(ok)]\bm{B}=[b_j(o_k)], 它是一个N×MN\times M的矩阵. bj(ok)b_j(o_k)表示在隐状态jj下生成观测值oko_k的概率. 对于连续的观测值, 可以使用概率密度函数来表示概率

假设

HMM做了两个基本假设, 在上面的例子中也提到了.

  • 齐次性假设: 即假设隐藏的马尔可夫链在任意时刻tt的状态只依赖于它在前一时刻的状态, 与其他时刻的状态和观测无关, 也与时刻tt本身无关
  • 观测独立性假设: 即假设任意时刻的观测值只依赖于该时刻的马尔可夫链的状态, 与其他观测及状态无关

问题

HMM的三个基本问题:

  • 概率计算问题(也叫做Evaluation Problem): 给定模型λ=(A,B,π)\lambda = (\bm{A}, \bm{B}, \bm{\pi})和观测序列O=(o1,o2,...,oM)\bm{O}=(o_1, o_2, ..., o_M), 计算观测序列OO出现的概率p(O;λ)p(\bm{O}; \lambda). 即评估模型λ\lambda与观测序列O\bm{O}之间的匹配程度.
  • 学习问题(也叫做Learning Problem): 已知观测序列O=(o1,o2,...,oM)\bm{O}=(o_1, o_2, ..., o_M), 估计模型λ=(A,B,π)\lambda=(\bm{A}, \bm{B}, \bm{\pi})的参数, 使得在该模型下的观测序列概率p(O;λ)p(\bm{O}; \lambda)最大, 即用极大似然估计的方法估计参数
  • 预测问题(也叫做Decoding Problem): 已知模型λ=(A,B,π)\lambda = (\bm{A}, \bm{B}, \bm{\pi})和观测序列O=(o1,o2,...,oM)\bm{O}=(o_1, o_2, ..., o_M), 求对给定观测序列的条件概率P(IO)P(\bm{I}|\bm{O})最大的状态序列I=(i1,i2,...,ir)\bm{I}=(i_1, i_2, ..., i_r), 即给定观测序列, 求最可能的对应的状态序列

概率计算问题

概率计算问题, Evaluation Problem. 指的是给定一个HMM模型λ=(π,A,A0)\lambda = (\bm{\pi}, \bm{A}, \bm{A_0})和一个观测序列X=x1,x2,...,xmX=x_1, x_2, ..., x_m, 计算该观测序列出现的概率.

注意

这边的π\bm{\pi}很鸡肋, 其实不用写的, 直接写一个状态转移矩阵AA就够了. 然后这边的π\pi也不是我上面说的意思, 他这里的πi\pi_i是指时间步ii的状态, 而我上面说的πi\pi_i是初始时刻处于隐状态ii的概率. 最后应该加上一个观测概率矩阵E\bm{E}, 这边漏了. 但是为了保持和课件的统一, 下面都用它的写法.

例子

给定一个HMM模型如下(包含初始状态向量, 状态转移概率矩阵, 观测概率矩阵):

计算观测序列X=X= Shirt, Hoodie出现的概率.

我们可以使用枚举法: 首先, 列举出所有可能的状态序列, 由于我们的观测序列长度是22, 所以长度为22的状态序列有32=93^2=9种组合, 如, Rainy, Rainy; Rainy, Cloudy; Rainy, Sunny; ... 对于每一种状态序列, 计算其对应的观察序列X=X= Shirt, Hoodie的条件概率, 例如, 对于状态序列Rainy, Cloudy, 计算观测序列条件概率p(X,{Rainy,Cloudy})p(X, \{Rainy, Cloudy\})的步骤为:

  • 初始状态: 状态从Rainy开始, 所以初始概率参见初始状态向量, 是0.60.6
  • 状态转移: 从Rainy转移到Cloudy的概率参见状态转移概率矩阵, 是0.30.3
  • 观测概率:
    • 在第一个时刻Rainy观察到Shirt的概率参考观测概率矩阵, 是0.80.8
    • 在第二个时刻Cloudy观测到Hoodie的概率参考观测概率矩阵, 是0.10.1

所以, 结果为0.6×0.3×0.8×0.1=0.01440.6\times 0.3\times 0.8\times 0.1=0.0144. 对于所有的状态序列, 如上所示计算观测序列的条件概率. 相加这99个条件概率, 得到最终的观测序列概率.

可以看到, 计算一个简单的观测序列Short, Hoodie的过程就进行了4×9=364\times 9=36次乘法. 令NN为可能的状态的数量, 在这里有三个可能的状态, Rainy, Cloudy, Sunny. 令TT为观测序列的长度, 在这里是22. 那么复杂度就是2TNT2TN^T. 在实际中, 观测序列TT往往很大, 而状态数NN相对来说较小, 导致该算法的复杂度异常高. 解决这种问题的方法是使用前向算法.

前向算法

前向算法, Forward Algorithm, 是一种动态规划算法, 用于高效计算给定观察序列的概率. 就像之前我们干的一样, 对于所有可能的隐藏状态序列, 前向算法都会求观测序列的条件概率, 但是在计算过程中会存储中间值来加速计算.

前向概率fk(i)f_k(i)表示在时间ii时处于状态kk的条件下, 观察到部分观测序列的概率. fk(i)=ek(xi)jfj(i1)ajkf_k(i)=e_k(x_i)\sum_j f_j(i-1)a_{jk}, 其中ek(xi)=p(xiπi=k)e_k(x_i)=p(x_i|\pi_i=k)是状态kk下观察到观测序列xix_i的观测概率, ajk=p(πi=kπi1=j)a_{jk}=p(\pi_i=k|\pi_{i-1}=j)是从状态jj转移到状态kk的转移概率. 通过上述公式, 可以递归地计算fk(i)f_k(i), 因为fk(i)f_k(i)依赖于上一个时刻i1i-1地前向概率fj(i1)f_j(i-1). 这种递归计算不需要重新计算已经求得的中间结果, 大大减少了重复计算的次数.

前向算法的时间复杂度为N2TN^2T, 其中TT是观测序列长度, NN是状态数量, 相比枚举法的2TNT2TN^T的复杂度, 前向算法的效率显著提高.

前向算法主要由33步计算过程组成:

  1. 初始化

    计算在时间步t=1t=1时每个状态kk的前向概率fk(1)f_k(1), 公式为fk(1)=A0(k)ek(x1)f_k(1)=A_0(k)e_k(x_1), 其中A0(k)A_0(k)是初始时刻状态kk的概率, 参考初始状态向量; ek(x1)=p(x1π1=k)e_k(x_1)=p(x_1|\pi_1=k)是在状态kk下观察到第一个观测值x1x_1的概率.

  2. 迭代

    对于接下来的时间步t=2,...,mt=2, ..., m, 计算每个状态kk的前向概率fk(i)f_k(i). fk(i)=ek(xi)jfj(i1)ajkf_k(i)=e_k(x_i)\sum_j f_j(i-1)a_{jk}. 各部分的含义参见上方.

  3. 终止

    在最后一个时间步mm结束后, 对所有状态的前向概率求和. p(X)=kfk(m)p(X)=\sum_{k}f_k(m).

例子

继续上面的例子.

11的初始状态向量 + 22个矩阵:

  1. 初始化

    • fRainy(1)=A0(Rainy)eRainy(Shirt)=0.6×0.8=0.48f_{Rainy}(1)=A_0(Rainy)e_{Rainy}(Shirt)=0.6\times 0.8=0.48
    • fCloudy(1)=A0(Cloudy)eCloudy(Shirt)=0.3×0.5=0.15f_{Cloudy}(1)=A_0(Cloudy)e_{Cloudy}(Shirt)=0.3\times 0.5=0.15
    • fSunny(1)=A0(Sunny)eSunny(Shirt)=0.1×0.01=0.001f_{Sunny}(1)=A_0(Sunny)e_{Sunny}(Shirt)=0.1\times 0.01=0.001
  2. 迭代

    迭代计算第ii个时间步的前向概率.

    • fRainy(2)=eRainy(Hoodie)(fRainy(1)aRainy,Rainy+fCloudy(1)aCloudy,Rainy+fSunny(1)aSunny,Rainy)=0.01×(0.48×0.6+0.15×0.4+0.001×0.1)=0.0035f_{Rainy}(2)=e_{Rainy}(Hoodie)(f_{Rainy}(1)a_{Rainy, Rainy}+f_{Cloudy}(1)a_{Cloudy, Rainy}+f_{Sunny}(1)a_{Sunny, Rainy})=0.01\times(0.48\times 0.6+0.15\times 0.4 + 0.001\times 0.1)=0.0035
    • fCloudy(2)=eCloudy(Hoodie)(fRainy(1)aRainy,Cloudy+fCloudy(1)aCloudy,Cloudy+fSunny(1)aSunny,Cloudy)=0.1×(0.48×0.3+0.15×0.3+0.001×0.4)=0.0189f_{Cloudy}(2)=e_{Cloudy}(Hoodie)(f_{Rainy}(1)a_{Rainy, Cloudy}+f_{Cloudy}(1)a_{Cloudy, Cloudy}+f_{Sunny}(1)a_{Sunny, Cloudy})=0.1\times(0.48\times 0.3+0.15\times 0.3 + 0.001\times 0.4)=0.0189
    • fSunny(2)=eSunny(Hoodie)(fRainy(1)aRainy,Sunny+fCloudy(1)aCloudy,Sunny+fSunny(1)aSunny,Sunny)=0.79×(0.48×0.1+0.15×0.3+0.001×0.5)=0.0739f_{Sunny}(2)=e_{Sunny}(Hoodie)(f_{Rainy}(1)a_{Rainy, Sunny}+f_{Cloudy}(1)a_{Cloudy, Sunny}+f_{Sunny}(1)a_{Sunny, Sunny})=0.79\times(0.48\times 0.1+0.15\times 0.3 + 0.001\times 0.5)=0.0739
  3. 终止

    当前最后一个时间步m=2m=2, p(X)=p(Shirt,Hoodie)=fRainy(2)+fCloudy(2)+fSunny(2)=0.0035+0.0189+0.0739=0.0963p(X)=p(Shirt, Hoodie)=f_{Rainy}(2)+f_{Cloudy}(2)+f_{Sunny}(2)=0.0035+0.0189+0.0739=0.0963.

预测问题

预测问题, Decoding Problem. 指的是给定一个HMM模型λ=(π,A,A0)\lambda=(\bm{\pi}, \bm{A}, \bm{A_0})和一个观测序列X=x1,x2,...,xmX=x_1, x_2, ..., x_m, 计算最可能对应的隐藏序列.

Viterbi算法

Viterbi算法是一种动态规划算法, 用于计算每个状态的最优路径的概率, 称之为Viterbi得分. 由于它在每个时间点, 只需要维护每个状态的最高得分路径, 所以和前向算法类似, 能提高计算效率.

给定时间ii和状态kk. 状态的Viterbi得分Vk(i)V_k(i)表示到达该状态的最优路径的概率, 计算公式为Vk(i)=ek(xi)maxjVj(i1)ajkV_k(i)=e_k(x_i)max_j V_j(i-1)a_{jk}. 其中, ek(xi)=p(xiπi=k)e_k(x_i)=p(x_i|\pi_i=k)表示在当前状态kk下, 观测到xix_i的观测概率. ajk=p(πi=kπi1=j)a_{jk}=p(\pi_i=k|\pi_{i-1}=j)表示从前一状态jj转移到当前状态kk的转移概率. maxjVj(i1)ajkmax_j V_j(i-1)a_{jk}用于选择上一个时间步中到达当前状态kk的最优路径.

Viterbi得分Vk(i)V_k(i)可以递归地基于上一时间步的得分Vj(i1)V_j(i-1)计算, 因此, 不需要重复计算所有路径, 而是逐步优化路径选择.

Viterbi得分可以给出最终状态结束的最佳路径的概率, 但是仅仅只靠得分本身, 我们无法确定从起始状态到最终状态的整个路径. 为了确定完整的路径, 需要从最终状态回溯到其实状态, 为了实现回溯, 在计算Viterbi得分的过程中, 需要为每个状态保存一个指针, 这个指针记录了每一步使得Viterbi得分最大的前一状态. 数学表达为Ptrk(i)=argmaxjVj(i1)ajkPtr_k(i)=argmax_j V_j(i-1)a_{jk}, 指向时间i1i-1时能提供最高得分的状态jj.

与前向算法类似, Viterbi算法也分为三步:

  1. 初始化

    在初始时间步t=1t=1的时候, 计算每个状态的Viterbi得分, 公式为Vk(1)=A0(k)ek(x1)V_k(1)=A_0(k)e_k(x_1). 其中A0(k)A_0(k)是初始时刻状态kk的概率, 参考初始状态向量; ek(x1)=p(x1π1=k)e_k(x_1)=p(x_1|\pi_1=k)是在状态kk下观察到第一个观测值x1x_1的概率.

  2. 迭代

    对于时间步t=2,...,mt=2, ..., m:

    1. Viterbi得分: 计算状态kk在时间ii的得分Vk(i)=ek(xi)maxjVj(i1)ajkV_k(i)=e_k(x_i)max_j V_j(i-1)a_{jk}

    2. 回溯指针: 记录状态kk在时间ii的回溯路径, 用于后续的路径回溯Ptrk(i)=argmaxjVj(i1)ajkPtr_k(i)=argmax_j V_j(i-1)a_{jk}

  3. 终止

    1. 确定最终状态: 在最后一个时间步mm, 找到具有最高Viterbi得分的状态πm=argmaxkVk(m)\pi_m=argmax_k V_k(m)

    2. 回溯路径: 从最后的状态开始, 通过回溯指针逐步确定前一个时间步的最佳状态: πi1=Ptrπi(i)\pi_{i-1}=Ptr_{\pi_i}(i)

例子

还是上面的例子. 给定一个模型:

和观测序列X=X= Shirt, Hoodie.

  1. 初始化

    • VRainy(1)=A0(Rainy)eRainy(Shirt)=0.6×0.8=0.48V_{Rainy}(1)=A_0(Rainy)e_{Rainy}(Shirt)=0.6\times 0.8=0.48
    • VCloudy(1)=A0(Cloudy)eCloudy(Shirt)=0.3×0.5=0.15V_{Cloudy}(1)=A_0(Cloudy)e_{Cloudy}(Shirt)=0.3\times 0.5=0.15
    • VSunny(1)=A0(Sunny)eSunny(Shirt)=0.1×0.01=0.001V_{Sunny}(1)=A_0(Sunny)e_{Sunny}(Shirt)=0.1\times 0.01=0.001
  2. 迭代

    这里要计算Viterbi得分和获取回溯指针.

    • Rainy:
      • VRainy(2)=eRainy(Hoodie)×max(VRainy(1)aRainy,Rainy,VCloudy(1)aCloudy,Rainy,VSunny(1)aSunny,Rainy)=0.01×max(0.48×0.6,0.15×0.4,0.001×0.1)=0.01×0.48×0.6=0.0029V_{Rainy}(2)=e_{Rainy}(Hoodie)\times max(V_{Rainy}(1)a_{Rainy, Rainy}, V_{Cloudy}(1)a_{Cloudy, Rainy}, V_{Sunny}(1)a_{Sunny, Rainy})=0.01\times max(0.48\times 0.6, 0.15\times 0.4 , 0.001\times 0.1)=0.01\times 0.48\times0.6=0.0029
      • PtrRainy(2)=argmax(0.48×0.6,0.15×0.4,0.001×0.1)=1Ptr_{Rainy}(2)=argmax(0.48\times 0.6, 0.15\times 0.4, 0.001\times 0.1)=1, 如11是Rainy
    • Cloudy:
      • VCloudy(2)=eCloudy(Hoodie)×max(VRainy(1)aRainy,Cloudy,VCloudy(1)aCloudy,Cloudy,VSunny(1)aSunny,Cloudy)=0.1×max(0.48×0.3,0.15×0.3,0.001×0.4)=0.1×0.48×0.3=0.0144V_{Cloudy}(2)=e_{Cloudy}(Hoodie)\times max(V_{Rainy}(1)a_{Rainy, Cloudy}, V_{Cloudy}(1)a_{Cloudy, Cloudy}, V_{Sunny}(1)a_{Sunny, Cloudy})=0.1\times max(0.48\times 0.3, 0.15\times 0.3 , 0.001\times 0.4)=0.1\times 0.48\times0.3=0.0144
      • PtrCloudy(2)=argmax(0.48×0.3,0.15×0.3,0.001×0.4)=1Ptr_{Cloudy}(2)=argmax(0.48\times 0.3, 0.15\times 0.3, 0.001\times 0.4)=1, 如11是Rainy
    • Sunny:
      • VSunny(2)=eSunny(Hoodie)×max(VRainy(1)aRainy,Sunny,VCloudy(1)aCloudy,Sunny,VSunny(1)aSunny,Sunny)=0.01×max(0.48×0.1,0.15×0.3,0.001×0.5)=0.79×0.48×0.1=0.0379V_{Sunny}(2)=e_{Sunny}(Hoodie)\times max(V_{Rainy}(1)a_{Rainy, Sunny}, V_{Cloudy}(1)a_{Cloudy, Sunny}, V_{Sunny}(1)a_{Sunny, Sunny})=0.01\times max(0.48\times 0.1, 0.15\times 0.3 , 0.001\times 0.5)=0.79\times 0.48\times0.1=0.0379
      • PtrSunny(2)=argmax(0.48×0.1,0.15×0.3,0.001×0.5)=1Ptr_{Sunny}(2)=argmax(0.48\times 0.1, 0.15\times 0.3, 0.001\times 0.5)=1, 如11是Rainy
  3. 终止

    时间步22的最终状态可由下列公式计算argmax(VRainy(2),VCloudy(2),VSunny(2))=argmax(0.0029,0.0144,0.0379)=3argmax(V_{Rainy}(2), V_{Cloudy}(2), V_{Sunny}(2))=argmax(0.0029, 0.0144, 0.0379)=3, 如33是Sunny. 由于PtrSunny(2)=RainyPtr_{Sunny}(2)=Rainy, 所以最有可能的状态序列为Rainy, Sunny.

学习问题

学习问题, Learning Problem. 指的是给定一个观测序列X=x1,x2,...,xmX=x_1, x_2, ..., x_m. 找出HMM模型λ=(π,A,A0)\lambda=(\bm{\pi}, \bm{A}, \bm{A_0}).

期望最大化算法

期望最大发算法, Expectation Maximization, 用于计算HMM模型. 它分为4步:

  1. 初始化

    将模型参数λ=(π,A,A0)\lambda = (\bm{\pi}, \bm{A}, \bm{A_0})随机初始化.

  2. 期望步骤

    基于当前的参数λ\lambda, 计算各隐藏状态的概率分布.

  3. 最大化步骤

    利用前一步计算的概率, 更新模型参数λ\lambda, 使得给定观测数据的似然函数最大化. 这涉及预测最可能的观测序列并与实际观测序列进行比较.

  4. 收敛判断

    如果模型参数更新后, p(Xλ)p(X|\lambda)增加, 则返回第二步继续迭代, 否则停止迭代.

Comments