CRF++模板使用(转)

CRF++模板构建分为两类,一类是Unigram标注,一类是Bigram标注。 

Unigram和Bigram模板分别生成CRF的状态特征函数 s_{l}(y_{i},x,i) 和转移特征函数 t_{k}(y_{i-1},y_{i},x,i) 。其中 y_{i} 是标签, x 是观测序列, i 是当前节点位置。
Bigram 下面只需要加一个B就ok了,其它还是用Unigram模板生成特征。

主要介绍Unigram模板

Unigram

U00:%x[-2,0] 
U01:%x[-1,0] 
U02:%x[0,0] 
U03:%x[1,0] 
U04:%x[2,0] 
U05:%x[-2,0]/%x[-1,0]/%x[0,0] 
U06:%x[-1,0]/%x[0,0]/%x[1,0] 
U07:%x[0,0]/%x[1,0]/%x[2,0] 
U08:%x[-1,0]/%x[0,0] 
U09:%x[0,0]/%x[1,0] 

 

特征模板格式:%x[row,col]。x可取U或B,对应两种类型。方括号里的编号用于标定特征来源,row表示相对当前位置的行,0即是当前行col对应训练文件中的列。这里只使用第1列(编号0),即文字。

Unigram template:第一个字符是U,这是用于描述unigram feature的模板。每一行%x[#,#]生成一个CRFs中的点(state)函数: f(s, o), 其中s为t时刻的的标签(output),o为t时刻的上下文.


这是CRF++例子中给出的模板,一共有9个模板,先看第一个模板,表示当前词和其前面的第二个词组成的特征,U02表示当前词

CRF++遍历每一个位置时,会查看此位置前一个位置(-1,0)和前两个位置(-2,0)和后一个位置(1,0)和后两个位置(2,0),这是U00,U01,U02,U03,U04所规定的。至于后面几个特征函数,比如U05,它把前面的几个位置合起来看。

以‘小明今天穿了一件红色上衣’为例,符合CRF++处理格式的这句话应该变成如下形式: 
小 B 
明 I 
今 B 
天 I 
穿 S 
了 S 
一 B 
件 I 
红 B 
色 I 
上 B 
衣 I 

假设我们有三个标记tag,B(表示一个词的开头那个字),I(表示一个词的结尾那个字),S(表示单个字的词)。

先看第一个模板U00:%x[-2,0],第一个模板产生的特征如下: 
如果当前词是‘今’那-2位置对应的字就是‘小’, 
每个特征对应的字如下: 


U00:%x[-2,0]=====>小 
U01:%x[-1,0]=====>明 
U02:%x[0,0]=====>今 
U03:%x[1,0]=====>天 
U04:%x[2,0]=====>穿 
U05:%x[-2,0]/%x[-1,0]/%x[0,0]=====>小/明/今 
U06:%x[-1,0]/%x[0,0]/%x[1,0]=====>明/今/天 
U07:%x[0,0]/%x[1,0]/%x[2,0]=====>今/天/穿 
U08:%x[-1,0]/%x[0,0]=====>明/今 
U09:%x[0,0]/%x[1,0]=====>今/天 


根据第一个模板U00:%x[-2,0]能得到的转移特征函数如下: 
func1=if(output=B and feature=’U00:小‘ ) return 1 else return 0 

func2=if(output=I and feature=’U00:小’) return 1 else return 0 
func3=if(output=S and feature=’U00:小) return 1 else return 0 


其中output=B 指的是当前词(字)的预测标记,也就是’今‘的预测标记,每个模板会把所有可能的标记输出都列一遍,然后通过训练确定每种标记的权重,合理的标记在训练样本中出现的次数多,对应的权重就高,不合理的标记在训练样本中出现的少,对应的权重就少。

得到三个特征函数之后当前这个字’‘的特征函数利用第一个模板就全了。然后扫描下一个字‘‘,以’天‘字作为当前字预测这个字的标记tag,同样会得到三个特征函数: 
func4=if(output=B and feature=’U00:明’) return 1 else return 0 
func5=if(output=I and feature=’U00:明’) return 1 else return 0 
func6=if(output=S and feature=’U00:明’) return 1 else return 0 

后面U01~U09都会按此方式继续扫描生成特征函数。

func = if(output = B,and feature = “U05:小/明/今”) return 1 else return 0 
即当前位置输出标签为B,并且当前位置为,前一个位置是,前两个位置是,则输出1。

不管以何种方式扫描或者生成模板,最终会生成N*T*M个特征函数,N代表分词中词的个数,T代表分词标注的tag标签(B,I,S等),M代表模板个数。

 

Bigram类型

与Unigram不同的是,Bigram类型模板生成的函数会多一个参数:上个节点的标签 。

生成函数类似于:

func1 = if (prev_output = B and output = B and feature=B01:"北") return 1 else return 0
这样,每行模板则会生成 L*L*N 个特征函数。经过训练后,这些函数的权值反映了上一个节点的标签对当前节点的影响。

 

参考链接https://www.cnblogs.com/pangxiaodong/archive/2011/11/21/2256264.html

posted @ 2018-11-27 15:17  光彩照人  阅读(...)  评论(...编辑  收藏