sponsored links

CRF++之txt模型详解

例子解析

下面是一个crfpp训练出来的txt模型样例:

version: 100
cost-factor: 1
maxid: 2978536
xsize: 1

B
E
M
O

U00:%x[-3,0]
U01:%x[-2,0]
U02:%x[-1,0]
U03:%x[0,0]
U04:%x[1,0]
U05:%x[2,0]
U06:%x[3,0]
U07:%x[-3,0]/%x[-2,0]/%x[-1,0]/%x[0,0]
U08:%x[-2,0]/%x[-1,0]/%x[0,0]/%x[1,0]
U09:%x[-1,0]/%x[0,0]/%x[1,0]/%x[2,0]
U10:%x[0,0]/%x[1,0]/%x[2,0]/%x[3,0]
U11:%x[-2,0]/%x[-1,0]/%x[0,0]
U12:%x[-1,0]/%x[0,0]/%x[1,0]
U13:%x[0,0]/%x[1,0]/%x[2,0]
U14:%x[-1,0]/%x[0,0]
U15:%x[0,0]/%x[1,0]
B

0 B
16 U00:"
20 U00:#
24 U00:$
28 U00:%
32 U00:&
...
2978512 U15:¥/6
2978516 U15:¥/7
2978520 U15:¥/8
2978524 U15:¥/9
2978528 U15:¥/_
2978532 U15:¥/收

-0.3833645332269790
0.1201377122403721
2.4181637661758955
-2.9061977301372388
-0.8957977672327538
-0.5282220808730558
-0.4808152690227827
-0.0180459673166369
-0.7088260954767709
1.4525415018058483
4.5702819962135459
-2.5223604291302082
...

注意:文件太长,我们省略了一部分内容(用省略号表示)

从上往下,我们一一来看:

  1. 第1~4行:maxid表示最大的特征函数id;xsize表示训练数据特征列数
  2. 第6~9行:表示训练数据标注集(状态集),此处分别是BEMO
  3. 第11~27行:表示特征模板,其中第27行为bigram特征模板;其余为unigram特征模板
  4. 第29~41行:表示特征模板产生的特征函数。格式为:
    <特征函数id> <模板id>:<观测>
    

    你发现id显示并不是连续的,为什么呢?

    • 对于id为(0~15),特征函数实际上是bigram特征。bigram特征实际上是状态转移特征,即:
      B->B
      B->E
      B->M
      B->O
      E->B
      E->E
      E->M
      E->O
      M->B
      M->E
      M->M
      M->O
      O->B
      O->E
      O->M
      O->O
      
    • 对于后面的id,你发现每4个显示一次,实际上特征函数是针对某个具体标签的,模型中只显示了针对第一个标签(此处是B)产生的特征函数。所以特征函数U00:"对于标签O的id就是19。
  5. 第43行以后:表示每个特征函数的权重。数值越大,特征函数越重要。前16个数字是状态转移权重;后面是特征函数权重,和上面的特征函数一一对应。

关于解码

  1. 对于每个观测,每个特征模板都会生成它对于每个状态的特征函数,我们在模型中找到特征函数对应的权重,累加得到score
  2. 从模型中我们还获得了状态转移权重,于是可以使用维特比解码,找出score最高的序列

看个例子:
我们有如下模板:

U00:%x[-2,0]/%x[-1,0]
U01:%x[-1,0]/%x[0,0]

我们的标注集为:

B E M O

我们要预测的序列为:

我今天很开心

假设当前观测为,于是两个模板产生如下特征函数:

今/天 -> B
今/天 -> E
今/天 -> M
今/天 -> O

天/很 -> B
天/很 -> E
天/很 -> M
天/很 -> O

于是,我们从模型中找对应特征函数的权重(找不到就是0),将这些权重加起来,得到当前字分别为BEMO的score。这样,序列的每个观测对应每个状态都会有一个score,再依据状态转移信息,进行维特比解码。

Tags: