こんにちは、ごみばこです。
自然言語処理をするとき n-gram や形態素解析などの処理をし、文章から語にすることがよくあると思います。 n-gram はシンプルですが、分け具合、分け方によって情報量がなくなってしまうこともありますし、データ量も大きくなりがちです。形態素解析は簡単お手軽そうに見えますが、裏の処理はなかなかコストが高く、ちりもつもればなんとやら。
というところで、新しい選択肢の sentencepiece だそうです。
https://github.com/google/sentencepiece
私の知識や理解力の不足から雑な説明にはなってしまいますが…。sentencepiece が行うことは次のことです。
- 文章をよろしくニューラルネットワークで処理し語に分割するためのモデルを生成
- そのモデルを使って文章を分割する
- n-gram や 形態素解析のような何かが得られる!やったー!
この何かで機械翻訳をすると n-gram や形態素解析などと比べて劣ることなく十分に効果を発揮した、との記録もあります。
https://github.com/google/sentencepiece#results-bleu-scores
学習する、という初期コストがかかることについては、形態素解析も同じですが、その後の分割することについては、形態素解析よりもコスト低く行うことができます。また、語彙も形態素解析で扱う辞書に比べて遥かに小さくできるそうで、パフォーマンスよし、効果よし、ととても魅力的に見えますね!
実際に収録されているサンプルを試してみました。
環境構築は docker でお手軽にやってしまいます。
$ docker run -it -d centos:latest
$ docker ps
$ docker attach ...
コンテナの中で必要なツールの準備を進めていきます。
# yum install git make gcc-c++ autoconf automake libtool protobuf protobuf-devel
# git clone https://github.com/google/sentencepiece.git
# cd sentencepiece
# ./autogen.sh
# ./configure
# make
ここまでで実行ファイルが作られます。それでは文章から学習をしてみます。 サンプルとして吾輩は猫である…が収録されているので、これを使ってみます。
# src/spm_train --input=data/wagahaiwa_nekodearu.txt --model_prefix=neko --vocab_size=8000 --model_type=unigram
unigram_model_trainer.cc(494) LOG(INFO) Starts training with :
input: "data/wagahaiwa_nekodearu.txt"
model_prefix: "neko"
model_type: UNIGRAM
vocab_size: 8000
character_coverage: 0.9995
input_sentence_size: 10000000
mining_sentence_size: 2000000
training_sentence_size: 10000000
seed_sentencepiece_size: 1000000
shrinking_factor: 0.75
num_threads: 16
num_sub_iterations: 2
max_sentencepiece_length: 16
split_by_unicode_script: true
split_by_whitespace: true
trainer_interface.cc(109) LOG(INFO) Loading corpus: data/wagahaiwa_nekodearu.txt
trainer_size=0ace.cc(126) LOG(INFO) Loading: ▁吾輩は猫である
trainer_interface.cc(148) LOG(INFO) Loaded 2246 sentences
trainer_interface.cc(166) LOG(INFO) all chars count=182657
trainer_interface.cc(173) LOG(INFO) Done: 99.9502% characters are covered.
trainer_interface.cc(181) LOG(INFO) alphabet size=2507
trainer_interface.cc(211) LOG(INFO) Done! 2246 sentences are loaded
unigram_model_trainer.cc(121) LOG(INFO) Using 2246 sentences for making seed sentencepieces
unigram_model_trainer.cc(149) LOG(INFO) Making suffix array...
unigram_model_trainer.cc(153) LOG(INFO) Extracting frequent sub strings...
unigram_model_trainer.cc(204) LOG(INFO) Initialized 34678 seed sentencepieces
trainer_interface.cc(215) LOG(INFO) Tokenizing input sentences with whitespace: 2246
trainer_interface.cc(224) LOG(INFO) Done! 2193
unigram_model_trainer.cc(513) LOG(INFO) Using 2193 sentences for EM training
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=0 size=19246 obj=303.949 num_tokens=81388 num_tokens/piece=4.22883
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=1 size=17546 obj=276.547 num_tokens=81681 num_tokens/piece=4.65525
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=0 size=13133 obj=282.685 num_tokens=85486 num_tokens/piece=6.50925
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=1 size=13089 obj=279.841 num_tokens=85549 num_tokens/piece=6.53595
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=0 size=9814 obj=292.604 num_tokens=91023 num_tokens/piece=9.27481
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=1 size=9813 obj=289.388 num_tokens=91093 num_tokens/piece=9.28289
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=0 size=8799 obj=294.594 num_tokens=93339 num_tokens/piece=10.6079
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=1 size=8799 obj=293.481 num_tokens=93368 num_tokens/piece=10.6112
trainer_interface.cc(284) LOG(INFO) Saving model: neko.model
trainer_interface.cc(293) LOG(INFO) Saving vocabs: neko.vocab
学習が完了しました。適当な文章を入れて、分割の様子を見てみましょう。
# echo "吾輩は猫である。名はまだ無い。" | src/spm_encode --model=neko.model
▁吾輩は 猫 である 。 名 はまだ 無い 。
# echo "吾輩は箱が好きで好きでたまらない。" | src/spm_encode --model=neko.model
▁吾輩は 箱 が 好き で 好き で たま らない 。
# echo "ニャーと声を出せばで飯が提供され、ニャッと声を出せば頭を撫でられる。" | src/spm_encode --model=neko.model
▁ ニ ャ ー と 声を 出 せば で 飯 が 提 供 され 、 ニ ャ ッ と 声を 出 せば 頭 を撫 で ら れる 。
私自信の知識と能力が追いついていないのもあって、どんなところで使えそうなのかあまりイメージわかないですが、トークナイザの1つの選択肢として考えたいですねー!
関連リンク) http://qiita.com/taku910/items/7e52f1e58d0ea6e7859c どういった背景から作られたかが解説されています!