聚合国内IT技术精华文章,分享IT技术精华,帮助IT从业人士成长

用MeCab打造一套实用的中文分词系统(三):MeCab-Chinese

2015-04-29 12:00 浏览: 6521 次 我要评论(0 条) 字号:

我在Github上发布了一个MeCab中文分词项目: MeCab-Chinese , 目的是提供一个用于中文分词和词性标注的MeCab词典和模型数据,类似MeCab日文IPA词典(mecab-ipadic),并且提供一些我自己用到的特征模板和脚本,方便大家从源头开始训练一个MeCab中文分词系统。

自从上次在愚人节的时候发布了一个mecab中文词典和数据模型之后(《用MeCab打造一套实用的中文分词系统(二)》), 收到了一些反馈,而这些反馈又促使我深入的review了一下mecab,重新设计特征及特征模板,加入了一些新的词典数据,重新训练模型,感兴趣的同学可以先试试这个0.2版本: mecab-chinesedic-binary (链接: http://pan.baidu.com/s/1gdxnvFX 密码: kq9g)
注:目前所有发布的版本均默认utf-8编码,并且在Mac OS和Linux Ubuntu下测试有效,windows没有测试,感兴趣的同学可自行测试)

了解和安装mecab仍请参考:
日文分词器 Mecab 文档
用MeCab打造一套实用的中文分词系统

这里再补充一点,由于google code废弃的缘故,MeCab这个项目已经搬迁至github,但是一些资源反而不如之前那么好找了,可参考两个MeCab作者维护的页面:
MeCab日文文档: http://taku910.github.io/mecab/
MeCab github 页面:https://github.com/taku910/mecab

MeCab目前最新的版本是2013-02-18更新的MeCab 0.996,我在Mac OS和Linux Ubuntu下用的是这个版本,在MeCab-Chinese下,做了一个备份,感兴趣的同学可以从这里下载: MeCab 0.996

在安装完毕MeCab之后,请下载这个模型词典数据,解压之后,可以这样执行:
mecab -d mecab-chinesedic-binary
自从上次在愚人节的时候发布了一个mecab中文词典和数据模型之后
自从p,p,BE,2,自从,zi_cong,自從
上次t,t,BE,2,上次,shang_ci,上次
在p,p,S,1,在,zai,在
愚人n,n,BE,2,愚人,yu_ren,愚人
节n,n,S,1,节,jie,節
的u,u,S,1,的,de,的
时候n,n,BE,2,时候,shi_hou,時候
发布v,v,BE,2,发布,fa_bu,發佈
了u,u,S,1,了,le,了
一个m,m,BE,2,一个,yi_ge,一個
mecabunk,unk,*,*,*,*,*
中文n,nz,BE,2,中文,zhong_wen,中文
词典n,n,BE,2,词典,ci_dian,詞典
和c,c,S,1,和,he,和
数据n,n,BE,2,数据,shu_ju,數據
模型n,n,BE,2,模型,mo_xing,模型
之后f,f,BE,2,之后,zhi_hou,之後
EOS

如果想得到单行的中文分词输出结果,可以这样执行:
mecab -d mecab-chinesedic-binary -O wakati
自从上次在愚人节的时候发布了一个mecab中文词典和数据模型之后
自从 上次 在 愚人 节 的 时候 发布 了 一个 mecab 中文 词典 和 数据 模型 之后

如果想得到词性标注的输出结果,可以这样执行:
mecab -d mecab-chinesedic-binary -O pos
自从上次在愚人节的时候发布了一个mecab中文词典和数据模型之后
自从/p 上次/t 在/p 愚人/n 节/n 的/u 时候/n 发布/v 了/u 一个/m mecab/unk 中文/nz 词典/n 和/c 数据/n 模型/n 之后/f

注意词性标记可以参考:《现代汉语语料库加工规范——词语切分与词性标注》。

由于增加了拼音和繁体两个特征,这里还有两个副产品可以输出,一个是输出中文分词之后的对应拼音:
mecab -d mecab-chinesedic-binary -O pinyin
自从上次在愚人节的时候发布了一个mecab中文词典和数据模型之后
自从/zi_cong 上次/shang_ci 在/zai 愚人/yu_ren 节/jie 的/de 时候/shi_hou 发布/fa_bu 了/le 一个/yi_ge mecab/unk 中文/zhong_wen 词典/ci_dian 和/he 数据/shu_ju 模型/mo_xing 之后/zhi_hou

另外一个是输出中文分词之后简体词到繁体词的转换:
mecab -d mecab-chinesedic-binary -O fan
自从上次在愚人节的时候发布了一个mecab中文词典和数据模型之后
自从/自從 上次/上次 在/在 愚人/愚人 节/節 的/的 时候/時候 发布/發佈 了/了 一个/一個 mecab/unk 中文/中文 词典/詞典 和/和 数据/數據 模型/模型 之后/之後

