目录

基本概念

HMM的定义

HMM三要素

HMM的两个基本假设

例子

HMM的3个基本问题

概率计算算法

直接计算法

前向算法

例子

后向算法

前向后向算法

学习算法

监督学习

求A

求B

求π

无监督学习

1. 确定完全数据的对数似然

2. E步:求Q函数\( Q(\lambda, \bar \lambda) \)

3. M步:求模型参数, 使极大化这个期望, 即Q函数.

鲍姆-韦尔奇算法流程

预测算法

近似算法

维特比算法

维特比算法流程

例子

示例代码

模型学习

统计初始状态矩阵π

统计观测矩阵B

统计转移矩阵A

分词预测

(1)初始化

(2)递推

(3)终止

(4)最优路径回溯


隐马尔可夫模型(hidden Markov model, HMM)

属于生成式模型: 隐藏的马尔可夫链生成观测序列. (CRF判别式)

用于标注问题

序列标注可参考:

https://zhuanlan.zhihu.com/p/54574188

序列标注

对若干时间或空间上有关联的样本进行“批量分类”的任务

对于分词任务, 已知文本\( x=\left(x_{1}, x_{2}, \ldots, x_{\tau}, \ldots, x_{T}\right) \), 其中 \( x_t \)表示第t个字符,T是文本的长度(即字符个数)

如“我是中国人。”, T=6, \( \mathrm{x}_{1}=^{\prime}\text { 我 }^{\prime}, \mathrm{x}_{2}=^{\prime} \text { 是 }^{\prime}, \mathrm{x}_{3}=^{\prime} \text { 中 }^{\prime}, \mathrm{x}_{4}=^{\prime} \text { 国 }^{\prime}, \mathrm{x}_{5}=^{\prime} \text { 人 }^{\prime}, \mathrm{x}_{6}=^{\prime} \text { 。}^{\prime} \)

(分词任务需要考虑标点符号)

用特定的符号进行标注:

字符类型符号

符号全称

符号含义

S

single

单字词语, 包括标点符号

B

begin

词语的首字

M

middle

词语的中间字符

E

end

词语的尾字

该句字符类型: y=(S,S,B,M,E,S)

对应分词结果:“我/是/中国人/。”

分词任务->序列标注(时间关联的样本批量)分类任务, 即判断每个字符是(S,B,M,E)中的哪一类.

基本概念

HMM的定义

隐藏的马尔可夫链--生成->不可观测的状态随机序列(state sequence)--生成->观测序列(observation sequence)

1个状态->1个观测, 观测值之间相互独立

HMM三要素

初始概率分布、状态转移概率分布以及观测概率分布

λ=(A, B, π)

符号定义

状态(state)的集合(值域)

$$ Q = \{q_1,q_2,...,q_N\} $$

观测(observation)的集合(定义域)

$$ V =\{v_1,v_2,...v_M\} $$

状态数

$$ N $$

观测数

$$ M $$

状态序列

$$ I = \{i_1,i_2,...,i_T\}, i_t\in Q$$

对应的观测序列

$$ O =\{o_1,o_2,...o_T\}, o_t\in V $$

序列长度

$$ T $$

状态转移矩阵A:

qi->qj的概率

(行号为原状态, 列号为新状态)

$$ A=\Big [a_{ij}\Big ]_{N \times N} , a_{ij} = P(i_{t+1} = q_j | i_t= q_i) $$

观测概率矩阵:

qi->vk的概率

(行号为状态, 列号为观测)

$$ B = \Big [b_j(k) \Big ]_{N \times M}, b_j(k) = P(o_t = v_k | i_t= q_j) $$

状态初始概率向量:

t=1时, qi的概率

$$ \pi = \Big [ \pi(i)\Big ]_N \; 其中 \;\pi(i) = P(i_1 = q_i) $$

初始状态π+转移A->状态序列I

I+观测B->观测序列

HMM的两个基本假设

1) 齐次马尔科夫链假设。即任意时刻的隐藏状态只依赖于它前一个隐藏状态

$$ P\left(i_{t} \mid i_{t-1}, o_{t-1}, \cdots, i_{1}, o_{1}\right)=P\left(i_{t} \mid i_{t-1}\right), \quad t=1,2, \cdots, T $$

2) 观测独立性假设。即任意时刻的观察状态只仅仅依赖于当前时刻的隐藏状态

$$ P\left(o_{t} \mid i_{T}, o_{T}, i_{T-1}, o_{T-1}, \cdots, i_{t+1}, o_{t+1}, i_{t}, i_{t-1}, o_{t-1}, \cdots, i_{1}, o_{1}\right)=P\left(o_{t} \mid i_{t}\right) $$

例子

已知有4个盒子

即状态集合Q:

$$ Q=\{盒子1,盒子2,盒子3,盒子4\},N=4 $$

每个盒子里都有红色和白色两种球

即观测集合V:

$$ V=\{红,白\},M=2 $$

盒子里球的数量分别是

盒子

1

2

3

4

红球数

5

3

6

8

白球数

5

7

4

2

即观测概率矩阵B:

$$  B=\left[\begin{array}{ccc} 0.5 & 0.5 \\ 0.3 & 0.7 \\ 0.6 & 0.4 \\ 0.8 & 0.2 \end{array}\right] $$

开始(第一次抽球),从4个盒子里以等概率随机选取1个盒子,从这个盒子里随机抽出1个球,记录其颜色后,放回.

即初始状态向量π:

$$ \pi=(0.25,0.25,0.25,0.25)^{\mathrm{T}} $$

每次抽球后, 从当前盒子随机转移到下一个盒子,规则是:如果当前盒子是盒子1,那么下一盒子一定是盒子2,如果当前是盒子2或3,那么分别以概率0.4和0.6转移到左边或右边的盒子,如果当前是盒子4,那么各以0.5的概率停留在盒子4或转移到盒子3.

即状态转移矩阵A:

$$ A=\left[\begin{array}{cccc} 0 & 1 & 0 & 0 \\ 0.4 & 0 & 0.6 & 0 \\ 0 & 0.4 & 0 & 0.6 \\ 0 & 0 & 0.5 & 0.5 \end{array}\right] \\ $$

重复进行5次:

即序列长度T=5.

得到球的颜色的观测序列:

$$ O=\{红,红,白,白,红\} $$

观测序列的生成过程

(和抽球类似)

输入: HMM的模型λ=(A, B, π),观测序列的长度T;

输出: 观测序列O={o1,o2,...oT}

1)按照初始状态分布π生成隐藏状态\( i_1 \)

2) 令t=1

  a. 按照状态\( i_t \)的观测概率分布\( b_{i_t}(k) \)生成观察状态\( o_t \)

  b. 按照状态\( i_t \)的状态转移概率分布\( a_{i_t i_{t+1}} \)产生隐藏状态\( i_{t+1} \)

  c. 令t++, 如果t<T, 转步a; 否则终止. 得到的ot构成O={o1,o2,...oT}.

HMM的3个基本问题

经常需要求解的3个基本问题:

(1)概率计算问题

给定模型λ=(A, B, π)和观测序列O. 计算在模型λ下观测序列O出现的概率P(O|λ)

(2)学习问题

已知观测序列O, 估计模型λ=(A, B, π)参数. 目标是最大化(问题1的概率) P(O|λ)

(极大似然估计+EM算法)

(3)预测/解码(decoding)问题

给定模型λ和观测序列O下,求最可能出现的对应的状态序列I. (即P(I|O,λ))

(维比特算法)

概率计算算法

直接计算法

时间复杂度: \( O(TN^T) \)

求所有可能的状态序列I与观测序列O联合概率P(O,I|λ),然后对所有可能状态序列求和,得到P(O|λ)

根据联合概率与边缘概率的关系

$$ P(X=a)=\sum_{b} P(X=a,Y=b) \\ \Rightarrow P(O|λ)=\sum_{I}P(O,I|λ) $$

参考:

https://blog.csdn.net/tick_tock97/article/details/79885868

要求P(O|λ)首先要求联合概率P(O,I|λ), 根据联合概率、边缘概率与条件概率之间的关系:

$$ P(X=a|Y=b)=\frac{P(X=a,Y=b)}{P(Y=b)}\\ \Rightarrow P(O,I|\lambda) = P(I|\lambda)P(O|I, \lambda) $$

分解得到的两项分别计算

已知模型, 得到状态序列的概率(初始状态π&转移A->状态序列I):

$$ P(I|\lambda) = \pi_{i_1} a_{i_1i_2} a_{i_2i_3}... a_{i_{T-1}\;\;i_T} $$

已知模型π和状态I, 得到观测序列的概率(每个状态对应的观测概率):

$$ P(O|I, \lambda) = b_{i_1}(o_1)b_{i_2}(o_2)...b_{i_T}(o_T) $$

两项分别带入, 可得联合概率P(O,I|λ):

$$ P(O,I|\lambda) = P(I|\lambda)P(O|I, \lambda) = \pi_{i_1}b_{i_1}(o_1)a_{i_1i_2}b_{i_2}(o_2)...a_{i_{T-1}\;\;i_T}b_{i_T}(o_T) $$

联合概率求和得边缘概率:

$$ P(O|\lambda) = \sum\limits_{I}P(O,I|\lambda)  \\= \sum\limits_{i_1,i_2,...i_T}\pi_{i_1}b_{i_1}(o_1)a_{i_1i_2}b_{i_2}(o_2)...a_{i_{T-1}\;\;i_T}b_{i_T}(o_T) $$

前向算法

时间复杂度: \( O(TN^2) \)

前向概率定义

给定HMM模型λ ,到时刻t时, 出现观测序列{o1,o2,…,ot}且第t个状态为qi的概率

$$ \alpha_t(i) = P(o_1,o_2,...o_t, i_t =q_i | \lambda) $$

观测序列概率P(O|λ)的前向算法(算法10.2)

输入:HMM模型λ=(A,B, π),观测序列O=(o1,o2,...oT)

输出:观测序列概率P(O|λ)

1) 初始状态(t=1)的各个隐藏状态前向概率(t=1时的观测o1已经给定):

$$ \alpha_1(i) = \pi_ib_i(o_1),\; i=1,2,...N $$

2) 递推时刻2,3,...T时刻的前向概率:

 $$ \alpha_{t+1}(i) = \Big[\sum\limits_{j=1}^N\alpha_t(j)a_{ji}\Big]b_i(o_{t+1}),\; i=1,2,...N $$

3) 最终结果(时刻t=T)

$$ P(O|\lambda) = \sum\limits_{i=1}^N\alpha_T(i) $$

即对所有状态qi的情况求和

$$ \alpha_{T}(i)=P\left(o_{1}, o_{2}, \cdots, o_{T}, i_{T}=q_{i} \mid \lambda\right)\\ \Rightarrow  \sum\limits_{i=1}^N\alpha_T(i)= \sum\limits_{i=1}^N P\left(O, i_{T}=q_{i} \mid \lambda\right) $$

前向算法减少计算量的原因

利用了状态序列的路径结构进行递推.

直接计算法:

前向算法:

讲每层交汇处的概率值存为α, 可以复用.

例子

盒子和球模型

λ=(A, B, π),

状态集合

(可以从哪些盒中抽)

Q={1,2,3},N=3

观测集合

(可以抽到哪种球)

V={红,白},M=2

状态转移矩阵

(下一个盒是该盒的概率, 如a12是从第一个盒转移到第二个盒)

$$ A = \left( \begin{array} {ccc} 0.5 & 0.2 & 0.3 \\ 0.3 & 0.5 & 0.2 \\ 0.2 & 0.3 &0.5 \end{array} \right) $$

概率分布矩阵

(从该盒抽到每种球的概率)

$$ B = \left( \begin{array} {ccc} 0.5 & 0.5 \\ 0.4 & 0.6 \\ 0.7 & 0.3 \end{array} \right) $$

初始状态向量

(第一次可能是哪个盒)

$$ \pi = (0.2,0.4,0.4)^T $$

观测序列

(最后抽的结果)

O={红,白,红}

观测序列和状态序列的长度

T=3.

前向算法计算观测序列概率P(O|λ)

按照算法10.2

输入模型λ=(A, B, π), 观测序列O={红,白,红}.

(1)初值α1:

已知第一次拿到红球(观测), 从该盒拿(状态)的概率分别为

第一次从盒1拿到红球

$$ \alpha_1(1) = \pi_1b_1(o_1) = 0.2 \times 0.5 = 0.1 $$

第一次从盒2拿到红球

$$ \alpha_1(2) = \pi_2b_2(o_1) = 0.4 \times 0.4 = 0.16 $$

第一次从盒3拿到红球

$$ \alpha_1(3) = \pi_3b_3(o_1) = 0.4 \times 0.7 = 0.28 $$

(2)递推αt:

已知第二次白球(观测),第二次从盒1拿(状态)概率为

从盒1/2/3 转到盒i*从盒i抽到白球

第二次从盒1拿到白球

$$ \alpha_2(1) =  \Big[\sum\limits_{i=1}^3\alpha_1(i)a_{i1}\Big]b_1(o_2) = [0.1*0.5+0.16*0.3+0.28*0.2 ] \times 0.5 = 0.077 $$

第二次从盒2拿到白球

$$ \alpha_2(2) =  \Big[\sum\limits_{i=1}^3\alpha_1(i)a_{i2}\Big]b_2(o_2) = [0.1*0.2+0.16*0.5+0.28*0.3 ] \times 0.6 = 0.1104 $$

第二次从盒3拿到白球

$$ \alpha_2(3) =  \Big[\sum\limits_{i=1}^3\alpha_1(i)a_{i3}\Big]b_3(o_2) = [0.1*0.3+0.16*0.2+0.28*0.5 ] \times 0.3 = 0.0606 $$

递推第三次的前向概率, 同理得:

$$ \alpha_3(1) =0.04187  \\ \alpha_3(2) =0.03551  \\ \alpha_3(3) =0.05284   $$

(3)终止

