形態素解析ではありません。品詞などの情報は意識せず、長い単語を優先してザクザク切っていくだけです。
CC-CEDICTはオープンソース(Creative Commons)の中国語の辞書です。繁体字、簡体字、ピンインの発音に加えて、英語の意味がついています。品詞がついていればよかった。
まず、CEDICTのデータを雑に処理します。
MeCab辞書を作る
csvファイル
言語は何でもいいのですが、Rubyで簡単なプログラムを書きました。
cedict = open('cedict_ts.u8') cedict.each do |line| line.chomp! if line =~ /^(.*?)\s(.*?)\s\[(.*?)\]/ traditional = $1 simplified = $2 pinyin = $3 # カンマで区切られている単語は長いので切ることにする traditional = traditional.split(/,/) simplified = simplified.split(/,/) pinyin = pinyin.split(/,/) size = simplified.size (0..size-1).each {|i| cost = 0 # ピンインに大文字が含まれる語は固有名詞らしいので選ばれやすくする(コストが小さくなるようにする) if pinyin[i] =~ /[A-Z]/ then cost = [-32767, (-400 * (simplified[i].length ** 2)).to_i].max else cost = [-32767, (-400 * (simplified[i].length ** 1.5)).to_i].max end s = simplified[i].downcase.strip t = traditional[i].downcase.strip # 簡体字・繁体字の両方を出力する puts "#{s},0,0,#{cost},*,*,*,*,*,*,#{t},#{s},#{pinyin[i]}" puts "#{t},0,0,#{cost},*,*,*,*,*,*,#{t},#{s},#{pinyin[i]}" } end end
コストは小さい値が優先して採用されますので、長さの1.5乗に適当なマイナスの値を乗じて生成します。素性は特にありませんが、IPADICと同じ数に合わせておきます(そうしないとKuromojiでIndexOutOfBoundsExceptionが出たり面倒くさい)。これで辞書のCSVファイルができます。
6/18改変:コードを少し変更しました。kuromoji-ipadicのコードでは品詞タグ4つ、活用形2つの部分に繁体字、簡体字などの素性を入れるとうまくいかないため、後半に入れました。Javaコードも少し変更してgetTraditional()などのメソッドを追加してみました。
public class Token extends TokenBase { public Token(int wordId, String surface, ViterbiNode.Type type, int position, Dictionary dictionary) { super(wordId, surface, type, position, dictionary); } public String getTraditional() { return this.getFeature(10); } public String getSimplified() { return this.getFeature(11); } public String getPinyin() { return this.getFeature(12); } (略) }
char.def
IPA辞書のをもとに漢字、カタカナ、平仮名などの区分を除去してでっち上げます。ASCII文字とスペースとDEFAULTだけあればいいと思います。最後に
0xFF0C SYMBOL
を追加しています。全角カンマです。
DEFAULTの未知語処理で最大長を1文字にしています。未知語に当たった場合は1文字ずつに分割します。古代中国語は1文字=1形態素だったそうですので、そういう分割もありでしょう。現代中国語は違います。
################################################################################### # # CHARACTER CATEGORY DEFINITION # # CATEGORY_NAME INVOKE GROUP LENGTH # # - CATEGORY_NAME: Name of category. you have to define DEFAULT class. # - INVOKE: 1/0: always invoke unknown word processing, evan when the word can be found in the lexicon # - GROUP: 1/0: make a new word by grouping the same chracter category # - LENGTH: n: 1 to n length new words are added # DEFAULT 1 1 1 # DEFAULT is a mandatory category! SPACE 0 1 0 SYMBOL 1 1 0 NUMERIC 1 1 0 ASCII 1 1 0 ################################################################################### # # CODE(UCS2) TO CATEGORY MAPPING # # SPACE 0x0020 SPACE # DO NOT REMOVE THIS LINE, 0x0020 is reserved for SPACE 0x00D0 SPACE 0x0009 SPACE 0x000B SPACE 0x000A SPACE # ASCII 0x0021..0x002F ASCII 0x0030..0x0039 ASCII 0x003A..0x0040 ASCII 0x0041..0x005A ASCII 0x005B..0x0060 ASCII 0x0061..0x007A ASCII 0x007B..0x007E ASCII # Latin 0x00A1..0x00BF ASCII # Latin 1 0x00C0..0x00FF ASCII # Latin 1 0x0100..0x017F ASCII # Latin Extended A 0x0180..0x0236 ASCII # Latin Extended B 0x1E00..0x1EF9 ASCII # Latin Extended Additional # NUMERIC (�� �� �� �� �� �� ϻ �� Ȭ �� �� ɴ �� �� �� ��) 0x3007 NUMERIC # �� 0x3038 NUMERIC # ��? 0x30FB NUMERIC # �� 0x4E00 NUMERIC 0x4E8C NUMERIC 0x4E09 NUMERIC 0x56DB NUMERIC 0x4E94 NUMERIC 0x516D NUMERIC 0x4E03 NUMERIC 0x516B NUMERIC 0x4E5D NUMERIC 0x5341 NUMERIC 0x767E NUMERIC 0x5343 NUMERIC 0x4E07 NUMERIC 0x5104 NUMERIC 0x5146 NUMERIC # OTHER SYMBOLS 0x2000..0x206F SYMBOL # General Punctuation 0x2070..0x209F NUMERIC # Superscripts and Subscripts 0x20A0..0x20CF SYMBOL # Currency Symbols 0x20D0..0x20FF SYMBOL # Combining Diaritical Marks for Symbols 0x2100..0x214F SYMBOL # Letterlike Symbols 0x2150..0x218F NUMERIC # Number forms 0x2100..0x214B SYMBOL # Letterlike Symbols 0x2190..0x21FF SYMBOL # Arrow 0x2200..0x22FF SYMBOL # Mathematical Operators 0x2300..0x23FF SYMBOL # Miscellaneuos Technical 0x2460..0x24FF SYMBOL # Enclosed NUMERICs 0x2501..0x257F SYMBOL # Box Drawing 0x2580..0x259F SYMBOL # Block Elements 0x25A0..0x25FF SYMBOL # Geometric Shapes 0x2600..0x26FE SYMBOL # Miscellaneous Symbols 0x2700..0x27BF SYMBOL # Dingbats 0x27F0..0x27FF SYMBOL # Supplemental Arrows A 0x27C0..0x27EF SYMBOL # Miscellaneous Mathematical Symbols-A 0x2800..0x28FF SYMBOL # Braille Patterns 0x2900..0x297F SYMBOL # Supplemental Arrows B 0x2B00..0x2BFF SYMBOL # Miscellaneous Symbols and Arrows 0x2A00..0x2AFF SYMBOL # Supplemental Mathematical Operators 0x3300..0x33FF SYMBOL 0x3200..0x32FE SYMBOL # ENclosed CJK Letters and Months 0x3000..0x3004 SYMBOL # CJK Symbol and Punctuation 0x3008..0x303F SYMBOL # CJK Symbol and Punctuation 0xFE30..0xFE4F SYMBOL # CJK Compatibility Forms 0xFE50..0xFE6B SYMBOL # Small Form Variants 0xFF0C SYMBOL
dicrc
IPA辞書のをそのまま使います。エンコーディングはUTF-8に
; Configuration file of IPADIC ; ; $Id: dicrc,v 1.4 2005/12/24 19:58:42 taku-ku Exp $; ; bos-feature = BOS/EOS,*,*,*,*,*,* cost-factor = 800 eval-size = 4 unk-eval-size = 2 config-charset = UTF8
matrix.def
MeCabだと不要ですが、Kuromojiの辞書コンパイルで必要になるので作っておきます。1×1の状態の最小構成です。
1 1 0 0 0
unk.def
未知語処理のルールです。
DEFAULT,0,0,0,*,*,*,*,*,*,*,*,* ASCII,0,0,0,*,*,*,*,*,*,*,*,* NUMERIC,0,0,0,*,*,*,*,*,*,*,*,* SYMBOL,0,0,0,*,*,*,*,*,*,*,*,* SPACE,0,0,0,*,*,*,*,*,*,*,*,*
MeCab辞書のコンパイル
これだけファイルがあれば辞書のコンパイルができるはずです。
/usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -f urf-8 -t utf-8 ./pos-id.def is not found. minimum setting is used reading ./unk.def ... 5 emitting double-array: 100% |###########################################| ./model.def is not found. skipped. ./pos-id.def is not found. minimum setting is used reading ./cedict.csv ... 115950 emitting double-array: 100% |###########################################| reading ./matrix.def ... 1x1 done! mecab -d . 环球网是中国领先的国际资讯门户,拥有独立采编权的中央重点新闻网站 环球 環球,huan2 qiu2,*,*,*,*,*,*,* 网 網,wang3,*,*,*,*,*,*,* 是 是,shi4,*,*,*,*,*,*,* 中国 中國,Zhong1 guo2,*,*,*,*,*,*,* 领先 領先,ling3 xian1,*,*,*,*,*,*,* 的 的,de5,*,*,*,*,*,*,* 国际 國際,guo2 ji4,*,*,*,*,*,*,* 资讯 資訊,zi1 xun4,*,*,*,*,*,*,* 门户 門戶,men2 hu4,*,*,*,*,*,*,* , *,*,*,*,*,*,*,*,* 拥有 擁有,yong1 you3,*,*,*,*,*,*,* 独立 獨立,du2 li4,*,*,*,*,*,*,* 采 採,cai3,*,*,*,*,*,*,* 编 編,bian1,*,*,*,*,*,*,* 权 權,Quan2,*,*,*,*,*,*,* 的 的,de5,*,*,*,*,*,*,* 中央 中央,zhong1 yang1,*,*,*,*,*,*,* 重点 重點,chong2 dian3,*,*,*,*,*,*,* 新闻网 新聞網,xin1 wen2 wang3,*,*,*,*,*,*,* 站 站,zhan4,*,*,*,*,*,*,* EOS
とりあえず単語分割はできます。
6/18変更
环球网是中国领先的国际资讯门户 环球 *,*,*,*,*,*,環球,环球,huan2 qiu2 网 *,*,*,*,*,*,網,网,wang3 是 *,*,*,*,*,*,是,是,shi4 中国 *,*,*,*,*,*,中國,中国,Zhong1 guo2 领先 *,*,*,*,*,*,領先,领先,ling3 xian1 的 *,*,*,*,*,*,的,的,de5 国际 *,*,*,*,*,*,國際,国际,guo2 ji4 资讯 *,*,*,*,*,*,資訊,资讯,zi1 xun4 门户 *,*,*,*,*,*,門戶,门户,men2 hu4 EOS
Kuromoji用ビルド
Javaで分割したいので、これをKuromoji用にコンパイルします。
まずbuildscript for Kuromoji with mecab-neologdを拝借します。このスクリプトをまず一度動作させます。パッケージ名オプションだけ、-p com.atilika.kuromoji.cedictと指定しておきました。パッケージ名かぶりを避けるためです。
するとkuromoji/kuromoji-ipadic以下にneologdをマージしたIPADICを生成します。neologdの場所は kuromoji/kuromoji-ipadic/dictionary/mecab-ipadic-2.7.0-20070801-neologd-20180604/ でした。この同じ階層にさきほどのCEDICTのディレクトリ一式を置きます。
つづいてダウンロードしたシェルスクリプトの最後のビルド部分を拝借して書き換えます。
mvn -pl kuromoji-ipadic -am package \ -DskipTests=true \ -DskipDownloadDictionary=true \ -Dkuromoji.dict.dir=kuromoji-ipadic/dictionary/cedict \ -Dkuromoji.dict.encoding=utf-8
辞書のパスをCEDICTにします。あとはこのコマンドだけ実行してもいいし、スクリプトに戻してスクリプトを実行してもいいでしょう。なぜこんな面倒なことをするかと言うと、このスクリプトはパッケージ名の置換をやってくれるからです。別に自力でやってもいいし、IntelliJ IDEAのようなIDEのリファクタリングを使っても構いません。
import com.atilika.kuromoji.cedict.Token; import com.atilika.kuromoji.cedict.Tokenizer; import java.util.List; public class Test { public static void main(String[] args) { Tokenizer tokenizer = new Tokenizer(); List<Token> tokens = tokenizer.tokenize("环球网是中国领先的国际资讯门户,拥有独立采编权的中央重点新闻网站"); for( Token token : tokens ) { System.out.println(token.getSurface()); } } }
結果
环 球网 是 中国 领先 的 国际 资讯 门户 , 拥有 独立 采 编 权 的 中央 重点 新闻网 站 Process finished with exit code 0
Mecabだと 环球 网 だったのにKuromojiだと环 球网 になっていますが、一応Kuromoji用にコンパイルできました。
KuromojiはMeCab互換だと言われていますが、細かいところで動作が違うので注意です。
繁体字・簡体字変換
import com.atilika.kuromoji.cedict.Token; import com.atilika.kuromoji.cedict.Tokenizer; import java.util.List; public class Test { public static void main(String[] args) { Tokenizer tokenizer = new Tokenizer(); Listtokens = tokenizer.tokenize("环球网是中国领先的国际资讯门户,拥有独立采编权的中央重点新闻网站"); for( Token token : tokens ) { System.out.println(token.getTraditional()); } } }
結果
環 球網 是 中國 領先 的 國際 資訊 門戶 * 擁有 獨立 採 編 權 的 中央 重點 新聞網 站 Process finished with exit code 0
完璧ではないでしょうが、わりとしっかり繁体字と簡体字の変換ができます。
最近のコメント