LoginSignup
2
1

More than 5 years have passed since last update.

JAVAでのコマンドラインを通したCaboCha実行を高速化する

Posted at

背景

JavaでCabochaを使う方法の一つに外部プロセスを使う方法がありますが、よく紹介されている一文ずつ解析を行うやり方はとにかく時間がかかる。数万から数百万件のデータの処理完了に数日かかることもあるため、一括で解析を行う方法を書いておく。

一般的な方法

public void executeCabocha (String sentence) {
        String cabochaPath = "C:\\Program Files (x86)\\CaboCha\\bin\\cabocha.exe -f1";/

        //cabochaの結果を返す変数
        ArrayList<String> wordslist = new ArrayList<String>();
        try {
            //cabochaの起動
            process = Runtime.getRuntime().exec(cabochaPath);
            OutputStream out= process.getOutputStream();
            OutputStreamWriter writer = new OutputStreamWriter(out, "Shift-JIS");
            writer.write(sentence);
            writer.close();
            InputStream is = process.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "Shift-JIS"));
            String line;
            while ((line = br.readLine()) != null) {
                wordslist.add(line);
            }
                       process.destroy();
                   process.waitFor();
        } catch( Exception e ) {
            System.out.println(e);
        }       
    }

この方法で"wordlist"というArrayListに"sentence"を係り受け解析した結果が入ります。
"sentence"の中身は普通の日本語の文章です。単文でも複文でも構いません。
データ数が少ない場合はこれでも十分なのですが、データ数が3桁超えてくる(このexecuteCabochaが呼ばれる回数が多くなる)と処理完了までに数分かかるようになってしまいます。

参考
- WindowsのCabochaをJavaからexecで使う が 文字化け
- 外部プロセス起動

.txtファイルを読み込ませて実行すると早い

cabochaには文章を直接入力する方法とは別にtxtファイルを入力する方法が用意されています。

$cabocha  -f1 inputfile --output=outputfile

のようにするとinputfileの中身を読み込んでoutputfileに結果を出力してくれます。
コード一例:

public void getcabocharesult(ArrayList<String> sentences) {
        Random r = new Random();
        String serialcode = String.valueOf(r.nextInt(99999999));
        String path = "C:/pleiades/workspace/CaboCha/bin/cabocha";
        String pathinput = "C:/pleiades/workspace/CaboCha/bin/" + serialcode + "_inputtext.txt";
        String output ="--output=C:/pleiades/workspace/CaboCha/bin/" + serialcode + "_output.txt";
        String[] cmd = {path,"-f1", pathinput, output};
        this.makeinputfile(sentences, pathinput);

        //cabocha実行
        try {
            Process p = Runtime.getRuntime().exec(cmd);
            if (p.waitFor() == 0) {

            } else {
                System.out.println("--Cabocha起動失敗");
                System.exit(-1);
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

 途中"makeinputfile(...,...)"って関数がありますが、これは引数のsentencesに入っている文章データを一行ずつのデータにしてテキストファイルに出力しているだけです。出力先がpathinput。これでoutputにcabochaの出力結果がテキストファイルとしてはき出されるので後はこれを読み込むだけです。
 数万件のテキストデータをそれぞれcabochaで解析しようと思ったらこのように一度テキストデータにしてcabochaに入力する方が絶対に早いです。

比較データ等は今後掲載予定。
とりあえず今回はメモ程度にここまで。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1