PHP＋MeCab+Vagrantで日本語形態素解析を試す


なんか急に[形態素解析](http://ja.wikipedia.org/wiki/%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90)に興味が湧いたので試してみた。

今回作成したVagrantfileとサンプルコードは[github](https://github.com/kawanamiyuu/vagrant-php-mecab)で公開しています。


# 動作環境

* [MeCab](http://mecab.googlecode.com/svn/trunk/mecab/doc/index.html) - 形態素解析エンジン
 * C言語による実装
 * 2013/12現在、ver0.996
 * OSSの形態素解析エンジンの中で一番有名(らしい)
 * Googleの[大規模日本語n-gramデータ](http://googlejapan.blogspot.jp/2007/11/n-gram.html)の作成や、OSX・iOSの日本語入力にも利用されている(らしい)


* [php-mecab](https://github.com/rsky/php-mecab) - MeCabのPHPバインディング
 * 2013/12現在、ver0.5.0
 *  peclとして提供されている

* PHP 5.5

*  CentOS 6.4 (on Vagrant)

## 環境構築

GithubでVagrantfileとサンプルコードを公開していますので、```git clone```して```vagrant up```すれば、ハイ出来上がり！です。

[vagrant-php-mecab](https://github.com/kawanamiyuu/vagrant-php-mecab)

```bash
$ git clone https://github.com/kawanamiyuu/vagrant-php-mecab.git

$ tree vagrant-php-mecab
vagrant-php-mecab
├── LICENSE
├── README.md
├── src
│   ├── example-countMeishi.php
│   ├── example-parseToNode.php
│   └── example-parseToString.php
└── vagrant
    ├── Vagrantfile
    ├── inst_mecab.sh
    ├── inst_php.sh
    └── inst_php_mecab.sh

$ cd vagrant-php-mecab/vagrant
$ vagrant up --provision
$ vagrant ssh

#### 以下、vagrant上で ####

$ mecab -v
mecab of 0.996

$ php -v
PHP 5.5.7 (cli) (built: Dec 11 2013 07:13:20) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies

$ php --modules | grep mecab
mecab
```

※ mecab本体やphp-mecabのインストール方法の詳細については、すでに詳しく説明しているサイトが沢山あるためここでは割愛します。[inst_mecab.sh](https://github.com/kawanamiyuu/vagrant-php-mecab/blob/master/vagrant/inst_mecab.sh),[inst_php_mecab.sh](https://github.com/kawanamiyuu/vagrant-php-mecab/blob/master/vagrant/inst_php_mecab.sh)をご覧ください。

# 形態素解析を試す その1

```
坊主がびょうぶに上手に坊主の絵を書いた
```

という文章を解析してみる。

（以降のコマンドはすべてvagrant上で）

## mecabコマンド

```bash
$ mecab (エンター押下)
坊主がびょうぶに上手に坊主の絵を書いた (←ペーストしてエンター押下)
坊主	名詞,一般,*,*,*,*,坊主,ボウズ,ボーズ
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
びょうぶ	名詞,一般,*,*,*,*,びょうぶ,ビョウブ,ビョーブ
に	助詞,格助詞,一般,*,*,*,に,ニ,ニ
上手	名詞,形容動詞語幹,*,*,*,*,上手,ジョウズ,ジョーズ
に	助詞,副詞化,*,*,*,*,に,ニ,ニ
坊主	名詞,一般,*,*,*,*,坊主,ボウズ,ボーズ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
絵	名詞,一般,*,*,*,*,絵,エ,エ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
書い	動詞,自立,*,*,五段・カ行イ音便,連用タ接続,書く,カイ,カイ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
EOS
```

## php-mecab

### mecabコマンドを実行したのと同じ結果を出力

```bash
$ cd /share/src
$ php example-parseToString.php
坊主	名詞,一般,*,*,*,*,坊主,ボウズ,ボーズ
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
びょうぶ	名詞,一般,*,*,*,*,びょうぶ,ビョウブ,ビョーブ
に	助詞,格助詞,一般,*,*,*,に,ニ,ニ
上手	名詞,形容動詞語幹,*,*,*,*,上手,ジョウズ,ジョーズ
に	助詞,副詞化,*,*,*,*,に,ニ,ニ
坊主	名詞,一般,*,*,*,*,坊主,ボウズ,ボーズ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
絵	名詞,一般,*,*,*,*,絵,エ,エ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
書い	動詞,自立,*,*,五段・カ行イ音便,連用タ接続,書く,カイ,カイ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
EOS
```

### 解析(分解)後の品詞情報を詳しく出力

```bash
$ cd /share/src
$ php example-parseToNode.php 
Array
(
    [surface] => 
    [feature] => BOS/EOS,*,*,*,*,*,*,*,*
    [id] => 0
    [length] => 0
    [rlength] => 0
    [rcAttr] => 0
    [lcAttr] => 0
    [posid] => 0
    [char_type] => 0
    [stat] => 2
    [isbest] => 1
    [alpha] => 0
    [beta] => 0
    [prob] => 0
    [wcost] => 0
    [cost] => 0
)
Array
(
    [surface] => 坊主 # 形態素の文字列情報 
    [feature] => 名詞,一般,*,*,*,*,坊主,ボウズ,ボーズ # CSVで表記された素性情報
    [id] => 3        # 形態素に付与される ユニークID
    [length] => 6    # 形態素の長さ
    [rlength] => 6   # 形態素の長さ(先頭のスペースを含む)
    [rcAttr] => 1285 # 右文脈ID
    [lcAttr] => 1285 # 左文脈ID
    [posid] => 38    # 形態素ID
    [char_type] => 2 # 文字種情報
    [stat] => 0      # 形態素の種類
    [isbest] => 1    # ベスト解の場合 1, それ以外 0
    [alpha] => 0     # forward backward の foward log 確率
    [beta] => 0      # forward backward の backward log 確率
    [prob] => 0      # 周辺確率
    [wcost] => 5623  # 単語生起コスト
    [cost] => 5340   # 累積コスト
)
Array
(
    [surface] => が
    [feature] => 助詞,格助詞,一般,*,*,*,が,ガ,ガ
    [id] => 12
    [length] => 3
    [rlength] => 3
    [rcAttr] => 148
    [lcAttr] => 148
    [posid] => 13
    [char_type] => 6
    [stat] => 0
    [isbest] => 1
    [alpha] => 0
    [beta] => 0
    [prob] => 0
    [wcost] => 3866
    [cost] => 4485
)
…略…
```

# 形態素解析を試す その2

[進撃の巨人のストーリー](http://ja.wikipedia.org/wiki/%E9%80%B2%E6%92%83%E3%81%AE%E5%B7%A8%E4%BA%BA#.E3.82.B9.E3.83.88.E3.83.BC.E3.83.AA.E3.83.BC)を形態素解析して、出現回数が多い名詞を抽出してみる。

```bash
$ cd /share/src
# 3回以上出現する名詞を抽出する例
$ cat /path/to/shingeki-no-kyozin-story.txt | php example-countMeishi.php 3
Array
(
    [巨人] => 39
    [エレン] => 28
    [兵団] => 11
    [壁] => 9
    [アニ] => 7
    [作戦] => 7
    [カサ] => 6
    [女] => 6
    [ミ] => 6
    [班] => 5
    [アルミン] => 5
    [ウォール] => 5
    [マリア] => 5
    [リヴァイ] => 4
    [ユミル] => 4
    [人類] => 4
    [ウォール・ローゼ] => 4
    [コニー] => 3
    [故郷] => 3
    [ライナー] => 3
    [仲間] => 3
    [力] => 3
    [エルヴィン] => 3
    [大型] => 3
    [ベルトルト] => 3
)
```
おー！なんかそれっぽい(∩´∀｀)∩

# 実際に試してみて分かったことと課題

### 形態素解析って難しそうだけど、案外簡単に試せる。
```「形態素解析を試す その2」```の方法を使えば、```タグクラウド```とか簡単に実装できそう(な気がする笑)。

### でも、実は奥が深そう。

例えば、```「形態素解析を試す その2」```の

```
    [カサ] => 6
    [ミ] => 6
```

は、本来は「ミカサ」という登場人物の名前のはずが、「ミ」と「カサ」に分解されている。
これは```辞書```に「ミカサ」という単語がなかったことが原因なので、```辞書のチューニング```が形態素解析の肝になりそう。

ただ、こんな１つ１つ細かい単語まで対応するのは大変……と思っていろいろ調べてみると、、、

 - [mecabにwikipediaのタイトルリストを追加する](http://log.miraoto.com/2012/11/703/)
 - [mecabにはてなキーワードのタイトルリストを追加する](http://log.miraoto.com/2012/11/705/)

というようなページが結構出てくる。

おお！なるほど、```Wikipedia```や```はてなキーワード```に出てくる単語を辞書に使えば、```単語の網羅率```に加えて```現代的な表現```にも対応した辞書が作れそうだ。

次回は辞書のカスタマイズ(＝ユーザ辞書の作成)を試してみよう(σ・∀・)σ