因为之前有同学留言如何输出词性标记,这个输出时可以指定格式或者在dicrc里面自定义,所以我在这个版本的dicrc里加了上述三种类型的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cost-factor = 800
bos-feature = BOS/EOS,*,*,*,*,*,*
eval-size = 7
unk-eval-size = 4
config-charset = UTF-8

; pos
node-format-pos = %m/%f[1]s
unk-format-pos = %m/unks
eos-format-pos  = n

; pinyin
node-format-pinyin = %m/%f[5]s
unk-format-pinyin = %m/unks
eos-format-pinyin  = n

; fan
node-format-fan = %m/%f[6]s
unk-format-fan = %m/unks
eos-format-fan  = n

感兴趣的同学可以参考《日文分词器 Mecab 文档》里第四节关于输出格式的一些说明。

在backoff2005 人民日报语料库上的测试结果:

=== SUMMARY:
=== TOTAL INSERTIONS:3637
=== TOTAL DELETIONS:1643
=== TOTAL SUBSTITUTIONS:4969
=== TOTAL NCHANGE:10249
=== TOTAL TRUE WORD COUNT:104372
=== TOTAL TEST WORD COUNT:106366
=== TOTAL TRUE WORDS RECALL:0.937
=== TOTAL TEST WORDS PRECISION:0.919
=== F MEASURE:0.928
=== OOV Rate:0.058
=== OOV Recall Rate:0.495
=== IV Recall Rate:0.964
###pku_test.result363716434969102491043721063660.9370.9190.9280.0580.4950.964

召回率93.7%,准确率91.9%, F值为92.8%, 比上一个版本略好一些,另外感兴趣的同学也可以通过这个版本的中文分词Demo 进行测试。

==============================================================

如果觉得仅仅使用MeCab进行中文分词和词性标注还不过瘾,想自己train一个mecab分词所用的模型和词典,那么可以继续。之前在这里写过一篇《用MeCab打造一套实用的中文分词系统》 ,但是回过头来再看,其实问题多多,特别是特征模板这块儿,有很多歉考虑的地方,不过整个套路应该是没问题的,所以依然有一定的参考价值。

这个版本里定义了7个特征:
*词性1级分类(其实仅仅为了方便,取词性标记首字母而已)
*词性2(这是真实的词性)
*字标注tag(BEMS)
*中文词字数
*中文词基本型
*拼音
*繁体

所以训练语料需转换为如下的形式:

1
2
3
4
5
6
7
中文  n,nz,BE,2,中文,zhong_wen,中文
词典  n,n,BE,2,词典,ci_dian,詞典
和 c,c,S,1,和,he,和
数据  n,n,BE,2,数据,shu_ju,數據
模型  n,n,BE,2,模型,mo_xing,模型
之后  f,f,BE,2,之后,zhi_hou,之後
EOS

而词典文件需转换为如下的形式:

1
2
3
4
5
6
中文,0,0,0,n,nz,BE,2,中文,zhong_wen,中文
词典,0,0,0,n,n,BE,2,词典,ci_dian,詞典
和,0,0,0,c,c,S,1,和,he,和
数据,0,0,0,n,BE,2,数据,shu_ju,數據
模型,0,0,0,n,n,BE,2,模型,mo_xing,模型
之后,0,0,0,f,f,BE,2,之后,zhi_hou,之後

关于这个版本对应的配置文件可以在MeCab-Chinese上查看, 其中dicrc和上述一致,这里就不说了。这里分别说一下几个配置文件。

char.defunk.def 用于未登录词的处理,这里基本复用了mecab日文ipadic里的两个文件,做了少许修改:

1
2
3
4
5
6
7
8
9
10
11
DEFAULT,0,0,0,unk,unk,*,*,*,*,*
SPACE,0,0,0,unk,unk,*,*,*,*,*
KANJI,0,0,0,unk,unk,*,*,*,*,*
SYMBOL,0,0,0,unk,unk,*,*,*,*,*
NUMERIC,0,0,0,unk,unk,*,*,*,*,*
ALPHA,0,0,0,unk,unk,*,*,*,*,*
HIRAGANA,0,0,0,unk,unk,*,*,*,*,*
GREEK,0,0,0,unk,unk,*,*,*,*,*
CYRILLIC,0,0,0,unk,unk,*,*,*,*,*
KANJINUMERIC,0,0,0,unk,unk,*,*,*,*,*
KATAKANA,0,0,0,unk,unk,*,*,*,*,*

rewrite.def, 做了最小化的精简:

1
2
3
4
5
6
7
8
[unigram rewrite]
*,*,*,*,*,*,* $1,$2,$3,$4,$5,$6,$7

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

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

feature.def是crf特征模板,重新基于特征定义了一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# POS Unigram
UNIGRAM U1:%F[0]
UNIGRAM U2:%F[0],%F?[1]
UNIGRAM U3:%F[0],%F[1],%F[2]

# Word-POS
UNIGRAM W0:%F[4]
UNIGRAM W1:%F[0]/%F[4]
UNIGRAM W2:%F[1]/%F[4]
UNIGRAM W3:%F[2]/%F[4]
UNIGRAM W4:%F[0],%F?[1]/%F[4]
UNIGRAM W5:%F[1],%F?[2]/%F[4]
UNIGRAM W6:%F[0],%F[1],%F?[2]/%F[4]

# Word-Freq
UNIGRAM WF0:%F[3]
UNIGRAM WF1:%F[3]/%F[4]

# POS-Freq
UNIGRAM PF1:%F[0]/%F[3]
UNIGRAM PF2:%F[1]/%F[3]
UNIGRAM PF3:%F[0],%F?[1]/%F[3]
UNIGRAM PF4:%F[1],%F?[2]/%F[3]
UNIGRAM PF5:%F[0],%F[1],%F?[2]/%F[3]

# Read-POS
UNIGRAM RP0:%F[5]
UNIGRAM RP1:%F[0]/%F[5]
UNIGRAM RP2:%F[1]/%F[5]
UNIGRAM RP3:%F[2]/%F[5]
UNIGRAM RP4:%F[0],%F?[1]/%F[5]
UNIGRAM RP5:%F[1],%F?[2]/%F[5]
UNIGRAM RP6:%F[0],%F[1],%F?[2]/%F[5]

# Fan-POS
UNIGRAM RP0:%F[6]
UNIGRAM RP1:%F[0]/%F[6]
UNIGRAM RP2:%F[1]/%F[6]
UNIGRAM RP3:%F[2]/%F[6]
UNIGRAM RP4:%F[0],%F?[1]/%F[6]
UNIGRAM RP5:%F[1],%F?[2]/%F[6]
UNIGRAM RP6:%F[0],%F[1],%F?[2]/%F[6]

# Word-Read-POS
UNIGRAM R1:%F[4],%F[5]
UNIGRAM R2:%F[0],%F[4],%F[5]
UNIGRAM R3:%F[1],%F[4],%F[5]
UNIGRAM R4:%F[2],%F[4],%F[5]
UNIGRAM R5:%F[0],%F?[1],%F[4],%F[5]
UNIGRAM R6:%F[1],%F?[2],%F[4],%F[5]
UNIGRAM R7:%F[0],%F[1],%F?[2],%F[4],%F[5]

# Word-Fan-POS
UNIGRAM F1:%F[4],%F[6]
UNIGRAM F2:%F[0],%F[4],%F[6]
UNIGRAM F3:%F[1],%F[4],%F[6]
UNIGRAM F4:%F[2],%F[4],%F[6]
UNIGRAM F5:%F[0],%F?[1],%F[4],%F[6]
UNIGRAM F6:%F[1],%F?[2],%F[4],%F[6]
UNIGRAM F7:%F[0],%F[1],%F?[2],%F[4],%F[6]

# char type
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
UNIGRAM T5:%F[0],%F[1],%F[2],%F[3],%F[4]/%t

#
# bigram
#

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]
BIGRAM B07:%L[0],%L[1],%L?[2]/%R[0]
BIGRAM B08:%L[0],%L[1],%L?[2]/%R[0],%R?[1]
BIGRAM B09:%L[0],%L[1],%L[2],%L?[3]/%R[0]
BIGRAM B10:%L[0],%L[1],%L[2],%L?[3]/%R[0],%R?[1]
BIGRAM B11:%L[0],%L[1],%L?[2]/%R[0],%R[1],%R?[2]
BIGRAM B12:%L[0],%L[1],%L?[2]/%R[0],%R[1],%R[2],%R?[3]
BIGRAM B13:%L[0],%L[1],%L[2],%L?[3]/%R[0],%R[1],%R?[2]

最后提供两个脚本,你只需按如下形式准备词典和训练语料即可:

词典格式:中文词/中文词性标记(这里不限制使用某个特定的词性标记), 例如:
中文/n
词典/n
和/c
数据/n
模型/n

语料格式:带词性标注即可
中文/n 词典/n 和/c 数据/n 模型/n

具体可以参考script的两个脚本文件: make_mecab_seed_data.py 和 make_mecab_train_data.py

注意,这里用的是这个汉字到拼音的转换方案,使用脚本前需要先安装: https://github.com/cleverdeng/pinyin.py

另外汉字简体到繁体的转换代码已经拷贝和数据已经放到script目录下,不需要安装了,这个来源于:https://github.com/skydark/nstools

执行上述两个脚本的时候都需要在script目录下执行,需要load一些数据。

ok,MeCab-Chinese的一些介绍就到此为止了,欢迎大家一起参与共建MeCab-Chinese。

注:原创文章,转载请注明出处“我爱自然语言处理”:www.52nlp.cn

本文链接地址:用mecab打造一套实用的中文分词系统三:mecab-chinese



网友评论已有0条评论, 我也要评论

发表评论

*

* (保密)

Ctrl+Enter 快捷回复