LoginSignup
8
8

More than 5 years have passed since last update.

PHP で JUMAN を叩く

Last updated at Posted at 2015-06-26

形態素解析に用いられるJUMANですが、扱える言語がPerlやPythonです。Rubyで扱っている記事も見つけますが、PHPで書かれたものはなかったので、メモしておきます。
(2015/9/4: @mpywさんからを受けたので追記をしました)

proc_open を使った方法

<?php
function juman($text) {
  $descriptorspec = array(
     0 => array("pipe", "r"),  // stdin は、子プロセスが読み込むパイプです。
     1 => array("pipe", "w"),  // stdout は、子プロセスが書き込むパイプです。
  );

  $process = proc_open('juman', $descriptorspec, $pipes);

  if (is_resource($process)) {
      // $pipes はこの時点で次のような形を取っています。
      // 0 => 子プロセスの stdin に繋がれた書き込み可能なハンドル
      // 1 => 子プロセスの stdout に繋がれた読み込み可能なハンドル
      // すべてのエラー出力は /tmp/error-output.txt に書き込みされます。

      fwrite($pipes[0], $text);
      fclose($pipes[0]);

      $return_value = stream_get_contents($pipes[1]);
      fclose($pipes[1]);

      // デッドロックを避けるため、proc_close を呼ぶ前に
      // すべてのパイプを閉じることが重要です。
      proc_close($process);

      return $return_value;
  }
}
?>

shell_execを使った方法(こちらの方が簡単)

function juman($text) {
  // jumanのコマンドを実行
  $output = shell_exec(sprintf('echo %s | /usr/local/bin/juman', escapeshellarg($text)));

  return $output;
}

使い方

$textにjumanにかけたい文字列を渡すと、それを返してくれます。この関数を使用すると返ってくるのは文字列形式になります。よって、受け取り側で

<?php
// テキストをjumanにかけて結果を取得する
// splitした後の配列に {"EOS", ""} が含まれるので削除する
$text = 'こんにちは。私の名前はSOJOです。';
$juman_result = juman($text);
$juman_result = split("\n", $juman_result);
array_pop($juman_result);
array_pop($juman_result);

var_dump($juman_result);
?>

出力結果

array(9) {
  [0]=>
  string(119) "こんにちは こんにちは こんにちは 感動詞 12 * 0 * 0 * 0 "代表表記:こんにちは/こんにちは""
  [1]=>
  string(41) "。 。 。 特殊 1 句点 1 * 0 * 0 NIL"
  [2]=>
  string(112) "私 わたし 私 名詞 6 普通名詞 1 * 0 * 0 "代表表記:私/わたし 漢字読み:訓 カテゴリ:人""
  [3]=>
  string(47) "の の の 助詞 9 接続助詞 3 * 0 * 0 NIL"
  [4]=>
  string(110) "名前 なまえ 名前 名詞 6 普通名詞 1 * 0 * 0 "代表表記:名前/なまえ カテゴリ:抽象物""
  [5]=>
  string(44) "は は は 助詞 9 副助詞 2 * 0 * 0 NIL"
  [6]=>
  string(54) "SOJO SOJO SOJO 未定義語 15 その他 1 * 0 * 0 NIL"
  [7]=>
  string(72) "です です だ 判定詞 4 * 0 判定詞 25 デス列基本形 27 NIL"
  [8]=>
  string(41) "。 。 。 特殊 1 句点 1 * 0 * 0 NIL"
}

とする必要があります。関数側に配列に変換する処理を入れても良いかも知れまん。返ってくるデータはあくまでも文字列なので、単語の各要素を取り出すためには、更にsplitなどを使って文字列を切り分ける必要があります。

関数側の処理はproc_openが具体的に何をしているのか把握できていないので、分かり次第、追記していきたいと思います。


参考文献
http://php.net/manual/ja/function.proc-open.php
http://qiita.com/eme-fes456/items/7d5d481a167743f00c5e

8
8
4

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
8
8