用MeCab打造自己的分词器(二)

按照用MeCab打造自己的分词器(一)操作,已经安装好了MeCab。

接下来安装指定方式组织语料、词典和配置文件,打造自己的分词系统。

利用backoff2005中微软研究院的中文分词语料来训练一个简单的分词系统,逐步深入完成我们的总目标。

当前目录为$WordSeg,下载微软的语料到当前目录下,解压,并创建msr_mecab_test目录。

~/Project/WordSeg$ ls
icwb2-data  icwb2-data.zip  msr_mecab_test

icwb2-data目录下有如下文件:

~/Project/WordSeg/icwb2-data$ ls
doc  gold  README  scripts  testing  training

其中training目录中存放了训练语料,gold中存放了词典文件

~/Project/WordSeg/icwb2-data/training$ ls
as_training.b5    cityu_training.txt   msr_training.txt   pku_training.txt
as_training.utf8  cityu_training.utf8  msr_training.utf8  pku_training.utf8
~/Project/WordSeg/icwb2-data/gold$ ls
as_testing_gold.txt     cityu_test_gold.txt        msr_test_gold.txt        pku_test_gold.txt
as_testing_gold.utf8    cityu_test_gold.utf8       msr_test_gold.utf8       pku_test_gold.utf8
as_training_words.txt   cityu_training_words.txt   msr_training_words.txt   pku_training_words.txt
as_training_words.utf8  cityu_training_words.utf8  msr_training_words.utf8  pku_training_words.utf8

通过这两个语料可以创建MeCab需要的词典和训练语料,构建我们的模型。还需要配置文件,比如指定特征函数模板、未登录的处理方式等等。

在msr_mecab_test目录下,分别建立三个子目录:seed, final, script:

mkdir seed
mkdir final
mkdir script

~/Project/WordSeg/msr_mecab_test$ ls
final  script  seed


切换进入seed目录。

1、将icwb2-data中提供的词典,转换成MeCab格式。

1123项,0,0,0,0,0,0
义演,0,0,0,0,0,0
佳酿,0,0,0,0,0,0
沿街,0,0,0,0,0,0
老理,0,0,0,0,0,0
三四十岁,0,0,0,0,0,0
解波,0,0,0,0,0,0
统建,0,0,0,0,0,0
蓓蕾,0,0,0,0,0,0
李佑生,0,0,0,0,0,0

它的每一行包括七项特征,详细后表。如果只是分词功能,后面六项都置零就可以了。

2、准备配置文件

    在seed目录下准备5个最基础的配置文件,分别是dicrc, char.def, unk.def, rewrite.def, feature.def。

1) dicrc: 该文件中设定词典的各种动作的,以下为最小配置:

cost-factor = 800
bos-feature = BOS/EOS,*,*,*,*,*,*,*,*
eval-size = 6
unk-eval-size = 4
config-charset = UTF-8

2) char.def: 定义未登陆词处理的文件. 通常日语的词法分析是基于字符的种类处理未登陆词, Mecab 中哪个文字属于哪个字符种类, 用户可以进行细致的指定; 对于每个字符类别, 需要采用哪种未登陆词的识别处理,也可以进行详细的定义。

DEFAULT 0 1 0 # DEFAULT is a mandatory category!
SPACE 0 1 0
CJK 0 0 2

# SPACE
0x0020 SPACE # DO NOT REMOVE THIS LINE, 0x0020 is reserved for SPACE
0x00D0 SPACE
0x0009 SPACE
0x000B SPACE
0x000A SPACE

3) unk.def: 用于未登陆词的词典。

DEFAULT,0,0,0,unk,*,*
SPACE,0,0,0,unk,*,*
CJK,0,0,0,unk,*,*

4) rewrite.def: 定义从特征列到内部状态特征列的转换映射。
[unigram rewrite]
*,*,* $1,$2,$3

[left rewrite]
*,*,* $1,$2,$3

[right rewrite]
*,*,* $1,$2,$3

5) feature.def: 该文件中定义了从内部状态的素生列中抽取CRF的素生列的模板

UNIGRAM W0:%F[6]
UNIGRAM W1:%F[0]/%F[6]
UNIGRAM W2:%F[0],%F?[1]/%F[6]
UNIGRAM W3:%F[0],%F[1],%F?[2]/%F[6]
UNIGRAM W4:%F[0],%F[1],%F[2],%F?[3]/%F[6]

