糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > CRF模型——打通crf模型的任督二脉(一)

CRF模型——打通crf模型的任督二脉(一)

时间:2023-04-05 13:15:30

相关推荐

CRF模型——打通crf模型的任督二脉(一)

CRF模型 是nlp领域的经典模型,也是公认的不好学习的模型(相比其他机器学习模型)

,我记得作为小蓝书《统计机器学习》的最后一章,当年看得那叫一个晦涩难懂呢2333333,反正看了一两遍是看不太懂,

网上博客中 照抄小蓝书《统计机器学习》的最后一章的尤为多,也不能说不对,只是对我这种 小白,还是希望能有掰开算法细节和公式细节,甚至源代码细节来看的文章。

网上关于CRF模型的各种文章,我觉得问题在于没有 打通 CRF模型的任督二脉,

其中我认为CRF模型之所以被公认为是不好学习的模型,原因就在于相比其他机器学习模型,CRF模型中的特征的处理方式有较大的不同,CRF模型中有特征模板,特征函数,这些都是其他机器学习模型中少有的概念。所以,只要弄清楚 CRF模型中的特征模板,特征函数,特征值 这一条线上的关系,CRF模型就没有什么晦涩难懂的了。其后的 前向概率-后向概率算法以及维特比预测算法都是通用的算法,不算晦涩难懂。

关于CRF模型中的特征模板,特征函数,特征值,我画了一个下面的图。

一般机器学习模型 的特征 表现方式都比较直观,(虽然构造渠道,方式需要经验和技巧),但CRF模型中由于特征模板的存在,特征 表现方式就不再那么直观了,但不管怎么,由上图可以看到,如果不看中间的第二步(即第二步是透明的),我们能看到,只要 给定语料和特征模板 , 对应的特征值其实就 已经确定下来了,代码要做的事就是按特征函数来统计算出对应的特征值。

搞清楚CRF模型中 最难懂的概念之后,我们再来看一些公式,我相信感受会更好。

下面输markdown 也是累死老子了。

还是先从特征函数的表达式开始,然后再看似然函数或者损失函数的式子,最后再看 对参数求导的过程。

参考 两个我觉得不错的讲解CRF模型的原创博客

条件随机场(Conditional Random Field)简介

/aws3217150/article/details/68935789

CRF++源码解读

/aws3217150/article/details/69212445

特征模版

CRF++训练的时候,要求我们提供特征模版,特征模版像下面这样,先来看如下图片:

“%x[row, column]” 代表获得当前指向位置向上或向下偏移|row|行,并指向第column列的值,绝大多数情况下,我们的训练语料都是(字/词,label),且90%的例子中我们看到的特征模版中的column都是=0的,这意味着column=0,我们只把字/词当作特征。

比如上图中,当前指向位置为 “the DT B-NP”,那么”%x[0,0]”代表获得当前指向偏移0行,第0列的值,也就是”the”,这条模板构成的特征含义是“当前位置的词是“the”且label=xx”是否为真(xx可以是L中label中的任一个)。

而”%x[0,1]”代表获得当前指向偏移0行,第1列的值,也就是”DT”。这条模板构成的特征含义是“当前位置的词性是“DT”且label=xx”是否为真(xx可以是L中label中的任一个)。

”%x[-2,1]”则代表获得当前指向向上偏移2行,第1列的值,也就是”PRP”,这条模板构成的特征含义是“前前位置的词性是“PRP”且label=xx”是否为真(xx可以是L中label中的任一个)。

这就是特征最完整的意思,

之前对一个问题迷茫过,就是

”%x[0,0]”和”%x[-1,0]”遇到“the"是否产生了重复的特征。

后面想明白了,解开了这个困惑。

因为”%x[0,0]”遇到“the",产生的特征函数,举一个label=b为例来说就是,

产生了f1=“当前位置的词是“the”且当前位置label是b"是否为真。

而”%x[-1,0]”遇到“the”,产生的特征函数,举一个label=b为例来说就是,

产生了f2="前一个位置的词是“the”且当前位置label是b"是否为真。

显然不一样,f2在每个位置上都会去检查前一个位置是否为“the”。

看明白了这个,就能准确的知道Unigram模版产生多少个特征函数了。

对每一条Unigram模版的规则而言,它能扫描到M个不同的取值。(一般也就是M个不同的字/词),M个不同的取值中的每一中对当前位置的label(L种)都要考虑,也就要再乘以L.

