用MeCab打造一套实用的中文分词系统

Deep Learning Specialization on Coursera

MeCab是一套日文分词(形态分析)和词性标注系统(Yet Another Part-of-Speech and Morphological Analyzer), rick曾经在这里分享过MeCab的官方文档中文翻译: 日文分词器 Mecab 文档,这款日文分词器基于条件随机场打造,有着诸多优点,譬如代码基于C++实现,基本内嵌CRF++代码,词典检索的算法和数据结构均使用双数组Double-Array,性能优良,并通过SWIG提供多种语言调用接口,可扩展性和通用性都非常不错:

mecab (http://mecab.sourceforge.net/) 是奈良先端科学技術大学院的工藤拓开发的日文分词系统, 该作者写过多个 machine learning 方面的软件包, 最有名的就是 CRF++, 目前该作者在 google@Japan 工作。

mecab 是基于CRF 的一个日文分词系统,代码使用 c++ 实现, 基本上内嵌了 CRF++ 的代码, 同时提供了多种脚本语言调用的接口(python, perl, ruby 等).整个系统的架构采用通用泛化的设计,用户可以通过配置文件定制CRF训练中需要使用的特征模板。 甚至, 如果你有中文的分词语料作为训练语料,可以在该架构下按照其配置文件的规范定制一个中文的分词系统。

日文NLP 界有几个有名的开源分词系统, Juman, Chasen, Mecab. Juman 和 Chasen 都是比较老的系统了, Mecab 系统比较新, 在很多方面都优于 Juman 和 Chasen, mecab 目前开发也比较活跃。 Mecab 虽然使用 CRF 实现, 但是解析效率上确相当高效, 据作者的介绍, Mecab 比基于 HMM 的 Chasen 的解析速度要快。 笔者在一台 Linux 机器上粗略测试过其速度,将近达到 2MB/s, 完全达到了工程应用的需求, 该系统目前在日文 NLP 界被广泛使用。

我们曾经介绍过一个非常初级的CRF中文分词实现方案:中文分词入门之字标注法4,基于CRF++实现了一个Toy级别的CRF中文分词系统,但是还远远不够。在仔细看过这篇日文分词系统MeCab的中文文档并亲测之后,不得不赞这真是一个理想的CRF分词系统,除了上述所说的优点之外,在使用上它还支持Nbest输出,多种输出格式,全切分模式,系统词典和用户词典定制等等,难怪这套分词系统在日本NLP界被广泛使用。

MeCab的诸多优点以及它的通用性一直深深吸引着我,但是除了日文资料,相关的中文或英文资料相当匮乏,曾经尝试过基于MeCab的中文翻译文档以及代码中测试用例中的例子来训练一套中文分词系统,但是第一次以失败告终。这几天,由于偶然的因素又一次捡起了MeCab,然后通过Google及Google翻译发现了这篇日文文章《MeCabで中国語の形態素解析(分かち書き)をしてみる》,虽其是日语所写,但是主旨是通过MeCab构造一套中文(貌似是繁体)形态(中文分词+词性标注)分析系统,给了我很大的帮助。所以接下来,我会基于这篇文章的提示以及rick翻译文档中第八节“从原始词典/语料库做参数估计”的参考,同时结合backoff2005中微软研究院的中文分词语料来训练一套极简的中文分词系统,至于MeCab的相关介绍及安装使用请参考 日文分词器 Mecab 文档,这里不再赘述。以下是我在Mac OS下的操作记录,同理可推广制Linux下,至于Windows下,请自行测试。一些中文分词的背景知识可参考这里过往的相关文章: 中文分词

0、首先在和SIGHAN backoff2005的相关语料icwb2-data的同层次目录里建立一个msr_mecab_test目录:

mkdir msr_mecab_test
cd msr_mecab_test

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

mkdir seed
mkdir final
mkdir script

1、准备Seed 词典

MeCab 的词典是 CSV 格式的. Seed 词典和用于发布的词典的格式基本上是相同的 .

以下是词典的词条条目的例子 .

進学校,0,0,0,名詞,一般,*,*,*,*,進学校,シンガクコウ,シンガクコー
梅暦,0,0,0,名詞,一般,*,*,*,*,梅暦,ウメゴヨミ,ウメゴヨミ
気圧,0,0,0,名詞,一般,*,*,*,*,気圧,キアツ,キアツ
水中翼船,0,0,0,名詞,一般,*,*,*,*,水中翼船,スイチュウヨクセン,スイチューヨクセン
前面4个字段是必须的,

表层形(词条本身)
左连接状态号
右连接状态号
cost

我们的词典源来自于icwb2-data/gold/msr_training_words.utf8,由于不含词性等其他信息,这里我们提供一个非常简单的Seed 词条格式,如下所示:
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

这里提供一个python脚本用于制作seed词典: make_mecab_seed_data.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2015 @ YuZhen Technology
 
import codecs
import sys
 
def make_mecab_seed_data(input_file, output_file):
    input_data = codecs.open(input_file, 'r', 'utf-8')
    output_data = codecs.open(output_file, 'w', 'utf-8')
    for line in input_data.readlines():
        word = line.strip()
        output_data.write(word+ ",0,0,0,0,0,0\n")
    input_data.close()
    output_data.close()
 
if __name__ == '__main__':
    if len(sys.argv) < 3:
        print "pls use: python make_mecab_seed_data.py input output"
        sys.exit()
    input_file = sys.argv[1]
    output_file = sys.argv[2]
    make_mecab_seed_data(input_file, output_file)

可以将这个脚本拷贝到script目录下,然后进入到seed目录,执行 python ../script/make_mecab_seed_data.py ../../icwb2-data/gold/msr_training_words.utf8 msr_words.csv 即可得到MeCab所需的Seed词典。

2、准备配置文件
在seed目录下准备5个最基础的配置文件,分别是dicrc, char.def, unk.def, rewrite.def, feature.def , 这5个配置文件我主要参考自上述那篇日文文章,略作修改,其具体解释可参考中文翻译文档中的详细描述:

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、准备训练语料

用于训练的数据, 和 MeCab 的输出是相同格式的,

太郎 名詞,固有名詞,人名,名,*,*,太郎,タロウ,タロー
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
花子 名詞,固有名詞,人名,名,*,*,花子,ハナコ,ハナコ
が 助詞,格助詞,一般,*,*,*, が,ガ,ガ
好き 名詞,形容動詞語幹,*,*,*,*, 好き,スキ,スキ
だ 助動詞,*,*,*, 特殊・ダ,基本形,だ,ダ,ダ
. 記号,句点,*,*,*,*, . , . , .
EOS
焼酎 名詞,一般,*,*,*,*,焼酎,ショウチュウ,ショーチュー
好き 名詞,形容動詞語幹,*,*,*,*,好き,スキ,スキ
の 助詞,連体化,*,*,*,*, の,ノ,ノ
親父 名詞,一般,*,*,*,*,親父,オヤジ,オヤジ
. 記号,句点,*,*,*,*, . , . , .
EOS
...
Tab 键分隔的第一个部分为词条表层文字, 随后是CSV 格式的特征列, 句子结束标志为 只包行EOS的行.

我们的中文分词训练语料来源于icwb2-data/training/msr_training.utf8 ,和词典格式一样,我们提供一份格式非常简单的用于MeCab训练的分词语料,如下所示:

“ 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

同样提供一个可用于语料格式转换的脚本:make_mecab_train_data.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2015 @ YuZhen Technology
 
import codecs
import sys
 
def make_mecab_train_data(input_file, output_file):
    input_data = codecs.open(input_file, 'r', 'utf-8')
    output_data = codecs.open(output_file, 'w', 'utf-8')
    for line in input_data.readlines():
        word_list = line.strip().split()
        if len(word_list) == 0: continue
        for word in word_list:
            output_data.write(word+ "\t0,0,0,0,0,0\n")
        output_data.write("EOS\n")
    input_data.close()
    output_data.close()
 
if __name__ == '__main__':
    if len(sys.argv) < 3:
        print "pls use: python make_mecab_train_data.py input output"
        sys.exit()
    input_file = sys.argv[1]
    output_file = sys.argv[2]
    make_mecab_train_data(input_file, output_file)

可将其拷贝到script目录下,然后执行 python ../script/make_mecab_train_data.py ../../icwb2-data/training/msr_training.utf8 corpus 即可。

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

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

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

在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: 训练用二进制词典的输出目录(缺省为当前目录)

执行过程如下:

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

done!

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 ..),然后执行

