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行くらいで実装できたので、結構シンプルに書けるものだなと思いました。(式の導出はとても大変でしたが)