如果有N条Unigram模版的规则,那么需要再乘以N,为什么因为每一条Unigram模版的规则,参考的位置都不同,正如前面写的,”%x[0,0]”参考当前位置的取值,”%x[-1,0]”参考前一位置的取值,”%x[-2,0]”参考前前位置的取值。

所以N条Unigram模版的规则能产生N∗M∗LN*M*LN∗M∗L种特征函数。

再看Bigram模版。

绝大多少例子中的Bigram模版就写了一个B就完事了。

那么写一个B代表什么意思,没有具体写出Bigram模版的规则,会不会是没有用Bigram模版产生特征函数?如果确实产生了特征函数,那么长什么样子,能否像Unigram模版的规则知道每一个特征的具体含义呢?

答案一一解开:

1,写一个B不代表没有Bigram模版的规则,而是这里的B是一个简要记法。还原的话应该是”B01:%x[0,0]”,Bigram模版的B二元的意思是,当前标签取值和上一次标签取值,(一元的意思是只考虑当前位置的标签,就一个。二元的意思是不仅考虑当前位置的标签还考虑前一个位置的标签,所以是两个,原来你是这样的二,笑哭,是不是和开始想象的二不太一样了,哈哈)。

所以假设一条Bigram模版的规则而言,假设它能扫描到M个不同的取值。(一般也就是M个不同的字/词),M个不同的取值中的每一取值对当前位置label和前一个位置的label 这两个位置的label有(L∗LL*LL∗L种组合)。

所以1条Bigram模版1条Bigram模版1条Bigram模版的规则能产生M∗L∗LM*L*LM∗L∗L种特征函数。

另外再补充一点,为什么写一个B也应该有Bigram特征函数的产生。

那是因为Bigram特征函数本质上就是转移特征,Bigram特征函数对应的权重就是转移特征矩阵中的值。

对应着,Unigram特征函数本质上就是发射特征(或者说状态特征),Unigram特征函数对应的权重就是发射特征矩阵中的值。

小蓝书 《统计机器学习》的最后一章 对特征函数的数学表示是,如下:

条件随机场CRF中的同一特征 会在各个位置上都有定义,可以会对同一特征在各个位置上求和,得到特征函数对应的全局特征值。

特征函数包含两类,

一类是由B开头的模板决定的 定义在边上的特征函数,一般看成是 转移特征,对应有转移特征值,依赖当前位置和上一个位置

另一类是由U开头的模板决定的 定义在节点上的特征函数,一般看成是 转态特征,对应有转态特征值,只依赖当前位置的观测取值(crf++的Unigram特征模版产生的特征函数把“只依赖当前位置”这一条扩展了,变成了依赖当前位置的观测取值,依赖前一位置的观测取值,依赖前前一位置的观测取值)

小蓝书 《统计机器学习》也直白的说了, 条件随机场CRF完全由 转移特征函数值 tkt_ktk​、 状态特征函数值sls_lsl​ 和对应的 权重 λk,μl\lambda_k,\mu_lλk​,μl​确定。

看到这里估计对下标 k和l有点疑问了,放后面。

小蓝书 《统计机器学习》提到,首先将转移特征函数和状态特征函数 及其权重用同一的符号表示,设有K1K_1K1​个转移特征(L∗L∗NL*L*NL∗L∗N) , K2K_2K2​个转态特征(L∗NL*NL∗N),K=K1+K2K=K_1+K_2K=K1​+K2​,可把特征函数统一记为:

