通过追加-t, –textmodel参数可以输出文本格式的crf模型文件,通过该模型文本,可以加深对条件随机场的理解或为其他应用所利用。本文旨在介绍crf++的文本模型格式,具体读取与解码将集成到hanlp中一并开源。
以bmes标注语料为例:
注意字与标签之间的分隔符为制表符\t,否则会导致feature_index.cpp(86) [max_size == size] inconsistent column size错误。
t**:%x[#,#]中的t表示模板类型,两个"#"分别表示相对的行偏移与列偏移。
一共有两种模板:
第一种是unigram template:第一个字符是u,这是用于描述unigram feature的模板。每一行%x[#,#]生成一个crfs中的点(state)函数: f(s, o), 其中s为t时刻的的标签(output),o为t时刻的上下文.如crf++说明文件中的示例函数:
func1 = if (output = b and feature="u02:那") return 1 else return 0
它是由u02:%x[0,0]在输入文件的第一行生成的点函数.将输入文件的第一行"代入"到函数中,函数返回1,同时,如果输入文件的某一行在第1列也是“那”,并且它的output(第2列)同样也为b,那么这个函数在这一行也返回1。
第二种是bigram template:第一个字符是b,每一行%x[#,#]生成一个crfs中的边(edge)函数:f(s', s, o), 其中s'为t – 1时刻的标签.也就是说,bigram类型与unigram大致机同,只是还要考虑到t – 1时刻的标签.如果只写一个b的话,默认生成f(s', s),这意味着前一个output token和current token将组合成bigram features。
使用下列命令可以得到一个model文件和一个model.txt文件,后者是本文的主要研究对象。
参数解释如下:
输出
训练过程中会输出一些信息,其意义如下:
可见,如果希望训练快速结束,可以在命令行中适当减小maxiter值,增大eta值。
打开model.txt,其基本内容骨架如下:
接下来我会把上述骨架分解说明——
说明了模型的版本,通过-c参数指定的cost-factor,特征函数的最大id,xsize是特征维数,也就是训练语料列数-1。
值得注意的是maxid比我们从文本中观察到的最大id大了4,这是为什么呢?且听下文分解。
也就是最终的输出。
训练时用到的模板。
按照[id] [参数o]的格式排列,你可能会奇怪,f(s, o)应该接受两个参数才对。其实s隐藏起来了,注意到id不是连续的,而是隔了四个,这表示这四个标签(s=b|m|e|s)和公共的参数o组合成了四个特征函数。特别的,0-15为bems转移到bems的转移函数,也就是f(s', s, o=null)。
后面的小数依id顺序对应每个特征函数的权值。
严格来讲,解码并不属于本文的范围,但是不说说解码的话,对特征函数权值的理解就仅仅限于“浮点数”这一表面。所以简要地说说解码,比如说我们有一个句子“商品和服务”,对于每个字都按照上述模板生成一系列u特征函数的参数代入,得到一些类似010101的函数返回值,乘上这些函数的权值求和,就得到了各个标签的分数,由大到小代表输出这些标签的可能性。
至于b特征函数(这里特指简单的f(s', s)),在viterbi后向解码的时候,前一个标签确定了后就可以代入当前的b特征函数,计算出每个输出标签的分数,再次求和排序即可。
<a target="_blank" href="http://www.hankcs.com/wp-content/uploads/2014/12/crf++%e5%b7%a5%e5%85%b7%e5%8c%85%e4%bd%bf%e7%94%a8%e4%bb%8b%e7%bb%8d.ppt">crf++工具包使用介绍.ppt</a>
原文 http://www.hankcs.com/nlp/the-crf-model-format-description.html