2017年9月18日月曜日

形態素解析の速度比較

日本語形態素解析の速度比較をしてみました。
環境は、仮想マシン上でXeon 2コアを割り当てた4GBのメモリとSSDのストレージを使った環境です。
解析対象はWikipediaExtractorで分割したWikipediaのデータ5MB分です。

正確性でいけばJUMAN++なんでしょうが、やっぱり速さとの関係上、大量のドキュメント処理するにはMeCabかなという心象です。あとで試験してみたところkuromojiもなかなかに早いです。
実行したコマンド 実行時間
chasen -iw 2.525s
mecab -Owakati 2.330s
mecab -Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd 2.435s
mecab -Ochasen 4.098s
mecab -Ochasen -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd 3.887s
juman 30.607s
juman++ 10782.644s
kuromoji 4.862s
janome 716.016s
Janomeとkuromojiを加えました。
kuromojiはやい!


グラフ化してみるとこんな感じでした。(縦軸が対数になっているので注意してください。)

Janomeのテスト用コード

Janomeについては、テスト用に標準入力を受け取るようにコードを作ってパイプで繋げて計測しました。
ファイル: test_janome.py
import sys
from janome.tokenizer import Tokenizer

t = Tokenizer()
for line in sys.stdin:
    tokens = t.tokenize(line, wakati=True)
    print(" ".join(tokens))


kuromojiのテスト用コード

kuromojiについては、exampleディレクトリの下に、ちょうどいいサンプルがついてきますので、そのコードををほんの少し変更し、こちらもパイプで繋げて計測しました。
ファイル: TokenizerExample.java
package org.atilika.kuromoji.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import org.atilika.kuromoji.Token;
import org.atilika.kuromoji.Tokenizer;
import org.atilika.kuromoji.Tokenizer.Mode;

public class TokenizerExample {

        public static void main(String[] args) throws IOException {
                Tokenizer tokenizer;
                if (args.length == 1) {
                        Mode mode = Mode.valueOf(args[0].toUpperCase());
                        tokenizer = Tokenizer.builder().mode(mode).build();
                } else if (args.length == 2) {
                        Mode mode = Mode.valueOf(args[0].toUpperCase());
                        tokenizer = Tokenizer.builder().mode(mode).userDictionary(args[1]).build();
                } else {
                        tokenizer = Tokenizer.builder().build();
                }
                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
                String line;
                while ((line = reader.readLine()) != null) {
                        List result = tokenizer.tokenize(line);
                        for (Token token : result) {
                                System.out.print(token.getSurfaceForm() + " ");
                        }
                }
        }
}

0 件のコメント:

コメントを投稿