mecab -d ./final/

让MeCab加载中文分词所需的相关词典文件,待加载完毕,输入一行中文句子:

扬帆远东做与中国合作的先行

回车后我们得到逐行的分词结果,和输入的训练文件格式相似:

扬帆 0,0,0
远东 0,0,0
做 0,0,0
与 0,0,0
中国 0,0,0
合作 0,0,0
的 0,0,0
先行 0,0,0
EOS

如果想得到NBest的输出结果,可以这样执行:

mecab -d ./final/ -N2
扬帆远东做与中国合作的先行
扬帆 0,0,0
远东 0,0,0
做 0,0,0
与 0,0,0
中国 0,0,0
合作 0,0,0
的 0,0,0
先行 0,0,0
EOS
扬帆 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
EOS

如果想得到单行的分词结果,可以这样执行:

mecab -d ./final/ -O wakati
扬帆远东做与中国合作的先行
扬帆 远东 做 与 中国 合作 的 先行

如果想直接对文件分词,可以这样执行:

mecab -d ./final/ INPUT -o OUTPUT

基于以上信息,我们可以利益backoff2005的评估脚本来评估本次分词的结果,首先利用mecab对msr的测试文件进行中文分词:

mecab -d ./final/ -O wakati ../icwb2-data/testing/msr_test.utf8 -o msr_test.mecab

