読者です 読者をやめる 読者になる 読者になる

xiangze's sparse blog

機械学習、ベイズ統計、コンピュータビジョンと関連する数学について

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)

20 Newsgroupsで分類精度を評価

20 newsgroups

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パッケージもこれに関係しそうですがあまり調査できていません)