我在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,一個
mecab unk,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/unk\s eos-format-pos = \n ; pinyin node-format-pinyin = %m/%f[5]\s unk-format-pinyin = %m/unk\s eos-format-pinyin = \n ; fan node-format-fan = %m/%f[6]\s unk-format-fan = %m/unk\s 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.result 3637 1643 4969 10249 104372 106366 0.937 0.919 0.928 0.058 0.495 0.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.def 和 unk.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