2011年11月8日火曜日

PHPで潜在的意味解析

芸能人の相関関係を探ってみる。

redsvdのチュートリアル

誰かの論文

単語と意味属性との共起に基づく概念ベクトル生成手法


これをニュースの記事でやってみる。
基本的に、PHPを使う。


1、ニュースのタイトルと本文を取得
① phpの関数simplexml_load_fileで、rssからタイトルとかURLとか取得できる。
PHPでRSSを読み込む方法

② 下記のサービスをつかえば、全文配信にしてくれる。
http://fulltextrssfeed.com/
※ 本文はdescriptionタグに入れられる。

余計なタグは、「strip_tags」という関数で除去することができる。



2、共起行列の作成

① mecabを使い、本文からキーワードを抽出。
しかし、でふぉの辞書ではいまいち。下記をやってみる。
mecabのユーザ辞書でwikipediaとhatenaキーワードを利用する
辞書の場所 : /usr/local/lib/mecab/dic/ipadic
使う辞書の設定 : /usr/local/etc/mecabrc


② RMecabを使う。

(1)CentOS5.5で、yumでRをインストール
※1 urlは「http://rm.mirror.garr.it/mirrors/CRAN/bin/linux/redhat/el5/x86_64/」二変更
※2 「libtcl」「libtk」を入れる。
※3 どうやら「R-core2.0」は最新ではないらしい。
rpmforgeをいれ、yum listすると「R-core2.3」がインストールできた。

(2)RMecabをインストールする。
※1 tar.gzは、R-2.13.0用からダウンロードする。
※2 wgetでダウンロードできなかったから、別マシンで落として、winscpで送った。
$ sudo tar -xvzf RMeCab_0.95.tar.gz
$ sudo R
> install.packages("RMeCab_0.95.tar.gz", destdir=".", repos=NULL)
> library(RMeCab)    ↓(3)を忘れるとエラーが出る。


(3)libmecab.so.1: 共有オブジェクトファイルを開けません
※1 /etc/ld.so.conf.d/mecab.conf を作成。
※2 /usr/local/libのままでよい。
※3 $ sudo /sbin/ldconfig を実行。


(4)RMeCabを使う。

$ R
> library(RMeCab)
> RMeCabC("すもももももももものうち")
> res <- docMatrix("doc", pos = c("名詞", "形容詞", "助詞"), weight = "tf*idf")
> res
> q()


③ phpで書く。
RMeCabをPHPから使うのはめんどくさそうだったので、
PHPで直接書いた。
行に文章、列に抽出した全語句を割り当て、
共起行列を作成した。



2、特異値分解処理(次元圧縮)
PHPで行列の計算をするのはめんどくさそう。
考えた選択肢としては、

① PHP行列計算ライブラリを使う。

見つからないかった。


② redsvdを使い、行列計算用 PHP Extensionを作成する。
redsvdを使うためには、eigen3をインストールする必要がある。
また、c++なので、Extensionを作成し、PHPから使えるようにする必要がある。
つまり、作ろうとしている潜在意味解析モジュールを使おうとしたら、
Extensionのいんすとーる、eigen3のいんすとーる、redsvdのいんすとーるを
する必要がある。
ちょっとめんどい。

③ eigen3を使い、行列計算用 PHP Extensionを作成する。
redsvdを使わなくても、eigen3だけでも特異値分解は可能。
これなら、
Extensionのいんすとーる、eigen3のいんすとーる、だけでよい。
まだまし。
そのためには、

・ eigen3の使い方調べる。
・ C++でphp extensinoを作る方法の調査
・ PHP extensionで、配列を受け渡す方法を調べる。

c++でphp extensionを作成する。


また、次元圧縮は、引数で、その割合を指定できるようにする。

てかそもそも、全部 PHP Extensionに押し込めるか。
共起行列の作成とかも、全部、PHP Extensionに押し込めないかな。。
ただ、データの受け渡しがチョイ不安なので、
今は、行列計算の部分だけにしとく。



3、特徴ベクトルの作成
共起行列Aを特異値分解すると、以下の3つに分解される。

A = U * S * V.transpose

U : 左特異行列 (文書の特徴を表す)
S : 特異値行列
V : 右特異行列 (語句の特徴を表す)
※ transposeは転置行列

括弧内は、行を文書、列を語句としたときの、
行列が表す意味。
この分解の特徴として、
特異行列の次元を小さくして、Aを復元すると、
Aを近似した行列を求められる点。


① 文書同士を比較したい場合は、
Uの1行を文書の特徴ベクトルとして、コサインをとれば、
1~-1の範囲で、文書の特徴を評価できる。

② 語句であれば、Vのベクトル。

③ 文書と語句の関連性は、復元したAの近似行列の
各要素の大きさで評価できる。

④ 特異分解するときAに含まれていない文書を評価したいときは、
V, Sを使って、Uの特徴ベクトルを作成することができる。

U_Vector = T_Vector.transpose() * V * S.inverse
※ transposeは逆行列

このU_Vectorと、Uの特徴ベクトルでコサインを計算すれば、
①と同様に評価できる。



4、コサインの計算
計算する。


5、感想
ここまで作って見たが、
ニュース同士の関連を数値化することはできたが、
その精度には疑問が残る。

・ もっと対象とする文書、語句を大きくして、潜在意味空間を広げるか。
・ 文書、語句の範囲を絞り、潜在意味空間の質を上げるか。

もうちょっと検討の必要あり。

0 件のコメント:

コメントを投稿