机器学习算法-条件随机场

条件随机场

条件随机场(Conditional Random Field,简称CRF)是一种判别式无向图模型,生成式模型是直接对联合分布进行建模,而判别式模型则是对条件分布进行建模,条件随机场则是判别式模型。

马尔可夫过程

定义

假设一个随机过程中,

t_n时刻的状态
x_n的条件发布,只与其前一状态
x_{n-1} 相关,即:

P(x_n|x_1,x_2,...,x_{n-1}) = P(x_n|x_{n-1})

则将其称为 马尔可夫过程。

v2-0bd96a72d51227da056669f1bc5c2c3b_b.png

隐马尔科夫算法

隐马尔可夫模型(Hidden Markov Model,HMM)是结构最简单的动态贝叶斯网(Dynamic Bayesian Betwork),这是一种著名的有向图模型,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中确定该过程的隐含参数。然后利用这些参数来作进一步的分析,例如模式识别。在正常的马尔可夫模型中,状态对于观察者来说是直接可见的。这样状态的转换概率便是全部的参数。而在马尔可夫模型中,状态并不是直接可见的,但受状态影响的某些变量则是可见的。每一个状态在可能输出的符号上都有一概率分布。因此输出符号的序列能够透露出状态序列的一些信息。

HMM有三个典型(canonical)问题:

  • 预测(filter):已知模型参数和某一特定输出序列,求最后时刻各个隐含状态的概率分布,通常使用前向算法解决.。
  • 平滑(smoothing):已知模型参数和某一特定输出序列,求中间时刻各个隐含状态的概率分布, 通常使用forward-backward 算法解决。
  • 解码(most likely explanation): 已知模型参数,寻找最可能的能产生某一特定输出序列的隐含状态的序列,通常使用Viterbi算法解决。

定义

隐马尔科夫算法是对含有未知参数(隐状态)的马尔可夫链进行建模的生成模型,如下图所示:

v2-25f80358a01e747d1e9e1726eb0b0836_b.jpg

在隐马尔科夫模型中,包含隐状态 和 观察状态,隐状态

x_i对于观察者而言是不可见的,而观察状态
y_i对于观察者而言是可见的。隐状态间存在转移概率,隐状态
x_i到对应的观察状态
y_i间存在输出概率。

假设

1.假设隐状态

x_i的状态满足马尔可夫过程,i时刻的状态
x_i的条件分布,仅与其前一个状态
x_{i-1}相关,即:

P(x_i|x_1,x_2,...,x_{i-1}) = P(x_i|x_{i-1})

2.假设观测序列中各个状态仅取决于它所对应的隐状态,即:

P(y_i|x_1,x_2,...,x_{i-1},y_1,y_2,...,y_{i-1},y_{i+1},...) = P(y_i|x_{i})

存在问题

在序列标注问题中,隐状态(标注)不仅和单个观测状态相关,还和观察序列的长度、上下文等信息相关。例如词性标注问题中,一个词被标注为动词还是名词,不仅与它本身以及它前一个词的标注有关,还依赖于上下文中的其他词。

条件随机场 (以线性链条件随机场为例)

定义

给定

X=(x_1,x_2,...,x_n)
Y=(y_1,y_2,...,y_n)均为线性链表示的随机变量序列,若在给随机变量序列X的条件下,随机变量序列Y的条件概率分布
P(Y|X)构成条件随机场,即满足马尔可夫性:

P(y_i|x_1,x_2,...,x_{i-1},y_1,y_2,...,y_{i-1},y_{i+1})=P(y_i|x,y_{i-1},y_{i+1})

则称为

P(Y|X)为线性链条件随机场。

通过去除了隐马尔科夫算法中的观测状态相互独立假设,使算法在计算当前隐状态$x_i$时,会考虑整个观测序列,从而获得更高的表达能力,并进行全局归一化解决标注偏置问题。

v2-cf7ede75004fe56b9b6dbedf81bdb6cf_b.jpg

参数化形式

p\left(y | x\right)=\frac{1}{Z\left(x\right)} \prod_{i=1}^{n} \exp \left(\sum_{i, k} \lambda_{k} t_{k}\left(y_{i-1}, y_{i}, x, i\right)+\sum_{i, l} \mu_{l} s_{l}\left(y_{i}, x, i\right)\right)

其中:

Z(x)为归一化因子,是在全局范围进行归一化,枚举了整个隐状态序列
x_{1…n}的全部可能,从而解决了局部归一化带来的标注偏置问题。

