[PHP]複合名詞に対応させて分かち書きをする

今回も igo-php を用いた形態素解析のサンプルなので、導入については こちら を御覧ください。

通常分かち書きをする場合、名詞は細かく分割され、次のように解釈されます。

「これは形態素解析の実験結果です。」 → 「これ | は | 形態素 | 解析 | の | 実験 | 結果 | です | 。」

もちろん間違ってはいないのですが、感覚的には「形態素解析」「実験結果」はそれぞれひとつの単語でまとめられていたほうが自然です。
「東京特許許可局」などの場合も同様に一つの単語として扱うことがほとんどです。

法則を見てみると、名詞が連続している場合は複合名詞になるというシンプルなものなので、
それを踏まえて次のようにしてみました。

<?php
require_once 'lib/Igo.php';

$igo = new Igo(dirname(__FILE__) . "/ipadic", "UTF-8");
$str = "これは形態素解析の実験結果です。";
$result = $igo->parse($str);

$noun = "";
$words = array();
foreach($result as $value){
  $feature = explode(",", $value->feature);
  if($feature[0] === "名詞"){
    $noun .= $value->surface;
  } else {
    if(mb_strlen($noun)) $words[] = $noun;
    $noun = "";
    $words[] = $value->surface;
  }
}
if(mb_strlen($noun)) $words[] = $noun;
print_r($words);

結果: 「これ | は | 形態素解析 | の | 実験結果 | です | 。」

名詞が現れた場合は一旦 $noun に保管しておき、その他の場合は単語として $words に追加します。
連続して名詞が現れた場合は $noun に追加します。

[PHP]文章を解析して単語ごとに分解する(形態素解析)

日本語は英語と違い、単語同士が明確に区切られていないので、一つ一つの単語の品詞を調べる場合は、いわゆる「分かち書き」をする必要があります。
分かち書きとは次のように単語を分けて書くことです。

これは日本語です → これ | は | 日本語 | です

プログラミングで分かち書きを行うには大変な労力がかかるので、ゼロから開発するのは現実的ではありません。

簡単に行う方法の一つは Yahoo! API を利用することです。
クエリを送るだけで簡単に解析結果を受け取ることができるので便利ですが、リクエスト回数に上限があったり、クレジット表記が義務付けられたりするので、状況によっては使いにくくなります。

もう一つはサーバーに MeCab をインストールする方法です。
Mecab はオープンソースの形態素解析エンジンで、様々な分野で活用されている実績あるプログラムです。
可能ならこちらを導入するのがベストですが、サーバーにインストールする必要が有るため、レンタルサーバーなどでは運用できない場合があります。

以上のメリット・デメリットを踏まえた上で最も簡便な方法は igo-php を使うことです。
igo-php は Java で作られた形態素解析器を PHP で実装したものです。
これは PHP からクラスファイルをインクルードするだけで使うことができるため、多くの環境で運用することができます。

igo-php を利用するには次の3つを用意します

Igo 本体
Mecab用辞書ファイル(IPA)
igo-php

igo-php 自体には辞書ファイルが付属されていないので、使用するには MeCab の辞書を利用する必要があります。こちらから辞書ファイルをダウンロードします。

辞書ファイルはそのままでは使えません。圧縮されている辞書ファイルを展開したら、Igo を用いてビルドします。
Igo 本体(執筆時点では igo-0.4.5.jar )をダウンロードし、コンソールに次のように入力します

java -Xmx1024m -cp (igo のファイルパス) net.reduls.igo.bin.BuildDic ipadic (展開した辞書のディレクトリ) EUC-JP

ファイルを展開した場所によってパスは変わりますが、私の環境では次のようなコマンドでした。
(Windowsで C:\igo\ に全て入れた場合)

cd C:\igo
java -Xmx1024m -cp igo-0.4.5.jar net.reduls.igo.bin.BuildDic ipadic mecab-ipadic-2.7.0-20070801 EUC-JP

「ipadic」というディレクトリができるので、これを辞書として使います。
文字コードを EUC-jP と指定してありますが、PHP から変換できるので、UTF-8 の PHP で使う場合も辞書は EUC-JP のままで問題ありません。

辞書の準備ができたら PHP プログラムで使う igo-php をダウンロードします。展開すると「lib」フォルダがあるのでそちらを使用します。

実際のPHPソースは次のようになります

<?php
require_once 'lib/Igo.php';
$igo = new Igo("./ipadic", "UTF-8");
$text = "これはテストです";
$result = $igo->wakati($text);
print_r($result);

[出力結果]

Array
(
    [0] => これ
    [1] => は
    [2] => テスト
    [3] => です
)

lib フォルダの Igo.php をインクルードし、new Igo(“辞書フォルダへのパス”, “文字コード(省略可)”) のようにインスタンス化します。

関数は分かち書きをする wakati() と、単語の品詞などを詳細に解析する parse() が利用できます。
wakati() は単語ごとの配列、parse() は単語の名前、品詞、活用形、読み方などが細かく分けられた多次元配列を返します。

もしプログラムがメモリ不足で正常に動作しない場合はプログラムの先頭に次のように記述して下さい。

ini_set('memory_limit', '128M');