$$ P(O|\lambda) = \sum\limits_{i=1}^3\alpha_3(i) = 0.13022  $$

后向算法

后向概率定义

给定HMM模型λ ,在时刻t之后, 出现观测序列{ot+1,ot+2,…,oT}且第t个状态为qi的概率

 $$ \beta_t(i) = P(o_{t+1},o_{t+2},...o_T| i_t =q_i , \lambda)  $$

观测序列概率P(O|λ)的后向算法(算法10.3)

输入:HMM模型λ=(A,B, π),观测序列O=(o1,o2,...oT)

输出:观测序列概率P(O|λ)

1) 最初时刻(t=T)的各个隐藏状态后向概率(规定为1, 与前向概率的初始不同):

$$ \beta_T(i) = 1,\; i=1,2,...N  $$

2) 递推时刻T-1, T-2,...1时刻的后向概率:

βt=P(时刻t+1之后的观测序列为ot+1,ot+2,…,oT|在时刻t状态为qi)

$$ \beta_{t}(i) = \sum\limits_{j=1}^{N}a_{ij}b_j(o_{t+1})\beta_{t+1}(j),\; i=1,2,...N  $$

3) 最终结果(时刻t=1):

$$ P(O|\lambda) = \sum\limits_{i=1}^N\pi_ib_i(o_1)\beta_1(i)  $$

前向后向算法

(forward-backward algorithm)

一些需要用到的概率.

1)给定模型λ和观测序列O,在时刻t处于状态qi的概率

定义这个概率为符号γ:

根据联合概率、边缘概率与条件概率之间的关系

$$ \gamma_t(i) = P(i_t = q_i | O,\lambda) = \frac{P(i_t = q_i ,O|\lambda)}{P(O|\lambda)} $$

代入前向概率和后向概率的定义

前向概率:

给定HMM模型λ ,到时刻t时, 出现观测序列{o1,o2,…,ot}且第t个状态为qi的概率

$$ \alpha_t(i) = P(o_1,o_2,...o_t, i_t =q_i | \lambda) $$

后向概率:

给定HMM模型λ ,在时刻t之后, 出现观测序列{ot+1,ot+2,…,oT}且第t个状态为qi的概率

$$ \beta_t(i) = P(o_{t+1},o_{t+2},...o_T| i_t =q_i , \lambda)  $$

即分子可化为两概率相乘, 分母可根据联合概率与边缘概率关系的公式化为分子的形式:

$$ P(i_t = q_i ,O|\lambda) = \alpha_t(i)\beta_t(i)\\ \gamma_t(i) = \frac{ \alpha_t(i)\beta_t(i)}{\sum\limits_{j=1}^N \alpha_t(j)\beta_t(j)} $$

2)给定模型λ和观测序列O,在时刻t处于状态qi,且时刻t+1处于状态qj的概率

定义这个概率为符号ξ:

类似地, 根据联合概率、边缘概率与条件概率之间的关系

$$ \xi_t(i,j) = P(i_t = q_i, i_{t+1}=q_j | O,\lambda) = \frac{ P(i_t = q_i, i_{t+1}=q_j , O|\lambda)}{P(O|\lambda)} $$

分母可根据联合概率与边缘概率关系的公式, 化为与分子相同形式的累加. 因为这个分子每次固定两个时刻的状态\( i_t, i_{t+1} \) , 所以分母也要分布对两个时刻的状态q累加:

$$ \xi_t(i,j) = \frac{\alpha_t(i) a_{ij}b_j(o_{t+1}) \beta_{t+1}(j) }{\sum\limits_{r=1}^N\sum\limits_{s=1}^N \alpha_t(r)a_{rs}b_s(o_{t+1}) \beta_{t+1}(s)} $$

接下来代入前向概率与后向概率:

$$ P(i_t = q_i, i_{t+1}=q_j , O|\lambda) = \alpha_t(i)a_{ij}b_j(o_{t+1})\beta_{t+1}(j) $$

分母按这个形式每项带入求和, 得到的公式也就是观测序列概率P(O|λ)的一般计算公式.

$$ P(O|\lambda) = \sum\limits_{r=1}^N\sum\limits_{s=1}^N\alpha_t(r)a_{rs}b_s(o_{t+1})\beta_{t+1}(s) $$

代入分子分母, 即得到概率ξ:

$$ \xi_t(i,j) = \frac{\alpha_t(i)a_{ij}b_j(o_{t+1})\beta_{t+1}(j)}{\sum\limits_{r=1}^N\sum\limits_{s=1}^N\alpha_t(r)a_{rs}b_s(o_{t+1})\beta_{t+1}(s)} $$

3) 将γt(i)和ξt(i,j)在各个时刻t求和,得到几个求解HMM模型λ的参数需要使用的期望值:

在观测序列O下状态i出现的期望值

$$ \sum\limits_{t=1}^T\gamma_t(i) $$

在观测序列O下由状态i转移的期望值

(由状态i转移, 下一个状态不需要是状态I, 所以最后T时刻的γT不需要)

$$ \sum\limits_{t=1}^{T-1}\gamma_t(i) $$

在观测序列O下由状态i转移到状态j的期望值

(由状态i转移到状态j, 状态i是t时刻, 状态j是t+1时刻, 所以最后T时刻的ξT不需要)

$$ \sum\limits_{t=1}^{T-1}\xi_t(i,j) $$

学习算法

模型学习, 也就是求解模型参数. 根据状态序列的已知和未知, 分为监督学习(已知)和无监督学习(未知).

监督学习

极大似然估计法求模型参数

已知样本:

$$ \{(O_1, I_1), (O_2, I_2), ...(O_S, I_S)\} $$

其中O为观测序列, I为状态序列, 样本个数为S.

λ=(A, B, π), 分别求解A, B, π三个参数.

求A

根据频数, 估计转移概率aij

Aij为从状态qi转移到qj的频率计数. 分母为从qi转移到所有状态的频数和.

$$ A = \Big[a_{ij}\Big], \;其中a_{ij} = \frac{A_{ij}}{\sum\limits_{s=1}^{N}A_{is}} $$

求B

根据频数, 估计观测概率bj(k)

Bjk为样本隐藏状态为qj且观测状态为vk的频率计数, 分母为状态qj所有观测的频数和

$$ B= \Big[b_{j}(k)\Big], \;其中b_{j}(k) = \frac{B_{jk}}{\sum\limits_{s=1}^{M}B_{js}} $$

求π

根据频数, 估计初始状态概率πi

C(i)为所有样本中初始状态为qi的频率计数, 分母为所有状态出现在初始的频数和

$$ \pi(i) = \frac{C(i)}{\sum\limits_{s=1}^{N}C(s)} $$

无监督学习

训练数据{O1,O2,…,OS}

其中包含S个样本, 每个样本只有观测序列O(长度为T), 没有状态序列I.

目标: 学习模型参数λ=(A, B, π)

学习方法: EM算法(即Baum-Welch)估计\( \bar \lambda \)

观测序列的生成式模型

观测序列O->可观测变量,状态序列I->隐藏变量, HMM->含有隐变量的概率模型

(与直接计算法处的分解方法相同)

$$ \begin{aligned}P(O|\lambda) & & \\= \sum\limits_{I}P(O,I|\lambda) & &根据 P(X)=\sum_{Y} P(X,Y) \\ =\sum\limits_{I}P(O|I, \lambda) P(I|\lambda) & & 根据P(X|Y)=\frac{P(X,Y)}{P(Y)}\end{aligned} $$

EM算法分为3步

1. 确定完全数据的对数似然

观测序列O->可观测变量,状态序列I->隐藏变量

可观测变量O=(o1,o2,…,oT),隐藏变量I=(i1,i2,…,iT),完全数据(O,I)=(o1,o2,…,oT,i1,i2,…,iT)

完全数据的对数似然函数:

$$ \log P(O,I|\lambda) $$

2. E步:求Q函数\( Q(\lambda, \bar \lambda) \)

E步求出Q函数, 按照Q函数的定义: 完全数据的对数似然logP(O,I|λ)关于给定观测O和当前估计参数\( \bar \lambda \)下对隐变量I的条件概率\( P(I|O,\bar \lambda) \)的期望

$$ Q(\lambda, \overline{\lambda}) = \sum\limits_{I}logP(O,I|\lambda)P(I|O,\overline{\lambda}) \\ =\sum\limits_{I}logP(O,I|\lambda)\frac{P(O,I|\overline{\lambda})}{P(O|\overline{\lambda})}\\ \mathop\Longrightarrow\limits^{\frac{1}{P(O|\overline{\lambda})}对\lambda为常数,忽略}\sum\limits_{I}logP(O,I|\lambda)P(O,I|\overline{\lambda})$$

其中完全数据P(O, I | λ)可以根据估计参数计算:

$$ P(O, I \mid \lambda)=\pi_{i_{1}} b_{i_{1}}\left(o_{1}\right) a_{i_{1} i_{2}} b_{i_{2}}\left(o_{2}\right) \cdots a_{i_{T-1} i_{T}} b_{i_{T}}\left(o_{T}\right) $$

将上式代入原式log中可化连乘为累加, 整理将相同类型参数放在一起(这样做极大化的时候, 可以单独对其中一个求和项做极大化) 得:

$$ \begin{aligned} Q(\lambda, \bar{\lambda})=& \sum_{I} \log \pi_{i_{1}} P(O, I \mid \bar{\lambda})+ \sum_{I}\left( \sum_{t=1}^{T-1} \log a_{i_{t} i_{t+1}}\right) P(O, I \mid \bar{\lambda})+\\ & \sum_{I}\left(\sum_{t=1}^{T} \log b_{i_{t}}\left(o_{t}\right)\right) P(O, I \mid \bar{\lambda}) \end{aligned} $$

3. M步:求模型参数, 使极大化这个期望, 即Q函数.

目标:

$$ \overline{\lambda} = \arg\max_{\lambda}\sum\limits_{I}P(I|O,\overline{\lambda})\log P(O,I|\lambda)\\=\arg\max_{\lambda}\sum\limits_{I}\log P(O,I|\lambda)P(O,I|\overline{\lambda}) $$

因为三个参数A, B, π分别出现在其中一项, 将上一步得到的3个求和项分别极大化

1)第1项对π求该式极大

$$ \overline{\pi_i} = arg\;\max_{\pi_{i_1}} \sum\limits_{I}P(O,I|\overline{\lambda})log\pi_{i_1} \\ \mathop\Longrightarrow\limits^{i_1 =i}\arg\;\max_{\pi_{i}} \sum\limits_{i=1}^NP(O,i_1 =i|\overline{\lambda})log\pi_{i} \\ s.t. \sum\limits_{i=1}^N π_i=1$$

求有约束的极值, 用拉格朗日乘子法. 拉格朗日函数为:

$$ arg\;\max_{\pi_{i}}\sum\limits_{i=1}^NP(O,i_1 =i|\overline{\lambda})log\pi_{i} + \gamma(\sum\limits_{i=1}^N\pi_i -1) $$

其中γ为拉格朗日乘子.

上式对πi求偏导数并令结果为0

$$ \frac{\partial\sum\limits_{i=1}^NP(O,i_1 =i|\overline{\lambda})log\pi_{i} + \gamma(\sum\limits_{i=1}^N\pi_i -1)}{\partial\pi_i}=0\\ \Rightarrow P(O,i_1=i|\overline{\lambda}) + \gamma\pi_i = 0 $$

对i求和得γ:

$$ \sum_{i=1}^N (P(O,i_1=i|\overline{\lambda}) + \gamma\pi_i )= 0 \\ \Rightarrow P(O|\overline{\lambda}) + \gamma = 0 \\ \Rightarrow \gamma = -P(O|\overline{\lambda})$$

所得γ代回到求偏导结果:

$$ \begin{aligned}   \left\{\begin{array}{ll}P(O,i_1=i|\overline{\lambda}) + \gamma\pi_i = 0 \\ \gamma = -P(O|\overline{\lambda}) \end{array}\right. \end{aligned} \\ \Rightarrow \pi_i =\frac{P(O,i_1 =i|\overline{\lambda})}{P(O|\overline{\lambda})}  $$

即求得π的迭代公式

$$ \pi_i =\frac{P(O,i_1 =i|\overline{\lambda})}{P(O|\overline{\lambda})}  $$

这与前向后向算法一节得到的第一个常用概率相同

给定模型λ和观测序列O,在时刻t处于状态qi的概率

$$ \gamma_t(i) = P(i_t = q_i | O,\lambda) = \frac{P(i_t = q_i ,O|\lambda)}{P(O|\lambda)} $$

2)第2项对a求该式极大

同理, 对第2项整理, 代入所有状态情况

$$ \sum\limits_{I}P(O,I|\overline{\lambda})\sum\limits_{t=1}^{T-1}\log a_{i_t,i_{t+1}} \\ = \sum\limits_{i=1}^N\sum\limits_{j=1}^N\sum\limits_{t=1}^{T-1}P(O,i_t = i, i_{t+1} = j|\overline{\lambda})log\;a_{ij} $$

用拉格朗日乘子法求得aij的迭代表达式

$$ a_{ij} = \frac{\sum\limits_{t=1}^{T-1}P(O, i_t = i, i_{t+1} = j|\overline{\lambda})}{\sum\limits_{t=1}^{T-1}P(O, i_t = i|\overline{\lambda})} $$

所求结果代入常用概率:

$$ a_{ij} = \frac{\sum\limits_{t=1}^{T-1}\xi_t(i,j)}{\sum\limits_{t=1}^{T-1}\gamma_t(i)} $$

由状态i转移到状态j的期望值/由状态i转移的期望值

3)第3项对b求该式极大

$$ \sum\limits_{I}P(O,I|\overline{\lambda})\sum\limits_{t=1}^{T}log\;b_{i_t}(o_t) = \sum\limits_{j=1}^N\sum\limits_{t=1}^{T}P(O,i_t = j|\overline{\lambda})log\;b_{j}(o_t) $$

