CRF++中文分词使用指南

来源:互联网 发布:松井玲奈 知乎 编辑:程序博客网 时间:2024/05/22 23:59

前段时间写了中文分词的一些记录里面提到了CRF的分词方法,近段时间又研究了一下,特把方法写下来,以备忘,另外,李沫南同学优化过CRF++,见:http://www.coreseek.cn/opensource/CRF/我觉得CRF++还有更大的优化空间,以后有时间再搞。


人民日报语料是分好词的,我下面贴出的代码就是把语料整理为CRF需要的训练数据,直接修改模板训练即可。不过有下面的同学给出了更加详细的资料,请各位可以参考:

原始程序确实有一些问题,估计作者没时间修正了,我修改好了楼主的程序并分词成功,并上传了代码和处理好的训练、测试语料:

http://x-algo.cn/index.php/2016/02/27/crf-of-chinese-word-segmentation/ 


1 下载和安装

CRF的概念,请google,我就不浪费资源啦。官方地址如下:http://crfpp.sourceforge.net/

我用的是Ubutnu,所以,下载的是源码:http://sourceforge.net/projects/crfpp/files/ 下载CRF++-0.54.tar.gz

没有gcc/g++/make请安装
% ./configure
% make
% sudo make install

2 测试和体验
在源码包中有example,可以执行./exec.sh体验一下
exec.sh   #训练和测试脚本
template #模板文件
test.data #测试文件
train.data #训练文件
可以打开看看


3 语料整理和模板编写

我采用的是6Tag和6Template的方式
S,单个词;B,词首;E,词尾;M1/M2/M,词中


1个字的词:
和 S
2个字的词(注意是实际上是一个字一行,我为了排版,改为横排的了):
中 B 国 E
3个字的词:
进 B 一 M 步 E
5个字的词:
发 B 展 M1 中 M2 国 M 家 E
跟多字的词
中 B 华 M1 人 M2 民 M 共 M 和 M国 E
标点符号作为单词(S表示)

从bamboo 项目中下载:people-daily.txt.gz
pepoledata.py文件

下载下来并解压,然后用脚本整理数据,注意home_dir改为语料的目录:
python ./peopledata.py 6

90%数据作为训练数据,10%的数据作为测试数据,生成的文件如:
6.test.data
6.train.data

模板文件的写法如下
template:


%x[row,column]代表的是行和列,[-1,0]表示前1个字的第1列,[0,0]当前字的第1列,[1,0]后1个字的第1列

4 执行和结果查看
6exec.sh文件


WordCount from test result: 109805
WordCount from golden data: 109948
WordCount of correct segs : 106145
P = 0.966668, R = 0.965411, F-score = 0.966039

5 调整Tag和模板
4 Tag S/B/M/E 比 6Tag 去掉了M1和M2
python ./peopledata.py 4
4exec.sh文件为

4Tag的效果为
lhb@localhost:~/workspace/CRF_data$ ./crfeval.py 4.test.rst
ordCount from test result: 109844
WordCount from golden data: 109948
WordCount of correct segs : 105985
P = 0.964868, R = 0.963956, F-score = 0.964412

6Tag的效果比4Tag有细微的差距,当然是6Tag好。


6Tag 训练时间为
10062.00s
4tag的训练时间为
4208.71s

6Tag的标注方法差异

1)把M放在E之前:
发 B 展 M1 中 M2 国 M 家 E
2)把M放在B后
发 B 展 M 中 M1 国 M2 家 E
3)把M放在M1和M2之间:
发 B 展 M1 中 M 国 M2 家 E
第1种方式效果最好,有细微的差距。
template的编写

我尝试过12行模板的编写,把词性作为一个计算因素,但是速度实在是很慢,没跑完,我就关机了。效果应该比6 template要好,可以尝试以下。

 

有某位同学问我要crfeval.py文件,特放出如下:

 

 

原创粉丝点击