然后用测试脚本来评估MeCab的中文分词结果文件msr_test.mecab的准确率和召回率,执行:

../icwb2-data/scripts/score ../icwb2-data/gold/msr_training_words.utf8 ../icwb2-data/gold/msr_test_gold.utf8 msr_test.mecab > msr_test.mecab.score

最终的结果如下:
=== SUMMARY:
=== TOTAL INSERTIONS: 4984
=== TOTAL DELETIONS: 474
=== TOTAL SUBSTITUTIONS: 4828
=== TOTAL NCHANGE: 10286
=== TOTAL TRUE WORD COUNT: 106873
=== TOTAL TEST WORD COUNT: 111383
=== TOTAL TRUE WORDS RECALL: 0.950
=== TOTAL TEST WORDS PRECISION: 0.912
=== F MEASURE: 0.931
=== OOV Rate: 0.026
=== OOV Recall Rate: 0.000
=== IV Recall Rate: 0.976
### msr_test.mecab 4984 474 4828 10286 106873 111383 0.950 0.912 0.931 0.026 0.000 0.976

我们得到一个准确率91.2%,召回率95%,F值为93.1%的中文分词器。当然,这只是一个初步测试,还有许多工作要做,譬如添加词典,添加语料,设计特征模板等等。

我们再说一下如何在Python中调用MeCab进行中文分词,其他各种语言的绑定的安装方法参见 perl/README, ruby/README, python/README, java/README),写得很清楚。首先下载mecab-python-0.996.tar.gz,一路解压安装,安装成功后打开python解释器,这里使用ipython:

In [1]: import sys

In [2]: import MeCab

In [3]: m = MeCab.Tagger("-d ./final/ -O wakati")

In [4]: m.parse("扬帆远东做与中国合作的先行")
Out[4]: '\xe6\x89\xac\xe5\xb8\x86 \xe8\xbf\x9c\xe4\xb8\x9c \xe5\x81\x9a \xe4\xb8\x8e \xe4\xb8\xad\xe5\x9b\xbd \xe5\x90\x88\xe4\xbd\x9c \xe7\x9a\x84 \xe5\x85\x88\xe8\xa1\x8c \n'

In [5]: print m.parse("扬帆远东做与中国合作的先行")
扬帆 远东 做 与 中国 合作 的 先行

最后再说一下之所以说实用,并不是说马上给出一个实用的中文分词系统,而是在这个通用的分词框架下,我们可以做很多有趣的事情和测试,最终定制属于我们自己的实用的中文分词和词性标注系统,也欢迎大家一起来探索。

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

本文链接地址:http://www.52nlp.cn/用mecab打造一套实用的中文分词系统

Deep Learning Specialization on Coursera

