old school magic

機械学習と統計とプログラミングについてちょっとずつ勉強していきます。

ディリクレ過程ガウス混合モデルの Python 実装(「続・わかりやすいパターン認識」ノート)

続・わかりやすいパターン認識―教師なし学習入門―

続・わかりやすいパターン認識―教師なし学習入門―

「続・わかりやすいパターン認識」12章のディリクレ過程ガウス混合モデル(DPGMM)を Python で実装してみました。
コードはこちら。
http://nbviewer.ipython.org/github/breakbee/PyNote/blob/master/Implementation_of_DPGMM.ipynb

参考
wishart and inverse wishart sampler
ウィシャート分布 - MATLAB & Simulink - MathWorks 日本

掲載されているアルゴリズムでは、

  1. 中華料理店過程(CRP)で潜在変数(クラスタ)のサンプリング
  2. パラメータの更新
  3. 潜在変数とパラメータの事後確率が前より大きくなるようなら新しい値に更新

という3つのステップを何度も繰り返し、事後確率が収束すれば終了、というアルゴリズムですが、今回は簡単のため、ステップ1と2を繰り返すことにしています。
(つまり、事後確率が大きくなるにしろ小さくなるにしろ潜在変数とパラメータを更新しています。)

実際にDPGMMを適用した結果はこんな感じになりました。(初期クラスタ数は1に設定)

f:id:breakbee:20141008030539p:plain

ちゃんと適切な混合数を選択できていることが確認できました。

実装していて分からなかったのですが、CRPで潜在変数をサンプリングしている時、新しくクラスタが増えた場合、そのクラスタのパラメータも同時に生成する必要があると思うのですが、基底測度(というか事前分布)からサンプリングすれば良いのでしょうか?
とりあえず適当に初期化したパラメータを新規クラスタに与えたところ、一応期待通りの動作をしているのですが、あまり厳密ではないかもしれません...

ともあれ、DPGMM自体は130行くらいで実装できたので、結構シンプルに書けるものだなと思いました。(式の導出はとても大変でしたが)