UNIGRAM T0:%t
UNIGRAM T1:%F[0]/%t
UNIGRAM T2:%F[0],%F?[1]/%t
UNIGRAM T3:%F[0],%F[1],%F?[2]/%t
UNIGRAM T4:%F[0],%F[1],%F[2],%F?[3]/%t

BIGRAM B00:%L[0]/%R[0]
BIGRAM B01:%L[0],%L?[1]/%R[0]
BIGRAM B02:%L[0]/%R[0],%R?[1]
BIGRAM B03:%L[0]/%R[0],%R[1],%R?[2]
BIGRAM B04:%L[0],%L?[1]/%R[0],%R[1],%R?[2]
BIGRAM B05:%L[0]/%R[0],%R[1],%R[2],%R?[3]
BIGRAM B06:%L[0],%L?[1]/%R[0],%R[1],%R[2],%R?[3]

3、准备训练语料

msr提供的语料格式是这样的:

人们  常  说  生活  是  一  部  教科书  ,  而  血  与  火  的  战争  更  是  不可多得  的  教科书  ,  她  确实  是  名副其实  的  ‘  我  的  大学  ’  。
“  心  静  渐  知  春  似  海  ,  花  深  每  觉  影  生  香  。
“  吃  屎  的  东西  ,  连  一  捆  麦  也  铡  不  动  呀  ?
他  “  严格要求  自己  ,  从  一个  科举  出身  的  进士  成为  一个  伟大  的  民主主义  者  ,  进而  成为  一  位  杰出  的  党外  共产主义  战士  ,  献身  于  崇高  的  共产主义  事业  。

分词用空格隔开,而MeCab的训练语料和它的词典格式非常相似,每行行首是一个词,然后用tab键隔开,后跟词相关的特征比如词性、发音等等。我们只有分词功能,后面都置零就可以。

人们    0,0,0,0,0,0
常      0,0,0,0,0,0
说      0,0,0,0,0,0
生活    0,0,0,0,0,0
是      0,0,0,0,0,0
一      0,0,0,0,0,0
部      0,0,0,0,0,0
教科书  0,0,0,0,0,0
,      0,0,0,0,0,0
而      0,0,0,0,0,0
血      0,0,0,0,0,0
与      0,0,0,0,0,0
火      0,0,0,0,0,0
的      0,0,0,0,0,0
战争    0,0,0,0,0,0
更      0,0,0,0,0,0
是      0,0,0,0,0,0
不可多得        0,0,0,0,0,0
的      0,0,0,0,0,0
教科书  0,0,0,0,0,0
,      0,0,0,0,0,0
她      0,0,0,0,0,0
确实    0,0,0,0,0,0
是      0,0,0,0,0,0
 

seed目录下多了两个文件分别是corpus、和msr_words.csv

到目前为止,我们需要训练用的词典,配置文件及训练语料已准备就绪:

seed 词典(CSV 格式文件集合)
所有的配置文件 (char.def, unk.def, rewrite.def, feature.def)
训练用的数据 (文件名: corpus)

4、生成训练用的二进制词典

在seed目录下运行以下命令, 生成学习用的二进制词典:

/usr/local/libexec/mecab/mecab-dict-index

也可以通过 -d, -o 选项指定输入输出目录来运行该命令
/usr/local/libexec/mecab/mecab-dict-index -d \$WORK/seed -o \$WORK/seed
-d: 包含seed 词典和配置文件的目录(缺省为当前目录)
-o: 训练用二进制词典的输出目录(缺省为当前目录)

5、CRF模型参数训练

在seed目录下执行如下命令,训练CRF模型:
/usr/local/libexec/mecab/mecab-cost-train -c 1.0 corpus model

可以使用 -d 参数指定使用的词典
/usr/local/libexec/mecab/mecab-cost-train -d \$WORK/seed -c 1.0 \$WORK/seed/corpus \$WORK/seed/model
-d: 包含训练用二进制词典的目录(缺省为当前目录)
-c: CRF的超参数(hyper-parameter)
-f: 特征频率的阈值
-p NUM: 实行NUM个并行训练 (缺省为1)
corpus: 训练数据文件名
model: 输出CRF参数文件名

这个训练过程需要一会儿时间,最终的输出大致如下:

adding virtual node: 0,0,0,0,0,0
adding virtual node: 0,0,0,0,0,0
adding virtual node: 0,0,0,0,0,0
adding virtual node: 0,0,0,0,0,0
...
Number of sentences: 86918
Number of features: 28
eta: 0.00005
freq: 1
eval-size: 6
unk-eval-size: 4
threads: 1
charset: EUC-JP
C(sigma^2): 1.00000