同理用拉格朗日乘子法求得bj(k)的迭代表达式

$$ b_{j}(k) = \frac{\sum\limits_{t=1}^{T}P(O,i_t = j|\overline{\lambda})I(o_t=v_k)}{\sum\limits_{t=1}^{T}P(O,i_t = j|\overline{\lambda})} \\ I(o_t=v_k)=\left\{\begin{array}{ll}1, if \ o_t=v_k \\ 0, if \ o_t\neq v_k \end{array}\right. $$

指示函数保证观测不为v_k时, 偏导数为0.

代入常用概率

$$ b_{j}(k) = \frac{\sum\limits_{t=1, o_t=v_k}^{T}\gamma_t(j)}{\sum\limits_{t=1}^{T}\gamma_t(j)} $$

观测为vk时状态j出现的期望值/状态j出现的期望值

鲍姆-韦尔奇算法流程

输入:观测序列\( O=\left(o_{1}, o_{2}, \cdots, o_{T}\right)\)

输出:HMM模型参数

1) 初始化. 设迭代次数n=0时的初始模型参数\(a_{i j}^{(0)}, b_{j}(k)^{(0)}, \pi_{i}^{(0)}\)

2) 利用迭代公式递推. 对\( n=1,2, \cdots \)

更新模型参数:

$$ \begin{aligned} a_{i j}^{(n+1)}=\frac{\sum_{t=1}^{T-1} \xi_{t}(i, j)}{\sum_{t=1}^{T-1} \gamma_{t}(i)}\\ {b_{j}(k)^{(n+1)}=\frac{\sum_{t=1, o_{t}=v_{k}}^T \gamma_{t}(j)}{\sum_{t=1}^{T} \gamma_{t}(j)}} \\ {\pi_{i}^{(n+1)}=\gamma_{1}(i)} \end{aligned} $$

3) 当参数值收敛,终止, 得到模型参数\( \lambda^{(n+1)}=\left(A^{(n+1)}, B^{(n+1)}, \pi^{(n+1)}\right) \)

预测算法

给定模型λ和观测O={o1,o2,...oT},求状态I∗使P(I∗|O)最大化

近似算法, 维特比(Viterbi)算法

近似算法

每个时刻t都选择最可能的隐藏状态i∗t作为预测结果.

缺点: 不能保证整体是最可能的状态序列,因为预测的状态序列中, 某些相邻的隐藏状态可能存在转移概率为0.

即求状态i*:

$$ i_t^* = arg \max_{1 \leq i \leq N}[\gamma_t(i)], \; t =1,2,...T $$

其中γ为第一个常用概率: 在给定模型λ和观测序列O时,在时刻t处于状态qi的概率是γt(i)

$$ \gamma_t(i) = P(i_t = q_i | O,\lambda) = \frac{P(i_t = q_i ,O|\lambda)}{P(O|\lambda)} $$

维特比算法

用动态规划(dynamic programming)求概率最大路径(最优路径). 路径对应状态序列.

近似算法类似最优路径的贪心,维特比类似动态规划.

贪心很好理解, 就是每一步都求下一步的最优, 而动态规划有一个回溯的过程.

动态规划

参考: https://zhuanlan.zhihu.com/p/111134524

动态规划适用可以分解的问题: 大规模问题的答案可以由小规模问题的答案递推得到

多段图的最短路径问题是求从源点到终点的最小代价路径

多段图将顶点划分为k个互不相交的子集(k段). 10 个顶点的多段图:

算法流程参考:

https://zhuanlan.zhihu.com/p/163010698

1.建立状态转移方程. 当做已经知道​f(1)~f(n-1)求f(n)

2.缓存并复用以往结果 求f(n)时需要复用f(n-1)结果

3.按顺序从小往大递推f(1)…f(n)

需要求解的路线是由 A 到 G,这就意味着 A 要先到 B,再到 C,再到 D,再到 E,再到 F。每一轮都需要做不同的决策,而每次的决策又依赖上一轮决策的结果

例如,做 D2 -> E 的决策时,D2 -> E2 的距离为 1,最短。但这轮的决策,基于的假设是从 D2 出发,这就意味着前面一轮的决策结果是 D2

其中, 第一轮决策的状态是 S1,可选的值是 A,第二轮决策的状态是 S2,可选的值就是 B1 和 B2

步骤:

1.分阶段:从 A 到 G,可以拆分为 A -> B、B -> C、C -> D、D -> E、E -> F、F -> G,6 个阶段。

2.找状态:第一轮的状态 S1 = A,第二轮 S2 = {B1,B2},第三轮 S3 = {C1,C2,C3,C4},第四轮 S4 = {D1,D2,D3},第五轮 S5 = {E1,E2,E3},第六轮 S6 = {F1,F2},第七轮 S7 = {G}。

3.做决策:决策变量就是上面图中的每条边。以第四轮决策 D -> E 为例来看,可以得到 u4(D1),u4(D2),u4(D3)。其中 u4(D1) 的可能结果是 E1 和 E2。

4.写出状态转移方程: \( s_{k+1}=u_{k}\left(s_{k}\right) \)

5.定目标:目标是总距离最短。定义 dk(sk,uk) 是在第k段的状态为 sk 时,选择 uk 动作的距离,如 d5(E1,F1) = 3. 此处总段数 n = 7,则有如下为最终要优化的目标:

$$ \mathrm{v}_{\mathrm{k}, 7}\left(\mathrm{~s}_{1}=\mathrm{A}, \mathrm{s}_{7}=\mathrm{G}\right)=\sum_{\mathrm{k}=1}^{7} \mathrm{~d}_{\mathrm{k}}\left(\mathrm{s}_{\mathrm{k}}, \mathrm{u}_{\mathrm{k}}\right) $$

6.寻找终止条件:起止条件分别是,s1 = A 和 s7 = G

7.求子问题最优解:

原问题的最优解所包括的子问题的解也是最优的=>

如果 A -> ... -> F1 -> G 是全局 A 到 G 最优的路径,那么此处 A -> ... -> F1 也是 A 到 F1 的最优路径, 即是 A 到 F1 到 G 的路径和 A 到 F2 到 G 的路径中更短的那个.

核心代码

输入m x m二维数组表示距离

