ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

日本語形態素解析ライブラリ Kuromoji のコマンドライン用インターフェイスを書いた

Java で書かれた日本語形態素解析ライブラリ Kuromoji を Perl から使ってみたいなー、と思って、別の言語のプログラムから使いやすいようなインターフェイスを書きました。

Kuromoji について

Java で書かれたオープンソースの日本語の形態素解析ライブラリです。 検索用のライブラリらしくて、Apache LuceneApache Solr に組み込まれているらしいです。 もちろん検索エンジンとは独立して利用することも可能です。

独立して使用する場合は、単に jar ファイルをダウンロードしてきて Java のライブラリパスに追加するだけ (あるいは公開されている Maven リポジトリを使用して依存関係を解決するだけ) で形態素解析できるようになります。 便利ですね。

Java で Kuromoji を使う方法に関しては下記の記事がわかりやすかったです。

ライセンスは Apache License, Version 2 です。

コマンドライン用のインターフェイスについて

さて、上述のように Java から使うだけなら簡単に形態素解析できるようになるわけですが、他の言語からはそのままでは使えないので、簡単に使えるようにコマンドライン用のインターフェイスを書きました *1

単純に標準入力に入力された文字列を 1 行ごとに形態素解析し、その結果を JSON 形式で標準出力に流す、というものです。

ライセンスは Apache License, Version 2 です。

使い方

上記 ZIP ファイルをダウンロードして展開してください。 実行ファイルは shino/bin/shino です。

実行後、標準入力に文字列を入力すると、それが形態素解析されて JSON 形式で結果が返ってきます。

$ ./shino/bin/shino
お水おいしい。
[{"position":0,"all_features":["接頭詞","名詞接続","*","*","*","*","お","オ","オ"],
  "reading":"オ","is_known":true,"is_user":false,"part_of_speech":"接頭詞,名詞接続,*,*",
  "is_unknown":false,"surface_form":"お","base_form":"お"},
  {"position":1,"all_features":["名詞","一般","*","*","*","*","水","ミズ","ミズ"],
  "reading":"ミズ","is_known":true,"is_user":false,"part_of_speech":"名詞,一般,*,*",
  "is_unknown":false,"surface_form":"水","base_form":"水"},
  {"position":2,"all_features":["形容詞","自立","*","*","形容詞・イ段","基本形","おいしい","オイシイ","オイシイ"],
  "reading":"オイシイ","is_known":true,"is_user":false,"part_of_speech":"形容詞,自立,*,*",
  "is_unknown":false,"surface_form":"おいしい","base_form":"おいしい"},
  {"position":6,"all_features":["記号","句点","*","*","*","*","。","。","。"],
  "reading":"。","is_known":true,"is_user":false,"part_of_speech":"記号,句点,*,*",
  "is_unknown":false,"surface_form":"。","base_form":"。"}]

上は 「お水おいしい。」 という標準入力に対して JSON 形式で結果が返される例 *2

Ruby プログラムなどからの使い方

Ruby などから使う場合は、双方向のパイプを開いて、標準入力に形態素解析させる文字列を渡して、標準出力から結果を取り出す、というようなことをすればよいです。 以下は Ruby の例で、文字列の中の名詞を取り出すというものです。

# coding: utf-8

require 'json'

PATH_TO_SHINO = './shino/bin/shino'

nouns = []
IO.popen(PATH_TO_SHINO, 'r+') do |io|
  ['君とつながる RPG。', '今日はいい天気ですね。', '闇の炎に抱かれて消えろ。'].each do |str|
    io.puts str
    tokens = JSON.parse(io.gets())
    tokens.each do |token|
      nouns.push token if token['all_features'][0] == '名詞'
    end
  end
end
p nouns.map{|token| token['surface_form'] } #=> ["君", "RPG", "今日", "天気", "闇", "炎"]

*1:他にもっといい方法があるのかもしれない。

*2:JSON 文字列は見やすいように改行を入れています。