fk(yi−1,yi,x,i)={tk(yi−1,yi,x,i)k=1,2,...,K1sl(yi,x,i)k=K1+l,l=1,2,...,K2f_k(y_{i-1},y_{i},x,i)=\left\{ \begin{array}{rcl} t_k(y_{i-1},y_{i},x,i) & & {k=1,2,...,K_1} \\ s_l(y_{i},x,i) & & { k=K_1+l, l=1,2,...,K_2}\\ \end{array} \right. fk​(yi−1​,yi​,x,i)={tk​(yi−1​,yi​,x,i)sl​(yi​,x,i)​​k=1,2,...,K1​k=K1​+l,l=1,2,...,K2​​

状态特征函数需要在 各个位置上求和 ,得到对应特征值,

转移特征也是如此,得到对应的特征值,记作:

fk(y,x,i)=∑i=1nfk(yi−1,yi,x,i),k=1,2,...,Kf_k(y,x,i) = \sum_{i=1}^{n} f_k(y_{i-1},y_{i},x,i) ,k=1,2,...,Kfk​(y,x,i)=∑i=1n​fk​(yi−1​,yi​,x,i),k=1,2,...,K

并且各特征的权重值是一一对应的:

wk={λkk=1,2,...,K1μlk=K1+l,l=1,2,...,K2w_k=\left\{ \begin{array}{rcl} \lambda_{k} & & {k=1,2,...,K_1} \\ \mu_{l} & & { k=K_1+l, l=1,2,...,K_2}\\ \end{array} \right. wk​={λk​μl​​​k=1,2,...,K1​k=K1​+l,l=1,2,...,K2​​

看了上面之后,我们再看

/aws3217150/article/details/69212445

博客中,提到的Lafferty的原始论文中的表示方法:

原始论文的阐述形式是CRF是一种概率图模型,而一幅图可以由它的边和节点来表达,也就是

G=(V,E)

其中,V是节点集合,E是边集合,对于链式CRF,模型对于输入序列和输出序列可以建立如下的概率模型:

p(y⃗∣x⃗)=exp(∑e∈E∑kwkϕk(e=(yi−1,yi),x⃗)+∑v∈V∑twtϕt(v=yi,x⃗))Zp(\vec{y}|\vec{x})=\dfrac{exp( \sum_{e \in E}\sum_{k} w_k \phi_k (e=(y_{i-1},y_{i}), \vec{x}) +\sum_{v \in V}\sum_{t} w_t \phi_t (v=y_{i}, \vec{x})) }{Z}p(y​∣x)=Zexp(∑e∈E​∑k​wk​ϕk​(e=(yi−1​,yi​),x)+∑v∈V​∑t​wt​ϕt​(v=yi​,x))​

这种形式和我们常见的另一种形式其实又很大区别,另一种形式是:

p(y⃗∣x⃗)=exp(∑i∑kwkϕk(yi−1,yi,x⃗))∑y′∈Yexp(∑i∑kwkϕk(yi−1′,yi′,x⃗))p(\vec{y}|\vec{x})=\dfrac{exp( \sum_{i}\sum_{k} w_k \phi_k (y_{i-1},y_{i}, \vec{x}) ) }{\sum_{y^{'} \in Y} exp( \sum_{i}\sum_{k} w_k \phi_k (y_{i-1}^{'},y_{i}^{'}, \vec{x}) ) }p(y​∣x)=∑y′∈Y​exp(∑i​∑k​wk​ϕk​(yi−1′​,yi′​,x))exp(∑i​∑k​wk​ϕk​(yi−1​,yi​,x))​

下面的这种形式是没有将边和节点区分开来,看上去只是写了边的特征函数,因为从某种程度上看,边包含的信息其实已经涵盖了节点所拥有的所有信息,将这两者统一起来只是有利于我们数学公式表达的方便性,另一方面,将边和节点进行单独讨论,从理论上可能有一点冗余, 但从实际效果来讲以及实际源码编写中看,都是边和节点区分开来写源码的,节点信息可以充当一种backoff,起到一定的平滑效果(Smoothing)。

下面我们就看 CRF的似然函数或者损失函数的式子:

L=−∑iNlogp(y⃗i∣x⃗i)L=- \sum_{i}^{N} log p(\vec y^{i} |\vec x^{i})L=−∑iN​logp(y​i∣xi)

其实我看到这个式子,总觉得和以前看到的机器学习的损失函数式子不一样,就在于这个∑iN\sum_{i}^{N}∑iN​, 按之前看到的,应该不需要这个∑iN\sum_{i}^{N}∑iN​,直接用L=−logp(y⃗i∣x⃗i)L=- log p(\vec y^{i} |\vec x^{i})L=−logp(y​i∣xi)就行了好像。

N应该不是句子的个数,而是语料中按词或者子拆分后的行数才对。

在直接看对损失函数的求导推导之前,应该再回一下,CRF的模型的损失函数的由来,并由此带出CRF模型中的前向后向算法。

MEMM(Maximum Entropy Markov Model)最大熵马尔科夫模型,解决标注问题的假设,也是认为状态的转移仅仅依赖于上一状态(这里我将标注标签称为一种状态)

这其实和crf很像, crf 大致一看其实也是这样,crf本来就是基于这个改进的,后面再说

上述MEMM虽然可以很优雅地解决标注问题,但存在标注偏好的问题,就是说模型在为输入序列x 打标签的时候,存在偏袒心里,会倾向于选择某些标签,

如果 s1只有两种转移状态:s1,s2,而s2有5种转移状态:s1,s2,s3,s4,s5

因为s1的转移状态很少,所以不管实际训练观测值有多少,由于每一步的状态转移概率都要归一化,所以s1的转移概率都会被放大,而s2由于转移状态多,因此每一步转移概率归一化的时候都被平均分摊了。因此在计算最优序列的时候,MEMM会偏袒那些状态转移少的标签,而忽略了实际观察值,

为了说明该现象,我们可以参考原始论文的识别 rob和rib例子,可参考/aws3217150/article/details/68935789

MEMM产生Label Bias的根源是什么,

这是因为MEMM的状态转移概率的计算方式,为了获得转移概率,它每一步的状态转移都会进行归一化,从而导致问题的产生。

CRF认清了问题的根源,只要不要在每一步状态转移进行归一化,而在全局进行归一化就能一下子化解了MEMM产生的Label Bias标注偏好这个大问题。

p(s⃗∣x⃗)=∏i=0np(si∣si−1,x1,x2,...,xn)=∏i=0nexp(w⃗Tf(si,si−1,x⃗))∑s′∈Sexp(w⃗Tf(s⃗′,si−1,x⃗))p(\vec s| \vec x)=\prod_{i=0}^n p(s_i|s_{i-1},x_1,x_2,...,x_n)=\prod_{i=0}^n \dfrac{exp(\vec w^{T} f(s_i,s_{i-1},\vec x))}{ \sum_{s^{'} \in S} exp(\vec w^{T} f(\vec s^{'},s_{i-1},\vec x))}p(s∣x)=∏i=0n​p(si​∣si−1​,x1​,x2​,...,xn​)=∏i=0n​∑s′∈S​exp(wTf(s′,si−1​,x))exp(wTf(si​,si−1​,x))​

p(s⃗∣x⃗)=exp(w⃗TΦ(s⃗,x⃗))∑s′∈Snexp(w⃗TΦ(s⃗′,x⃗))p(\vec s| \vec x)=\dfrac{exp(\vec w^{T} \Phi(\vec s,\vec x))}{ \sum_{s^{'} \in S^{n}} exp(\vec w^{T} \Phi(\vec s^{'},\vec x))}p(s∣x)=∑s′∈Sn​exp(wTΦ(s′,x))exp(wTΦ(s,x))​

第一个是MEMM 对条件概率做的表达式,

第二个是CRF 对条件概率做的表达式,

分母中的 s′∈S,s′∈Sns^{'} \in S , s^{'} \in S^{n}s′∈S,s′∈Sn 一点点不同,表示的含义就千差万别了,前者只是局部的,后者是全局的。

CRF相对于MEMM做了几个改动,首先在特征函数上面做了变动:

Φ(s⃗,x⃗)→Rd\Phi(\vec s,\vec x) \rightarrow R^{d}Φ(s,x)→Rd

第一个是它将输入序列x⃗\vec xx和输出标注s⃗\vec ss映射为一个d维实数向量(这个d其实就是特征函数的个数,联系前面讲到的特征函数的内容,L∗N,L∗L∗NL*N,L*L*NL∗N,L∗L∗N),而MEMM的特征函数拥有的信息只是输入序列x⃗\vec xx和当前状态以及上一个状态,也就是说CRF的特征函数掌握信息量更多,从而表达能力更强。

第二个的改进是它不再针对每一次状态转移进行归一化,而是在全局进行归一化,这样完美解决Label Bias问题。

有得必有失,注意到全局进行归一化就意味着 模型的分母需要罗列所有的状态序列,对于序列长度为n的输入序列,状态序列的个数为∣S∣n|S|^{n}∣S∣n,对于这种指数增长问题,在实际应用中一般都是intractable的,只能付诸于近似求解,比如我们之前提过的Variational Bayes或者Gibbs Sampling等等。不过有一种特殊结构的CRF,精确快速求解的方式是存在的(前向后向算法帮助我们),因此在早期得以广泛应用。

如果觉得《CRF模型——打通crf模型的任督二脉(一)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。