public static int process(int[][] matrix, int i) {#第一次传入的i为终点编号

        // 到达A退出递归

        if (i == 0) {

            return 0;

        }

        // 状态转移

        else{

            int distance = 999;

            for(int j=0; j<i; j++){#对结点编号时就规定了, 后一段结点的编号一定大于前一段的编号

                if(matrix[j][i]!=0){

                    int d_tmp = matrix[j][i] + process(matrix, j);

                    if (d_tmp < distance){#选择当前段距离总和最小的

                        distance = d_tmp;

                    }

                }

            }

            return distance;

        }

维特比原理

1.求各条部分路径概率与终结点

从时刻t=1开始,递推地计算在时刻t状态为i的各条部分路径的最大概率,直至得到时刻t=T状态为i的各条路径的最大概率。时刻t=T的最大概率即为最优路径的概率P*,最优路径的终结点\( i^*_T \)也同时得到

2.求路径(与普通动态规划求最优路径步骤同)

为了找出最优路径的各个结点,从终结点\( i^*_T \)开始,由后向前逐步求得结点\( i_{T-1}^{*}, \cdots, i_{1}^{*} \)得到最优路径\( I^{*}=\left(i_{1}^{*}, i_{2}^{*}, \cdots, i_{T}^{*}\right) \)

定义变量

给定时刻t状态为i,

从时刻1到时刻t-1的状态不确定,

存在多条可能路径\( (i_{1}, i_{2}, \cdots, i_{T}) \)

其中概率最大的一条路径的概率为δ_t(i)

$$ \delta_t(i) = \max_{i_1,i_2,...i_{t-1}}\;P(i_t=i, i_{t-1}...i_1,o_t,...o_1|\lambda),\; i =1,2,...N $$

δ的递推公式

由已知t时刻最优的j转移到t+1时刻的i,

并观测到\( o_{t+1}\)

$$ \delta_{t+1}(i)  =  \max_{i_1,i_2,...i_{t}}\;P(i_{t+1}=i, i_{t},...,i_1,o_{t+1},...o_1|\lambda) \\  = \max_{1 \leq j \leq N}\;[\delta_t(j)a_{ji}]b_i(o_{t+1})\\ i =1,2,...N ;T=1,...,T-1 $$

给定时刻t状态为i,

比较所有路径\( (i_{1}, i_{2}, \cdots, i_{T}) \)

其中概率最大的一条路径的第t-1个结点

$$ \Psi_t(i) = arg \; \max_{1 \leq j \leq N}\;[\delta_{t-1}(j)a_{ji}];\\i =1,2,...N $$

维特比算法流程

算法10.5(维特比算法)

输入:模型λ=(A, B, π)和观测序列\( O=\left(o_{1}, o_{2}, \cdots, o_{T}\right)\)

输出:最优路径(最有可能的隐藏序列) \( I^*= \{i_1^*,i_2^*,...i_T^*\} \)

(1)初始化

t=1时, 路径(只有一个初始点)的概率即为初始状态概率πi*观测bi; t-1个结点不存在令其为0

$$ \delta_1(i) = \pi_ib_i(o_1),\;i=1,2...N \\ \Psi_1(i)=0,\;i=1,2...N $$

(2)递推

对t=2,3,…,T分别求到达各个状态结点的最优路径概率

δ已知t-1时间各结点最优路径概率, 再转移, 观测, 即可递推得到该时间结点的概率.

Ψ已知t-1时间各结点最优路径概率, 转移到i结点, 哪个概率最大, 就选哪个作为t-1的最优结点.

$$ \delta_{t}(i) = \max_{1 \leq j \leq N}\;[\delta_{t-1}(j)a_{ji}]b_i(0_{t}),\;i=1,2...N\\ \Psi_t(i) = arg \; \max_{1 \leq j \leq N}\;[\delta_{t-1}(j)a_{ji}],\;i=1,2...N $$

(3)终止

计算时刻T最大的δT(i),即为最可能隐藏状态序列出现的概率

计算时刻T最大δT(i)所用的i,即为时刻T最可能的隐藏状态

$$ P^* = \max_{1 \leq i \leq N}\delta_{T}(i)\\i_T^* = arg \; \max_{1 \leq i \leq N}\;[\delta_{T}(i)] $$

(4)最优路径回溯。

对t=T-1,T-2,…,1

$$ i_t^* = \Psi_{t+1}(i_{t+1}^*) $$

得最优路径:

$$ I^*= \{i_1^*,i_2^*,...i_T^*\} $$

例子

已知条件与前向算法中的例子相同:

盒子和球模型

λ=(A, B, π),

状态集合

(可以从哪些盒中抽)

Q={1,2,3},N=3

观测集合

(可以抽到哪种球)

V={红,白},M=2

状态转移矩阵

(下一个盒是该盒的概率, 如a12是从第一个盒转移到第二个盒)

$$ A = \left( \begin{array} {ccc} 0.5 & 0.2 & 0.3 \\ 0.3 & 0.5 & 0.2 \\ 0.2 & 0.3 &0.5 \end{array} \right) $$

概率分布矩阵

(从该盒抽到每种球的概率)

$$ B = \left( \begin{array} {ccc} 0.5 & 0.5 \\ 0.4 & 0.6 \\ 0.7 & 0.3 \end{array} \right) $$

初始状态向量

(第一次可能是哪个盒)

$$ \pi = (0.2,0.4,0.4)^T $$

观测序列

(最后抽的结果)

O={红,白,红}

观测序列和状态序列的长度

T=3.

维特比算法求最优状态序列(最优路径) \(  I^*= \{i_1^*,i_2^*,...i_T^*\}  \)

按照算法10.5(维特比算法)

输入:模型λ=(A, B, π)和观测序列O={红,白,红}.

(1)初始化t=1

①t=1时, 已知第一次拿到红球(观测) \(  o_1=红  \), 状态路径的概率(只有一个初始点状态i, 从i盒拿) 分别为:

$$ \delta_{1}(i)=\pi_{i} b_{i}\left(o_{1}\right)=\pi_{i} b_{i}(\text { 红 }), \quad i=1,2,3 $$

第一次从盒1拿到红球

$$ \delta_1(1) = \pi_1b_1(o_1) = 0.2 \times 0.5 = 0.1 $$

第一次从盒2拿到红球

$$ \delta_1(2) = \pi_2b_2(o_1) = 0.4 \times 0.4 = 0.16 $$

第一次从盒3拿到红球

$$ \delta_1(3) = \pi_3b_3(o_1) = 0.4 \times 0.7 = 0.28 $$

即为初始状态概率πi*观测bi

②t=1时, t-1个结点不存在令其为0:

$$ \Psi_1(1)=\Psi_1(2) =\Psi_1(3) =0 $$

 (2)递推各个状态结点的最优路径概率, 最优结点

t=2时, 已知第二次拿到白球

$$ \delta_{2}(i)=\max _{1 \leqslant j \leqslant 3}\left[\delta_{1}(j) a_{j i}\right] b_{i}\left(o_{2}\right) \\ \Psi_{2}(i)=\arg \max _{1 \leqslant j \leqslant 3}\left[\delta_{1}(j) a_{j i}\right],  \quad i=1,2,3 $$

状态i=盒1的最优路径概率, 最优结点

第二次从盒1拿到白球

第一次为盒1, 转移到盒1

1->1

$$ \delta_1(1)a_{11}b_1(白)\\= 0.1 \times 0.5 \times 0.5 =0.05 \times 0.5$$

第一次为盒2, 转移到盒1

2->1

$$ \delta_1(2)a_{21}b_1(白)\\= 0.16 \times 0.3 \times 0.5 =0.048 \times 0.5$$

第一次为盒3, 转移到盒1

3->1为概率最大路径, 路径最大概率为

$$  \delta_2(1) =\delta_1(3)a_{31}b_1(白)=0.028   $$

盒3为t=2时盒1的最优上一结点

$$  \Psi_2(1)=3   $$

$$ \delta_1(3)a_{31}b_1(白)\\= 0.28\times 0.2 \times 0.5 =0.056 \times 0.5\\(0.056为最大值\times 0.5)=0.028$$

同理可得, 状态i=盒2的最优路径概率, 最优结点

第二次从盒2拿到白球

第一次为盒1, 转移到盒2

1->2

$$ \delta_2(2) = \max_{1\leq j \leq 3}[\delta_1(j)a_{j2}]b_2(o_2)\\ = \max_{1\leq j \leq 3}[0.1 \times 0.2, 0.16 \times 0.5, 0.28\times 0.3] \times 0.6\\=0.28\times 0.3 \times 0.6 = 0.0504  $$

第一次为盒2, 转移到盒2

2->2

第一次为盒3, 转移到盒2

3->2为概率最大路径, 路径最大概率为

$$  \delta_2(2) =\delta_1(3)a_{32}b_2(白)=0.0504 $$

盒3为t=2时盒1的最优上一结点

$$  \Psi_2(2)=3   $$

状态i=盒3的最优路径概率, 最优结点

第二次从盒3拿到白球

第一次为盒1, 转移到盒3

$$ \delta_2(3) = \max_{1\leq j \leq 3}[\delta_1(j)a_{j3}]b_3(o_2) = \max_{1\leq j \leq 3}[0.1 \times 0.3, 0.16 \times 0.2, 0.28\times 0.5] \times 0.3 = 0.042 $$

第一次为盒2, 转移到盒3

第一次为盒3, 转移到盒3

3->3为概率最大路径, 路径最大概率为

$$ \delta_2(3) =\delta_1(3)a_{33}b_3(白)=0.042 $$

盒3为t=2时盒1的最优上一结点

$$  \Psi_2(3)=3   $$

t=3时, 已知第三次拿到红球. 同理可得状态i=盒1, 2, 3的最优路径概率, 最优结点

第三次从盒1拿到红球

$$ \delta_3(1) = \max_{1\leq j \leq 3}[\delta_2(j)a_{j1}]b_1(o_3) \\ = \max_{1\leq j \leq 3}[0.028 \times 0.5, 0.0504 \times 0.3, 0.042\times 0.2] \times 0.5 = 0.00756\\ \Psi_3(1)=2 $$

第三次从盒2拿到红球

$$ \delta_3(2) = \max_{1\leq j \leq 3}[\delta_2(j)a_{j2}]b_2(o_3) \\ = \max_{1\leq j \leq 3}[0.028  \times 0.2, 0.0504\times 0.5, 0.042\times 0.3] \times 0.4 = 0.01008\\ \Psi_3(2)=2 $$

第三次从盒3拿到红球

$$ \delta_3(3) = \max_{1\leq j \leq 3}[\delta_2(j)a_{j3}]b_3(o_3) \\= \max_{1\leq j \leq 3}[0.028  \times 0.3, 0.0504 \times 0.2, 0.042\times 0.5] \times 0.7 = 0.0147\\ \Psi_3(3)=3 $$

(3)终止

取时刻3最大的δT(i),即为最优路径(最可能隐藏状态序列出现)的概率P*:

$$  P^* = \max_{1 \leq i \leq 3}\delta_{3}(i)=\delta_3(3)=0.0147 $$

取时刻3最大δT(i)所用的i,即为最优路径的终点(时刻T最可能的隐藏状态)

$$   i_3^* = arg \; \max_{1 \leq i \leq 3}\;[\delta_{3}(3)]=3  $$

(4)最优路径回溯

已知最优路径的终点 \(  i_{3}^{*} \)

对t=2,1, 根据最优上一结点\(  i_{2}^{*}, i_{1}^{*} \)进行回溯

$$ i_t^* = \Psi_{t+1}(i_{t+1}^*) \\t=2, \quad i_{2}^{*}=\Psi_{3}\left(i_{3}^{*}\right)=\Psi_{3}(3)=3 \\t=1, \quad i_{1}^{*}=\Psi_{2}\left(i_{2}^{*}\right)=\Psi_{2}(3)=3 $$

得最优路径:

$$ I^*= \{i_1^*,i_2^*,i_3^*\}= \{3,3,3\} $$

示例代码

代码参考:

https://github.com/Dod-o/Statistical-Learning-Method_Code

维特比为NLP中的经典算法, 此处给出的也是一个分词代码.

隐状态:

隐状态标记

含义

数组中对应的位置

B

词语的开头

0

M

一个词语的中间词

1

E

一个词语的结果

2

S

非词语,单个词

3

B->M->E->S

模型学习

模型λ=(A, B, π)学习, 也就是求解模型参数A, B, π, :

#依据现有训练集统计PI、A、B

    PI, A, B = trainParameter('HMMTrainSet.txt')

经过查看训练集数据, 此处已经做了分词, 隐状态也可通过判断字在词中的位置进行标注, 为有监督学习.

生成统计时主要借助以下思路:

1.句中n个词语,隔开后变成一个长度为n的列表,每个元素为一个词语

#对单行句子按空格进行切割

curLine = line.strip().split()

2.对每个词语长度进行判断:

如果为1认为该词语是S,即单个字

label = 'S'

如果为2则第一个是B,表开头,第二个为E,表结束

如果大于2,则第一个为B,最后一个为E,中间全部标为M,表中间词

#如果长度不为1,开头为B,最后为E,中间添加长度-2个M

#如果长度刚好为2,长度-2=0也就不添加了,反之添加对应个数的M

label = 'B' + 'M' * (len(curLine[i]) - 2) + 'E'

#在整行的词性标记状态链后添加该单词的状态链

wordLabel.extend(label)

3. 统计初始状态矩阵π:该句第一个字的词性对应的PI中位置加1

初始化PI = [0, 0, 0, 0],当本行第一个字是B('词语的开头')时,PI中B对应位置为0,

则PI = [1, 0, 0, 0],全部统计结束后,按照计数值再除以总数得到概率

统计转移矩阵A:对状态链中位置t和t-1的状态进行统计,在矩阵中相应位置加1,全部结束后生成概率

统计观测矩阵B:对于每个字的状态到字的发射计数,全部结束后生成概率

此处概率计算比频率多了取log过程, 对学习过程代码进行修改, 按照监督学习的公式, 取频率(不取对数)

得到分词结果

深圳|有个|打|工者|阅览|室

去年|1|2月|,|我在|广东|深圳|市出|差|,听|说南|山区|工商|分局|为打|工者|建了|个|免费|图书|阅览|室|,|这件|新鲜|事引|起了|我的|兴趣|。      

本|报|记者|罗|华

对比原代码分词结果:

-------------------分词后----------------------

深圳|有个|打|工者|阅览室

去年|12月|,|我|在|广东|深圳|市出|差|,|听|说|南|山区|工商|分局|为|打|工者|建了|个|免费|图书|阅览室|,|这件|新|鲜事|引起|了|我|的|兴趣|。

(|本报|记者|罗华|)

看起来还是加log的效果好一些

这是两个实际代码计算中的问题

1.某元素没有出现过,该位置为0,在后续的计算中这是不被允许的

比如说某个汉字在训练集中没有出现过,那在后续不同概率相乘中只要有一项为0,其他都是0了

2. 整条链很长的情况下,太多0-1的概率相乘, 不管怎样最后的结果都会很小,很容易下溢出, 所以在概率上我们习惯将其转换为log对数形式

x大的时候,log也大,x小的时候,log也相应小,(虽然是负值), 我们最后比较的是不同概率的大小,所以使用log没有问题

这在书上是没有讲的

统计初始状态矩阵π

根据频数, 估计初始状态概率πi

C(i)为所有样本中初始状态为qi的频率计数(此处再用log防止连乘下溢), 分母为所有状态出现在初始的频数和

$$ \log \pi(i) = \log \frac{C(i)}{\sum\limits_{s=1}^{N}C(s)} $$

#初始状态矩阵PI只需要计算单行开头第一个字,PI中对应位置加1,

if i == 0: PI[statuDict[label[0]]] += 1

#对PI求和,概率生成中的分母

sum = np.sum(PI)

#如果该项为0,则手动赋予一个极小值

if PI[i] == 0:  PI[i] = -3.14e+100

如果不为0,则计算概率,再对概率求log

PI[i] = np.log(PI[i] / sum)

其中代码只取了核心计算部分, 循环条件等省略

统计观测矩阵B

根据频数, 估计观测概率bj(k)

Bjk为样本隐藏状态为qj且观测状态为vk的频率计数(此处再用log防止连乘下溢), 分母为状态qj所有观测的频数和

$$ \log B= \Big[\log b_{j}(k)\Big], \;其中\log b_{j}(k) = \log \frac{B_{jk}}{\sum\limits_{s=1}^{M}B_{js}} $$

    #遍历状态链中每一个状态,并找到对应的中文汉字编码,在B中对应位置加1

    B[statuDict[label[j]]][ord(curLine[i][j])] += 1# 使用ord(汉字)即可找到其对应编码

sum = np.sum(B[i])

if B[i][j] == 0: B[i][j] = -3.14e+100

else:B[i][j] = np.log(B[i][j] / sum)

统计转移矩阵A

根据频数, 估计转移概率aij

对状态链中位置t和t-1的状态进行统计,在矩阵中相应位置加1,全部结束后生成概率

Aij为从状态qi转移到qj的频率计数(此处再用log防止连乘下溢). 分母为从qi转移到所有状态的频数和.

$$ \log A = \Big[\log a_{ij}\Big], \;其中\log a_{ij} = \log \frac{A_{ij}}{\sum\limits_{s=1}^{N}A_{is}} $$

#统计t-1时刻状态->t时刻状态的所有状态组合的出现次数

A[statuDict[wordLabel[i - 1]]][statuDict[wordLabel[i]]] += 1

sum = np.sum(A[i])

if A[i][j] == 0: A[i][j] = -3.14e+100

else: A[i][j] = np.log(A[i][j] / sum)

分词预测

给定模型λ和观测O={o1,o2,...oT},求状态I∗使P(I∗|O)最大化

算法依据“10.4.2 维特比算法”

#新建嵌套列表δ,δ存放四种状态的概率值,因为状态链中每个状态都有

#一个元素内部有四种概率值,长度(元素个数)是该行的长度(文字个数)

delta = [[0 for i in range(4)] for i in range(len(line))]

如句子'深圳有个打工者阅览室'

嵌套列表δ形状为

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

(1)初始化

t=1时, 路径(只有一个初始点)的概率即为初始状态概率πi*观测bi; t-1个结点不存在令其为0

$$ \log \delta_1(i) = \log \pi_i+\log b_i(o_1),\;i=1,2...N \\ \Psi_1(i)=0,\;i=1,2...N $$

(原先是概率直接相乘,取完log以后,概率的乘法转换为加法了)

    #初始化δ状态链中第一个状态的四种状态概率

    delta[0][i] = PI[i] + B[i][ord(line[0])]

#初始化ψ,初始时为0

psi = [[0 for i in range(4)] for i in range(len(line))]

(2)递推

对t=2,3,…,T分别求到达各个状态结点的最优路径概率

δ已知t-1时间各结点最优路径概率, 再转移, 观测, 即可递推得到该时间结点的概率.

Ψ已知t-1时间各结点最优路径概率, 转移到i结点, 哪个概率最大, 就选哪个作为t-1的最优结点.

$$ \log \delta_{t}(i) = \max_{1 \leq j \leq N}\;[\log \delta_{t-1}(j)+\log a_{ji}]+\log b_i(0_{t}),\;i=1,2...N $$

先计算δ, 书中的乘法在这里变成了加法,这是由于原先是概率直接相乘,但我们在求得概率时,同时取了log,取完log以后,概率的乘法转换为加法了,同时也简化了运算

#初始化一个临时列表,用于存放四种概率

tmpDelta = [0] * 4

tmpDelta[j] = delta[t - 1][j] + A[j][i]

#找到最大的那个δ_{t-1} * a,

maxDelta = max(tmpDelta)

#记录最大值对应的状态

maxDeltaIndex = tmpDelta.index(maxDelta)

#将找到的最大值乘以b放入,

#注意:这里同样因为log变成了加法

delta[t][i] = maxDelta + B[i][ord(line[t])]

再记录Ψ

$$  \Psi_t(i) = arg \; \max_{1 \leq j \leq N}\;[\log \delta_{t-1}(j)+\log a_{ji}],\;i=1,2...N $$

#在ψ中记录对应的最大状态索引

psi[t][i] = maxDeltaIndex

(3)终止

计算时刻T最大的δT(i),即为最可能隐藏状态序列出现的概率

计算时刻T最大δT(i)所用的i,即为时刻T最可能的隐藏状态

$$ P^* = \max_{1 \leq i \leq N}\delta_{T}(i)\\ i_T^* = arg \; \max_{1 \leq i \leq N}\;[\delta_{T}(i)] $$

#获取最后一个状态的最大状态概率对应的索引

i_opt = delta[len(line) - 1].index(max(delta[len(line) - 1]))

#建立一个状态链列表,开始生成状态链

sequence = []

#在状态链中添加索引

#注:状态链0、1、2、3,对应B、M、E、S

sequence.append(i_opt)

(4)最优路径回溯。

对t=T-1,T-2,…,1

$$ i_t^* = \Psi_{t+1}(i_{t+1}^*) $$

    #不断地从当前时刻t的ψ列表中读取到t-1的最优状态

    i_opt = psi[t][i_opt]

    #将状态放入列表中

    sequence.append(i_opt)

#因为是从后往前将状态放入的列表,所以这里需要翻转一下,变成了从前往后

sequence.reverse()

分词任务

#如果该字是3:S->单个词  或  2:E->结尾词 ,并且没到一句话结尾. 则在该字后面加上分隔符 |

if (sequence[i] == 3 or sequence[i] == 2) and i != (len(line) - 1):

    curLine += '|'

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