Z(x)=\sum_{y} \exp \left(\sum_{i, k} \lambda_{x} t_{k}\left(y_{i-1}, y_{i}, x, i\right)+\sum_{i, l} \mu_{l} s_{l}\left(y_{i}, x, i\right)\right)
t_k为定义在边上的特征函数,转移特征,依赖于前一个和当前位置

s_1为定义在节点上的特征函数,状态特征,依赖于当前位置。

简化形式

因为条件随机场中同一特征在各个位置都有定义,所以可以对同一个特征在各个位置求和,将局部特征函数转化为一个全局特征函数,这样就可以将条件随机场写成权值向量和特征向量的内积形式,即条件随机场的简化形式。

step 1

将转移特征和状态特征及其权值用统一的符号表示,设有k1个转移特征,

k_2个状态特征,
K=k_1+k_2,记

f_{k}\left(y_{t-1}, y_{i}, x, i\right)=\left\{\begin{array}{ll} t_{k}\left(y_{i-1}, y_{i}, x, i\right), & k=1,2, \cdots, K_{1} \\ s_{i}\left(y_{i}, x, i\right), & k=K_{1}+l ; l=1,2, \cdots, K_{2} \end{array}\right.

step 2

对转移与状态特征在各个位置i求和,记作

f_{k}(y, x)=\sum_{i=1}^{n} f_{k}\left(y_{i-1}, y_{i}, x, i\right), \quad k=1,2, \cdots, K

step 3

\lambda_{x}
\mu_{l}用统一的权重表示,记作

w_{k}=\left\{\begin{array}{ll} \lambda_{k}, & k=1,2, \cdots, K_{1} \\ \mu_{l}, & k=K_{1}+l ; l=1,2, \cdots, K_{2} \end{array}\right.

step 4

转化后的条件随机场可表示为:

\begin{aligned} P(y | x) &=\frac{1}{Z(x)} \exp \sum_{k=1}^{K} w_{k} f_{k}(y, x) \\ Z(x) &=\sum_{y} \exp \sum_{k=1}^{K} w_{k} f_{k}(y, x) \end{aligned}

step 5

w表示权重向量:

w = (w_1,w_2,...,w_K)^T

F(y,x)表示特征向量,即

F(y, x)=\left(f_{1}(y, x), f_{2}(y, x), \cdots, f_{K}(y, x)\right)^{\mathrm{T}}

则,条件随机场写成内积形式为:

\begin{array}{c} P_{x}(y | x)=\frac{\exp (w \cdot F(y, x))}{Z_{x}(x)} \\ Z_{x}(x)=\sum_{y} \exp (w \cdot F(y, x)) \end{array}

矩阵形式

推导 begin
推导 end

基本问题

条件随机场包含概率计算问题、学习问题和预测问题三个问题。

1. 概率计算问题:已知模型的所有参数,计算观测序列
Y出现的概率,常用方法:前向和后向算法;


2. 学习问题:已知观测序列
Y,求解使得该观测序列概率最大的模型参数,包括隐状态序列、隐状态间的转移概率分布和从隐状态到观测状态的概率分布,常用方法:Baum-Wehch 算法;


3. 预测问题:一直模型所有参数和观测序列
Y,计算最可能的隐状态序列
X,常用算法:维特比算法。

概率计算问题

给定条件随机场
P(Y|X),输入序列
x和输出序列
y;

计算条件概率

P(Y_i=y_i|x), P(Y_{i-1} = y_{i-1},Y_i = y_i|x)
计算相应的数学期望问题;

前向-后向算法

step 1 前向计算

对观测序列

x的每个位置
i=1,2,...,n+1,定义一个
m阶矩阵(
m为标记
Y_i取值的个数)

\begin{array}{c} M_{i}(x)=\left[M_{i}\left(y_{i-1}, y_{i} | x\right)\right] \\ M_{i}\left(y_{i-1}, y_{i} | x\right)=\exp \left(W_{i}\left(y_{i-1}, y_{i} | x\right)\right) \\ W_{i}\left(y_{i-1}, y_{i} | x\right)=\sum_{i=1}^{K} w_{k} f_{k}\left(y_{i-1}, y_{i}, x, i\right) \end{array}

对每个指标

i=0,1,...,n+1,定义前向向量
\alpha_{i}(x),则递推公式:

\alpha_{i}^{\mathrm{T}}\left(y_{i} | x\right)=\alpha_{i-1}^{\mathrm{T}}\left(y_{i-1} | x\right) M_{i}\left(y_{i-1}, y_{i} | x\right), \quad i=1,2, \cdots, n+1

其中,

\alpha_{0}(y | x)=\left\{\begin{array}{ll} 1, & y=\text { start } \\ 0, & \text { 否则 } \end{array}\right.

step 2 后向计算

对每个指标

i=0,1,...,n+1,定义前向向量
\beta_{i}(x),则递推公式:

\begin{aligned} &\beta_{n+1}\left(y_{n+1} | x\right)=\left\{\begin{array}{ll} 1, & y_{n+1}=\operatorname{stop} \\ 0, & \text { 否则 } \end{array}\right.\\ &\beta_{i}\left(y_{i} | x\right)=M_{i}\left(y_{i}, y_{i+1} | x\right) \beta_{i-1}\left(y_{i+1} | x\right) \end{aligned}

step 3

Z(x)=\alpha_{n}^{\mathrm{T}}(x) \cdot \mathbf{1}=\mathbf{1}^{\mathrm{T}} \cdot \beta_{1}(x)

step 4 概率计算

所以,标注序列在位置

i是标注
y_i的条件概率为:

\begin{array}{c} P\left(Y_{i}=y_{i} | x\right)=\frac{\alpha_{i}^{\mathrm{T}}\left(y_{i} | x\right) \beta_{i}\left(y_{i} | x\right)}{Z(x)} \\ P\left(Y_{t-1}=y_{i-1}, Y_{i}=y_{i} | x\right)=\frac{\alpha_{i-1}^{\top}\left(y_{i-1} | x\right) M_{i}\left(y_{i-1}, y_{i} | x\right) \beta_{i}\left(y_{i} | x\right)}{Z(x)} \end{array}

其中,

Z(x)=\alpha_{n}^{T}(x) \cdot \mathbf{1}

step 5 期望值计算

通过利用前向-后向向量,计算特征函数关于联合概率分布

P(X,Y)和条件概率分布
P(Y|X)的数学期望,即特征函数
f_k关于条件概率分布
P(Y|X)的数学期望:

\begin{aligned} E_{P(Y | X)}\left[f_{k}\right] &=\sum_{y} P(y | x) f_{k}(y, x) \\ &=\sum_{i=1}^{n+1} \sum_{n \rightarrow \infty} f_{k}\left(y_{i-1}, y_{i}, x, i\right) \frac{\alpha_{i-1}^{\top}\left(y_{i-1} | x\right) M_{i}\left(y_{i-1}, y_{i} | x\right) \beta_{i}\left(y_{i} | x\right)}{Z(x)} \\ k &=1,2, \cdots, K \end{aligned}

其中:

Z(x)=\alpha_{n}^{\mathrm{T}}(x) \cdot \mathbf{1}

学习问题

这里主要介绍一下 BFGS 算法的思路。

输入:特征函数

f_1,f_2,...,f_n:经验分布
\widetilde{P}(X,Y)

输出:最优参数值

\widehat{w},最优模型
P_{\widehat{w}}(y|x)
  • 1. 选定初始点
    w^{(0)},取
    B_0为正定对称矩阵,
    k = 0;
  • 2. 计算
    g_k = g(w^(k)),若
    g_k = 0,则停止计算,否则转 (3) ;
  • 3. 利用
    B_k p_k = -g_k计算
    p_k
  • 4. 一维搜索:求
    \lambda_k使得

f\left(w^{(k)}+\lambda_{k} p_{k}\right)=\min _{\lambda>0} f\left(w^{(k)}+\lambda p_{k}\right)
  • 5. 设
    w^{(k+1)} = w^{(k)} + \lambda_k * p_k
  • 6. 计算
    g_{k+1} = g(w^{(k+1)}),

    g_k = 0,则停止计算;否则,利用下面公式计算
    B_{k+1}:
    \begin{aligned} &B_{k+1}=B_{k}+\frac{y_{k} y_{k}^{\top}}{y_{k}^{\top} \delta_{k}}-\frac{B_{k} \delta_{k} \delta_{k}^{\dagger} B_{k}}{\delta_{k}^{\mathrm{T}} B_{k} \delta_{k}}\\ &y_{k}=g_{k+1}-g_{k}, \quad \delta_{k}=w^{(k+1)}-w^{(k)} \end{aligned}
  • 7. 令
    k=k+1,转步骤(3);

预测问题

对于预测问题,常用的方法是维特比算法,其思路如下:

输入:模型特征向量

F(y,x)和权重向量
w,输入序列(观测序列)
x={x_1,x_2,...,x_n}

输出:条件概率最大的输出序列(标记序列)

y^{*}=\left(y_{1}^{*}, y_{2}^{*}, \ldots, y_{n}^{*}\right),也就是最优路径;
  • 1. 初始化

\delta_{1}(j)=w \cdot F_{1}\left(y_{0}=\text {start}, y_{1}=j, x\right), \quad j=1,2, \cdots, m
  • 2. 递推,对
    i=2,3,...,n

\begin{array}{c} \delta_{i}(l)=\max _{1 \leqslant j \leqslant n}\left\{\delta_{i-1}(j)+w \cdot F_{i}\left(y_{i-1}=j, y_{i}=1, x\right)\right\}, \quad l=1,2, \cdots, m \\ \Psi_{i}(l)=\arg \max _{1 \leq j \leqslant m}\left\{\delta_{i-1}(j)+w \cdot F_{i}\left(y_{i-1}=j, y_{i}=l, x\right)\right\}, \quad l=1,2, \cdots, m \end{array}
  • 3. 终止

\begin{array}{c} \max _{y}(w \cdot F(y, x))=\max_{1<j<x}\delta_{n}(j) \\ y_{n}^{*}=\arg \max _{1<j \in n} \delta_{n}(j) \end{array}\coprod_{a}^{b}
  • 4. 返回路径

y_{i}^{*}=\Psi_{i+1}\left(y_{i+1}^{*}\right), \quad i=n-1, n-2, \cdots, 1

求得最优路径

y^{}= (y_1^*,y_2^*,...,y_n^*)

例子说明

利用维特比算法计算给定输入序列

x对应的最优输出序列
y^*

\max \sum_{i=1}^{3} w \cdot F_{i}\left(y_{i-1}, y_{i}, x\right)
  • 初始化

\begin{array}{l} \delta_{1}(j)=w \cdot F_{1}\left(y_{0}=\operatorname{star} t, y_{1}=j, x\right), \quad j=1,2 \\ t=1, \quad \delta_{1}(1)=1, \quad \delta_{1}(2)=0.5 \end{array}
  • 递推,对
    i=2,3,...,n

\begin{array}{c} i=2 \begin{array}{c} \delta_{2}(l)=\max \left\{\delta_{1}(j)+w \cdot F_{2}(j, l, x)\right\} \\ \delta_{2}(1)=\max \left\{1+\lambda_{2} t_{2}, 0.5+\lambda_{3} t_{4}\right\}=1.6, \quad \Psi_{2}(1)=1 \\ \delta_{2}(2)=\max \left\{1+\lambda_{1} t_{1}+\mu_{2} s_{2}, 0.5+\mu_{2} s_{2}\right\}=2.5, \quad \Psi_{,}(2)=1 \end{array} \\ \begin{aligned} i=3^{\prime} \delta_{3}(l)=\max \left\{\delta_{2}(j)+w \cdot F_{3}(j, l, x)\right\} \\ \delta_{3}(1)=\max \left\{1.6+\mu_{5} s_{5}, 2.5+\lambda t_{3}+\mu_{3} s_{1}\right\}=4.3, \quad \Psi_{3}(1)=2 \\ \delta_{3}(2)=\max \left\{1.6+\lambda t_{1}+\mu_{4} s_{4}, 2.5+\lambda_{5} t_{5}+\mu_{4} s_{4}\right\}=3.2, \quad \Psi_{3}(2)=1 \end{aligned} \end{array}
  • 终止

\begin{array}{c} \max _{y}(w \cdot F(y, x))=\max \delta_{3}(l)=\delta_{3}(1)=4.3 \\ y_{3}^{*}=\arg \max _{2} \delta_{3}(l)=1 \end{array}
  • 返回路径

\begin{array}{l} y_{2}^{*}=\Psi_{3}\left(y_{3}^{*}\right)=\Psi_{3}(1)=2 \\ y_{1}^{*}=\Psi_{2}\left(y_{2}^{*}\right)=\Psi_{2}(2)=1 \end{array}

求得最优路径

y^{}= (y_1^*,y_2^*,...,y_n^*) = (1,2,1)
import numpy as np

class CRF(object):
    '''实现条件随机场预测问题的维特比算法
    '''
    def __init__(self, V, VW, E, EW):
        '''
        :param V:是定义在节点上的特征函数,称为状态特征
        :param VW:是V对应的权值
        :param E:是定义在边上的特征函数,称为转移特征
        :param EW:是E对应的权值
        '''
        self.V  = V  #点分布表
        self.VW = VW #点权值表
        self.E  = E  #边分布表
        self.EW = EW #边权值表
        self.D  = [] #Delta表,最大非规范化概率的局部状态路径概率
        self.P  = [] #Psi表,当前状态和最优前导状态的索引表s
        self.BP = [] #BestPath,最优路径
        return 

    def Viterbi(self):
        '''
        条件随机场预测问题的维特比算法,此算法一定要结合CRF参数化形式对应的状态路径图来理解,更容易理解.
        '''
        self.D = np.full(shape=(np.shape(self.V)), fill_value=.0)
        self.P = np.full(shape=(np.shape(self.V)), fill_value=.0)
        for i in range(np.shape(self.V)[0]):
            #初始化
            if 0 == i:
                self.D[i] = np.multiply(self.V[i], self.VW[i])
                self.P[i] = np.array([0, 0])
                print('self.V[%d]='%i, self.V[i], 'self.VW[%d]='%i, self.VW[i], 'self.D[%d]='%i, self.D[i])
                print('self.P:', self.P)
                pass
            #递推求解布局最优状态路径
            else:
                for y in range(np.shape(self.V)[1]): #delta[i][y=1,2...]
                    for l in range(np.shape(self.V)[1]): #V[i-1][l=1,2...]
                        delta = 0.0
                        delta += self.D[i-1, l]                      #前导状态的最优状态路径的概率
                        delta += self.E[i-1][l,y]*self.EW[i-1][l,y]  #前导状态到当前状体的转移概率
                        delta += self.V[i,y]*self.VW[i,y]            #当前状态的概率
                        print('(x%d,y=%d)-->(x%d,y=%d):%.2f + %.2f + %.2f='%(i-1, l, i, y, \
                              self.D[i-1, l], \
                              self.E[i-1][l,y]*self.EW[i-1][l,y], \
                              self.V[i,y]*self.VW[i,y]), delta)
                        if 0 == l or delta > self.D[i, y]:
                            self.D[i, y] = delta
                            self.P[i, y] = l
                    print('self.D[x%d,y=%d]=%.2f\n'%(i, y, self.D[i,y]))
        print('self.Delta:\n', self.D)
        print('self.Psi:\n', self.P)

        #返回,得到所有的最优前导状态
        N = np.shape(self.V)[0]
        self.BP = np.full(shape=(N,), fill_value=0.0)
        t_range = -1 * np.array(sorted(-1*np.arange(N)))
        for t in t_range:
            if N-1 == t:#得到最优状态
                self.BP[t] = np.argmax(self.D[-1])
            else: #得到最优前导状态
                self.BP[t] = self.P[t+1, int(self.BP[t+1])]

        #最优状态路径表现在存储的是状态的下标,我们执行存储值+1转换成示例中的状态值
        #也可以不用转换,只要你能理解,self.BP中存储的0是状态1就可以~~~~
        self.BP += 1

        print('最优状态路径为:', self.BP)
        return self.BP

def CRF_manual():   
    S = np.array([[1,1],   #X1:S(Y1=1), S(Y1=2)
                  [1,1],   #X2:S(Y2=1), S(Y2=2)
                  [1,1]])  #X3:S(Y3=1), S(Y3=1)
    SW = np.array([[1.0, 0.5], #X1:SW(Y1=1), SW(Y1=2)
                   [0.8, 0.5], #X2:SW(Y2=1), SW(Y2=2)
                   [0.8, 0.5]])#X3:SW(Y3=1), SW(Y3=1)
    E = np.array([[[1, 1],  #Edge:Y1=1--->(Y2=1, Y2=2)
                   [1, 0]], #Edge:Y1=2--->(Y2=1, Y2=2)
                  [[0, 1],  #Edge:Y2=1--->(Y3=1, Y3=2) 
                   [1, 1]]])#Edge:Y2=2--->(Y3=1, Y3=2)
    EW= np.array([[[0.6, 1],  #EdgeW:Y1=1--->(Y2=1, Y2=2)
                   [1, 0.0]], #EdgeW:Y1=2--->(Y2=1, Y2=2)
                  [[0.0, 1],  #EdgeW:Y2=1--->(Y3=1, Y3=2)
                   [1, 0.2]]])#EdgeW:Y2=2--->(Y3=1, Y3=2)

    crf = CRF(S, SW, E, EW)
    ret = crf.Viterbi()
    print('最优状态路径为:', ret)
    return

if __name__=='__main__':
    CRF_manual()

v2-6196c8f2a9d4c8524ffe780bada7f8a6_b.jpg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值