用MeCab打造一套实用的中文分词系统》上有39条评论

  1. cathy

    您好,我现在要在一篇分好词的文档中统计比如word1出现的条件下word2出现的次数 应该怎么编程啊?python中有没有关于这个的函数?

    [回复]

  2. Janvn

    请问下大家为什么我用训练CRF模型时,进行到../mecab-cost-train -c 1.0 corpus model时,执行mecab-cost-train程序后,进行到一半时,老是中断啊。故障模块名称: libmecab.dll。请教下大家怎么解决这个问题?

    [回复]

  3. Janvn

    请教下,为什么我进行CRF模型训练时,../mecab/mecab-cost-train -c 1.0 corpus model,出现程序执行到一半的时候,自动中断, 故障模块名称: libmecab.dll。有碰到过这样的问题吗?纠结了好久不知道怎么解决。希望大家帮我解决下这个问题。谢谢!

    [回复]

    52nlp 回复:

    你这个是在windows下训练的吧?有具体报错信息吗?仅仅这个dll说明不了什么问题

    [回复]

    Janvn 回复:

    恩,是的,现在我打算在mac上重新跑下,你有没有对应mac版本的mecab啊?

    [回复]

    Janvn 回复:

    我后来使用了非常少的corpus去训练到时能跑出结果,是不是和corpus的量有关,导致程序崩溃?

    52nlp 回复:

    mecab很耗内存,有可能就是内存满了挂掉了;mac版本就是linux版本,按linux方法编译一下就可以了

    Janvn 回复:

    好的,谢谢!

    [回复]

  4. Janvn

    感谢楼主详细的文档说明,终于走通了整个流程。

    [回复]

    52nlp 回复:

    客气,后面加feature才是一个更有意思的环节

    [回复]

  5. 严力

    我在windows上训练的时候也出错了,不知道为什么

    D:\MeCab\dic\ipadic>mecab-cost-train.exe -c 1.0 corpus model
    reading corpus ...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
    adding virtual node: 0,0,0,0,0,0
    adding virtual node: 0,0,0,0,0,0
    feature_index.cpp(238) [rewrite_.rewrite2(path->rnode->feature, &ufeature2, &lfe
    ature2, &rfeature2)] cannot rewrite pattern: 0,0,0,0,0,0

    [回复]

  6. 严力

    我在windows上训练的时候也出错了,不知道为什么
    人们 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
    EOS

    D:\MeCab\dic\ipadic>mecab-cost-train.exe -c 1.0 corpus model
    reading corpus ...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
    adding virtual node: 0,0,0,0,0,0
    adding virtual node: 0,0,0,0,0,0
    feature_index.cpp(238) [rewrite_.rewrite2(path->rnode->feature, &ufeature2, &lfe
    ature2, &rfeature2)] cannot rewrite pattern: 0,0,0,0,0,0

    [回复]

    dustleon 回复:

    我也遇到这个问题,请问是怎么解决的?

    [回复]

  7. allen

    在seed目录下运行以下命令, 生成学习用的二进制词典:
    /usr/local/libexec/mecab/mecab-dict-index

    请问下我卡在这里一直不动是怎么回事?
    AllendeMacBook-Pro:seed Allen$ pwd
    /Users/Allen/backoff2005/msr_mecab_test/seed
    AllendeMacBook-Pro:seed Allen$ ls
    char.bin corpus feature.def rewrite.def
    char.def dicrc msr_words.csv unk.def
    AllendeMacBook-Pro:seed Allen$ /usr/local/libexec/mecab/mecab-dict-index

    [回复]

  8. allen

    您好:
    我在执行 AllendeMacBook-Pro:seed Allen$ /usr/local/libexec/mecab/mecab-dict-index
    这个命令的时候一直卡主不动,已经准备好了seed 词典(CSV 格式文件集合)
    所有的配置文件 (char.def, unk.def, rewrite.def, feature.def)
    训练用的数据 (文件名: corpus)这些文件,请问是什么原因,谢谢!

    [回复]

  9. SamaelChen

    用楼主的方法训练完,无法识别中文的逗号是为什么?
    原文输入是:
    最后再说一下之所以说实用,不是说。
    分词的结果如下:
    最后 再 说 一 下 之所以 说 实用 �� �不�� �说 。

    [回复]

  10. SamaelChen

    在ubuntu下按照楼主的方法训练完无法识别中文的逗号是什么原因?只要有中文逗号就会出现无法识别的字符
    输入文字如下:
    最后再说一下之所以说实用,不是说。
    分词结果如下:
    最后 再 说 一 下 之所以 说 实用 �� �不�� �说 。

    [回复]

    52nlp 回复:

    第一个版本可能存在一些问题,估计和char.def和unk.def里的定义有关,可以考虑复用后面几个版本里的一些定义,处理特殊字符和未登录词。后面的几个版本比较完善,可以继续读一下,也可以试试我们当前版本的demo,这个问题已不存在:
    http://www.52nlp.com/zhong-wen-fen-ci

    [回复]

    SamaelChen 回复:

    我是用的github上面放出来的那个版本,词典和语料都是按照第三篇文章准备的

    [回复]

    52nlp 回复:

    抱歉,这个不太清楚,你直接用我这边提供的词典和模型在ubuntu下试试有没有问题?如果没有问题的话可能和你的训练数据有关

    SamaelChen 回复:

    原因我找到了,是因为我所有的训练文件用的都是utf8编码,而生成词典的时候mecab默认实用EUC-JP,所以出错了,只要用/usr/local/libexec/mecab/mecab-dict-index -f utf8 -t utf8就可以了

    52nlp 回复:

    ok

  11. SamaelChen

    楼主词典里面是不是把标点符号也放进去了?!

    [回复]

    52nlp 回复:

    是的,从训练集里生成了一份词典,含标点符号及其标注

    [回复]

  12. AndyJi

    您好,我按照您的教程跑了一下,发现最后训练出的权重结果就只有两种情况,请问是哪里做错了,结果如下:
    1123项,1,1,11562,0,0,0
    义演,1,1,11562,0,0,0
    佳酿,1,1,11562,0,0,0
    沿街,1,1,11562,0,0,0
    老理,1,1,62,0,0,0
    三四十岁,1,1,11562,0,0,0
    解波,1,1,11562,0,0,0
    统建,1,1,11562,0,0,0
    蓓蕾,1,1,62,0,0,0
    李佑生,1,1,62,0,0,0
    肾结石,1,1,62,0,0,0
    劳作,1,1,62,0,0,0
    海因兹,1,1,11562,0,0,0
    上海行政开发培训班,1,1,11562,0,0,0
    大声,1,1,11562,0,0,0
    20余条,1,1,11562,0,0,0
    全国政协代表团,1,1,62,0,0,0
    邦国,1,1,62,0,0,0
    中心,1,1,11562,0,0,0
    魏克兴,1,1,11562,0,0,0
    意大利FILA(斐乐)公司,1,1,62,0,0,0
    第七版,1,1,11562,0,0,0
    天津今晚报,1,1,11562,0,0,0
    当红,1,1,11562,0,0,0
    悬案,1,1,62,0,0,0
    就只有11562和62两种权重结果,按经验不应该这样,还望您帮忙解惑,谢谢您

    [回复]

  13. AndyJi

    我然后换成pku的那个词典和训练数据,最后结果只有一种情况,这个应该可以明确不正确的了,结果为:
    数千,1,1,2480,0,0,0
    壁球,1,1,2480,0,0,0
    数十,1,1,2480,0,0,0
    太原,1,1,2480,0,0,0
    殆尽,1,1,2480,0,0,0
    宽容,1,1,2480,0,0,0
    77%,1,1,2480,0,0,0
    原状,1,1,2480,0,0,0
    总医院,1,1,2480,0,0,0
    灯塔,1,1,2480,0,0,0
    773,1,1,2480,0,0,0
    19980114-03-004-002,1,1,2480,0,0,0
    不知不觉,1,1,2480,0,0,0
    菜谱,1,1,2480,0,0,0
    777,1,1,2480,0,0,0
    鱼粉,1,1,2480,0,0,0
    白人,1,1,2480,0,0,0
    桂莲,1,1,2480,0,0,0
    所有权重数据都是2480,感觉这个错了,麻烦您帮我看下可以么

    [回复]

    52nlp 回复:

    这个原因不太清楚,不过这个版本给的特征比较少,区分度不高,可以follow后续几篇文章再试试,看看结果。

    [回复]

    AndyJi 回复:

    嗯,谢谢您。

    目前那几个配置文件还不是很明白怎么自己去写,所以改用了(三)里面您修改完善后的那5个配置文件,但跑完后发现词典的权重都还是一样的,就像没有被训练过一样,这个是配置文件的问题还是因为词典库和语料库的问题?

    您之前试验跑完后的词典权重呢?有没有去查验过是不是也一样,或者就只有两种权重值

    [回复]

    52nlp 回复:

    我这边不是这样的,你再检查一下吧

  14. MarkYang

    您好,我最近也在用mecab训练的分词库,可是问题来了,我用大概10000句中文文本语料,格式化后的语料最终就10M左右,但是再加载过程中,内存用了60G+,最终内存不足被kill了,这块是因为语料过多还是其他问题,怎么解决,目前输出的日志如下:
    ......
    adding virtual node: p,p,S,1,到
    adding virtual node: d,d,S,1,可
    6900... adding virtual node: q,q,S,1,里
    7000... 7100... adding virtual node: p,p,S,1,到
    adding virtual node: n,ns,S,1,大
    adding virtual node: p,p,S,1,到
    7200... adding virtual node: p,p,S,1,到
    7300... adding virtual node: q,q,S,1,里
    adding virtual node: p,p,S,1,就
    7400... adding virtual node: d,d,S,1,可
    7500... adding virtual node: p,p,S,1,到
    adding virtual node: p,p,S,1,到
    7600... adding virtual node: d,d,S,1,可
    adding virtual node: d,d,S,1,可
    adding virtual node: v,v,S,1,多
    7700...

    [回复]

    52nlp 回复:

    你是不是自己加了一些特征模板?feature.def里?按说1万句很小,不会耗这么多内存的。

    [回复]

发表评论

电子邮件地址不会被公开。 必填项已用*标注