iter=0 err=0.29595 F=0.94870 target=2267078.26396 diff=1.00000
iter=1 err=0.13623 F=0.97665 target=1056367.13470 diff=0.53404
iter=2 err=0.13849 F=0.97610 target=1005496.50043 diff=0.04816
iter=3 err=0.14630 F=0.97388 target=924449.25300 diff=0.08060
iter=4 err=0.13693 F=0.97643 target=891815.15638 diff=0.03530
iter=5 err=0.13537 F=0.97672 target=869032.52748 diff=0.02555
iter=6 err=0.11850 F=0.98127 target=854787.02218 diff=0.01639
iter=7 err=0.10803 F=0.98411 target=845031.70611 diff=0.01141
iter=8 err=0.08712 F=0.98848 target=838863.46990 diff=0.00730
iter=9 err=0.07940 F=0.99001 target=835481.49751 diff=0.00403
iter=10 err=0.07276 F=0.99114 target=833719.13204 diff=0.00211
iter=11 err=0.06556 F=0.99263 target=833462.32905 diff=0.00031
iter=12 err=0.06569 F=0.99258 target=831886.20533 diff=0.00189
iter=13 err=0.06568 F=0.99259 target=831739.11465 diff=0.00018
iter=14 err=0.06559 F=0.99262 target=831643.59710 diff=0.00011
iter=15 err=0.06531 F=0.99266 target=831599.69205 diff=0.00005
iter=16 err=0.06502 F=0.99274 target=831544.40251 diff=0.00007
iter=17 err=0.06480 F=0.99279 target=831518.14668 diff=0.00003
iter=18 err=0.06475 F=0.99280 target=831504.33361 diff=0.00002
iter=19 err=0.06470 F=0.99281 target=831502.92263 diff=0.00000

Done! writing model file ...

6、生成用于发布的词典

在seed目录下执行:

/usr/local/libexec/mecab/mecab-dict-gen -o ../final -m model

model is not a binary model. reopen it as text mode...
reading ./unk.def ... 3
reading ./msr_words.csv ... 88119
emitting ../final/left-id.def/ ../final/right-id.def
emitting ../final/unk.def ... 3
emitting ../final/msr_words.csv ... 88119
emitting matrix : 100% |###########################################|
emitting matrix : 133% |########################################### copying ./char.def to ../final/char.def
copying ./rewrite.def to ../final/rewrite.def
copying ./dicrc to ../final/dicrc
copying ./feature.def to ../final/feature.def
copying model to ../final/model.def

done!

也可以使用 -d -o 选项指定词典
/usr/local/libexec/mecab/mecab-dict-gen -o \$WORK/final -d \$WORK/seed -m \$WORK/seed/model
-d: 包含seed 词典和配置文件的目录(缺省为当前目录)
-o: 用于发布的词典的输出目录
-m: CRF 的参数文件
用于发布的词典, 必须输出到和 seed 词典不同的目录,通常把包含发布词典的 final 目录打包之后用于发布 .

7、生成用于解析器的词典
进入到final目录下
cd ../final
执行
/usr/local/libexec/mecab/mecab-dict-index

reading ./unk.def ... 3
emitting double-array: 100% |###########################################|
./pos-id.def is not found. minimum setting is used
reading ./msr_words.csv ... 88119
emitting double-array: 100% |###########################################|
reading ./matrix.def ... 3x3
emitting matrix : 100% |###########################################|

done!

也可以使用 -d -o 选项指定词典
usr/local/libexec/mecab/mecab-dict-index -d \$WORK/final -o \$WORK/final
-d: 包含seed 词典和配置文件的目录(缺省为当前目录)
-o: 用于解析器的二进制词典的输出目录(缺省为当前目录)

至此,MeCab中文分词所需的词典和模型文件准备就绪,都在final目录下,可以测试一下,回到上一层目录(cd ..),然后执行

/WordSeg/msr_mecab_test$ mecab -d ./final/

请介绍信托基金的情况

请    0,0,0
介绍信    0,0,0
托    0,0,0
基金    0,0,0
的    0,0,0
情况    0,0,0
EOS

输出的结果。看到它把“信托”分开了。信托基金是金融领域的常用词。可见语料和词典中没有覆盖金融领域词。这也是为什么要有自己的分词系统的缘故。
 

你可能感兴趣的:(自然语言处理)