IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    52nlp发表于 2015-04-28 13:59:14
    love 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,一個
    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

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

    相关文章:

    1. 用MeCab打造一套实用的中文分词系统(二)
    2. 用MeCab打造一套实用的中文分词系统
    3. 日文分词器 Mecab 文档
    4. abcNLP: AB-Natural Chinese Languange Processing
    5. 中文分词入门之最大匹配法扩展2
    6. Python自然语言处理实践: 在NLTK中使用斯坦福中文分词器
    7. 中文分词入门之字标注法2
    8. 中文分词入门之资源
    9. Itenyh版-用HMM做中文分词四:A Pure-HMM 分词器
    10. 中文分词入门之字标注法4



沪ICP备19023445号-2号
友情链接