这是一个基于CRF的中文依存句法分析器,内部CRF模型的特征函数采用 双数组Trie树(DoubleArrayTrie)储存,解码采用特化的维特比后向算法。相较于《最大熵依存句法分析器的实现》,分析速度翻了一倍,达到了1262.8655 sent/s算法
开源项目数组
本文代码已集成到HanLP中开源项目中,最新hanlp1.7版本已经发布网络
CRF简介函数
CRF是序列标注场景中经常使用的模型,比HMM能利用更多的特征,比MEMM更能抵抗标记偏置的问题。在生产中常常使用的训练工具是CRF++,关于CRF++的使用以及模型格式请参阅《CRF++模型格式说明》。工具
CRF训练性能
语料库测试
与《最大熵依存句法分析器的实现》相同,采用清华大学语义依存网络语料的20000句做为训练集。spa
预处理3d
依存关系事实上由三个特征构成——起点、终点、关系名称。在本CRF模型中暂时忽略掉关系名称(在下文能够利用其它模型补全)。对象
根据依存文法理论, 咱们能够知道决定两个词之间的依存关系主要有二个因素: 方向和距离。所以咱们将类别标签订义为具备以下的形式:
[ + |- ] dPOS
其中, [ + | – ]表示方向, + 表示支配词在句中的位置出如今从属词的后面, – 表示支配词出如今从属词的前面; POS表示支配词具备的词性类别; d表示距离。
好比原树库:
转换后:
特征模板
训练参数
1.crf_learn -f 3 -c 4.0 -p 3 template.txt train.txt model -t
个人试验条件(机器性能)有限,每迭代一次要花5分钟,最后只能设定最大迭代次数为100。通过痛苦的迭代,获得了一个效果很是有限的模型,其serr高达50%,暂时只作算法测试用。
解码
标准的维特比算法假定全部标签都是合法的,可是在本CRF模型中,标签还受到句子的约束。好比最后一个词的标签不多是+nPos,必须是负数,并且任何词的[+/-]nPos都得保证后面(或前面,当符号为负的时候)有n个词语的标签是Pos。因此我覆写了CRF的维特比tag算法,代码以下:
注意上面的
1.if (!isLegal(j, i, table)) continue;
保证了标签的合法性。
这一步的结果:
后续处理
有了依存的对象,还须要知道这条依存关系究竟是哪一种具体的名称。我从树库中统计了两个词的词与词性两两组合出现几率,姑且称其为2gram模型,用此模型接受依存边两端的词语,输出其最可能的关系名称。
最终结果
转换为CoNLL格式输出: