Pystanで自然言語処理 scikit.learnのdatasetで試す
scikit.learnは様々な機械学習のアルゴリズムのみならず、データセットも充実しています。stanのpythonラッパーpystanでこれを利用し、Stan manualのLDAのコードの性能を評価することを行いました。
20 newsgroupsというデータセットは名前の通りUsenetの20のカテゴリー、20000の文書(英語)からなるデータセットです。
これをsklearn.feature_extraction.text のCounterVectizerを用いて単語数をカウントした行列形式に変換し、Stanのコードに入力します。
コードは以下のようになります。
行列は疎行列形式で保存されているのでこれを変換し、またStanの添え字形式である1始まりに変換します。beroberoさんが高速化のために書かれたコード(あらかじめ計算しておいた各wordの頻度を用いて尤度を足し合わせる)にあわせています。
計算には非常に時間がかかってしまっています(document数100,iteration 1000で5時間程度 stop wordsを有効にすることで大幅に速度が改善しました。)。 θとして出力されるtopic index(ラベル)は正解に当たる値と同じになるとは限らず、計算の実行結果によっても一般に異なるので、ここではchain=1としなければいけませんでした*1。
よりLDAに特化した、洗練された実装を利用すべきだと思いました。
結果
docnum=40
iteration=500
stop _wordを有効にした場合
thetaの推定値の分布(中央値のみ)です。
|*original topic id |*docid|*topic1|*topic2|*topic3|*topic4|
|1|0|0.6|0.0|0.1|0.3|
|2|1|0.1|0.2|0.0|0.6|
|1|2|0.9|0.0|0.0|0.0|
|3|3|0.3|0.2|0.2|0.3|
|2|4|0.1|0.8|0.1|0.0|
|3|5|0.1|0.2|0.7|0.0|
|2|6|0.8|0.1|0.0|0.1|
|2|7|0.0|0.0|1.0|0.0|
|0|8|0.2|0.1|0.7|0.0|
|0|9|0.0|0.1|0.9|0.0|
|2|10|0.9|0.0|0.0|0.0|
|0|11|0.0|0.8|0.2|0.0|
|2|12|0.1|0.0|0.1|0.8|
|2|13|0.4|0.4|0.2|0.0|
|3|14|0.0|0.2|0.8|0.0|
|0|15|0.0|0.9|0.0|0.0|
|0|16|0.0|0.9|0.0|0.0|
|1|17|0.6|0.0|0.3|0.0|
|3|18|0.1|0.0|0.8|0.1|
|1|19|0.6|0.1|0.1|0.1|
|0|20|0.0|0.8|0.0|0.1|
|2|21|0.2|0.6|0.1|0.1|
|2|22|0.9|0.0|0.1|0.0|
|2|23|0.8|0.1|0.1|0.0|
|1|24|0.8|0.1|0.1|0.1|
|2|25|0.3|0.1|0.2|0.4|
|2|26|0.9|0.0|0.0|0.0|
|3|27|0.0|1.0|0.0|0.0|
|0|28|0.1|0.8|0.0|0.1|
|1|29|0.9|0.0|0.0|0.0|
|1|30|0.9|0.0|0.0|0.1|
|0|31|0.0|0.9|0.0|0.0|
|2|32|0.0|0.0|0.0|0.9|
|1|33|0.0|0.0|0.0|1.0|
|3|34|0.0|0.8|0.1|0.1|
|1|35|0.1|0.0|0.0|0.9|
|2|36|0.1|0.6|0.2|0.0|
|1|37|1.0|0.0|0.0|0.0|
|3|38|0.1|0.0|0.9|0.0|
|3|39|0.1|0.4|0.0|0.4|
Rhatはほとんどの値で収束を示していますが、どうも元々のtopicと一致していないようです。
続く...
Reference
トピックモデルシリーズ 4 LDA (Latent Dirichlet Allocation)
LDAの実装としてはcollapsed Gibbs サンプリングというのがありLDAでいうθ、φを周辺化し、サンプリングしなくてよくできるそうです。
Latent Dirichlet Allocations(LDA) の実装について
https://github.com/shuyo/iir/blob/master/lda/lda.py
↓ほとんど「Pystanで自然言語処理」の内容になっていませんでした。
http://www.slideshare.net/xiangze/pystan-for-nlp
*1:これに対処するために最初にラベルの制約なしで推定を行い、試行の結果に対してラベルを入れ替えるようなMCMCで推定を行うような方法があるそうです。(Markov chain Monte Carlo Estimation of Classical and Dynamic Switching and Mixture Models またRのlabel.switchingパッケージもこれに関係しそうですがあまり調査できていません)