CRF++的使用和模板理解

一 标注标签分类

IO
BIO
BMEWO
BMES

二 CRF++简介

CRF++是著名的条件随机场的开源工具,简单介绍一下windows系统下CRF++的使用
下载地址:crf++0.58
下载完解压就可以使用

2.1 文件目录

文件目录
doc文件夹:就是官方主页的内容。
example文件夹:有四个任务的训练数据、测试数据和模板文件。
sdk文件夹:CRF++的头文件和静态链接库。
crf_learn.exe:CRF++的训练程序。
crf_test.exe:CRF++的预测程序
libcrfpp.dll:训练程序和预测程序需要使用的静态链接库。

一般我们只需要使用的就是crf_learn.exe,crf_test.exe和libcrfpp.dll,这三个文件。

2.2 命令行格式

训练

% crf_learn template_file train_file model_file

这个训练过程的时间、迭代次数等信息会输出到控制台上(感觉上是crf_learn程序的输出信息到标准输出流上了),如果想保存这些信息,我们可以将这些标准输出流到文件上,命令格式如下:

% crf_learn template_file train_file model_file >> train_info_file

四个主要参数调整:

-a CRF-L2 or CRF-L1

规范化算法选择。默认是CRF-L2。一般来说L2算法效果要比L1算法稍微好一点,虽然L1算法中非零特征的数值要比L2中大幅度的小。

-c float

这个参数设置CRF的hyper-parameter。c的数值越大,CRF拟合训练数据的程度越高。这个参数可以调整过度拟合和不拟合之间的平衡度。这个参数可以通过交叉验证等方法寻找较优的参数。

-f NUM

这个参数设置特征的cut-off threshold。CRF++使用训练数据中至少NUM次出现的特征。默认值为1。当使用CRF++到大规模数据时,只出现一次的特征可能会有几百万,这个选项就会在这样的情况下起到作用。

-p NUM

如果电脑有多个CPU,那么那么可以通过多线程提升训练速度。NUM是线程数量。
一个示例

crf_learn -f  3 -c 4 template_file train_file model_file

测试

% crf_test -m model_file test_files

有两个参数-v和-n都是显示一些信息的,-v可以显示预测标签的概率值,-n可以显示不同可能序列的概率值,对于准确率,召回率,运行效率,没有影响。
与crf_learn类似,输出的结果放到了标准输出流上,而这个输出结果是最重要的预测结果信息(测试文件的内容+预测标注),同样可以使用重定向,将结果保存下来,命令行如下:

% crf_test -m model_file test_files >> output_file

训练过程中会输出一些信息,其意义如下:

iter:迭代次数。当迭代次数达到maxiter时,迭代终止
terr:标记错误率
serr:句子错误率
obj:当前对象的值。当这个值收敛到一个确定值的时候,训练完成
diff:与上一个对象值之间的相对差。当此值低于eta时,训练完成

如果希望训练快速结束,可以在命令行中适当减小maxiter值,增大eta值

三 模板构建

模板构建分为两类,一类是Unigram标注,一类是Bigram标注。
Unigram模板是比较常用的模板,这类模板提取的信息较为全面,组成的模板数量也比较多;
Bigram模板比较简单,一般是当前词和前面一个词的自动组合生成的Bigram特征集合。

Unigram和Bigram模板分别生成CRF的状态特征函数 sl(yi,x,i) 和转移特征函数 tk(yi-1,yi,x,i) 。其中 yi 是标签, x 是观测序列, i 是当前节点位置。每个函数还有一个权值.

crf++模板定义里的%x[row,col],即是特征函数的参数 x 。

举个例子。假设有如下用于分词标注的训练文件:
北 N B
京 N E
欢 V B
迎 V M
你 N E

第一列是文字,第二列是词性,前两列都可以视为特征,第三列为标签,也就是我们需要预测的内容,有BME三种状态。

我们选取第一列作为特征来讲解便于理解,去除中间的词性标注
所以训练文件变为:
北 B
京 E
欢 B
迎 M
你 E

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

Unigram类型

每一行模板生成一组状态特征函数,数量是L * N 个,L是标签状态数。N是此行模板在训练集上展开后的唯一样本数,在这个例子中,第一列的唯一字数是5个,所以有L * N = 3*5=15。

例如:U01:%x[0,0],生成如下15个函数:
func1 = if (output = B and feature=U01:“北”) return 1 else return 0
func2 = if (output = M and feature=U01:“北”) return 1 else return 0
func3 = if (output = E and feature=U01:“北”) return 1 else return 0
func4 = if (output = B and feature=U01:“京”) return 1 else return 0

func13 = if (output = B and feature=U01:“你”) return 1 else return 0
func14 = if (output = M and feature=U01:“你”) return 1 else return 0
func15 = if (output = E and feature=U01:“你”) return 1 else return 0
这些函数经过训练后,其权值表示函数内文字对应该标签的概率(形象说法,概率和可大于1)。

又如 U02:%x[-1,0] 因为第一行没有前一行(-1 行)所以从第二行开始选取当前token的前一行的第一列。一直到最后一行的前一行结束
token = “北”
func1 = if (output = B and feature=U01:“京”) return 1 else return 0
func1 = if (output = M and feature=U01:“京”) return 1 else return 0
func1 = if (output = E and feature=U01:“京”) return 1 else return 0


token = “你”
func10 = if (output = B and feature=U01:“迎”) return 1 else return 0
func11 = if (output = M and feature=U01:“迎”) return 1 else return 0
func12 = if (output = E and feature=U01:“迎”) return 1 else return 0

训练后,该组函数权值反映了句子中上一个字对当前字的标签的影响

对于每一个不同的token(这里指第一列的数据),依此套入模板来生成状态特征函数

Bigram类型

与Unigram不同的是,Bigram类型模板生成的函数会多一个参数:上个节点的标签 。第一个字符是B,每一行%x[#,#]生成一个CRFs中的边(Edge)函数:f(s’, s, o), 其中s’为t – 1时刻的标签.也就是说,Bigram类型与Unigram大致机同,只是还要考虑到t – 1时刻的标签。

每行模板则会生成 L* L* N 个特征函数。经过训练后,这些函数的权值反映了上一个节点的标签对当前节点的影响。

生成函数类似于(对于token =“北”):
func1 = if (prev_output = B and output = B and feature=B01:“北”) return 1 else return 0
func1 = if (prev_output = B and output = M and feature=B01:“北”) return 1 else return 0
func1 = if (prev_output = B and output =E and feature=B01:“北”) return 1 else return 0
func1 = if (prev_output = M and output = B and feature=B01:“北”) return 1 else return 0
func1 = if (prev_output = M and output = M and feature=B01:“北”) return 1 else return 0
func1 = if (prev_output = M and output = E and feature=B01:“北”) return 1 else return 0
func1 = if (prev_output = E and output = B and feature=B01:“北”) return 1 else return 0
func1 = if (prev_output = E and output = M and feature=B01:“北”) return 1 else return 0
func1 = if (prev_output = E and output = E and feature=B01:“北”) return 1 else return 0

对于上面的训练数据 一共生成45个转移函数

如果只写一个B的话,默认生成f(s’, s),这意味着前一个output token和current token将组合成bigram features。

先写到这儿,有不对的地方 欢迎指出

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值