About connecting the dots.

data science related trivial things

PythonのnimfaでNMFを試す

PythonでNMFやるには,nimfaというパッケージを使えばよいらしいです.とりあえず使うだけなら,適当なnumpy行列vecを用意して,以下のように関数に投げてあげます.

factor = nimfa.mf(vec, seed='random_vcol', method='nmf', rank='5', max_iter=10)
res = nimfa.mf_run(factor).basis()

とりあえずシードはランダムで,手法はベーシックなnmf.何次元に削減するかをrankで指定して,イテレーション回数を決めればOKです.

nmfは関連手法が山ほどあって,ざっと以下のようになります.説明文は基本的に意訳です.正直意訳があってるかも自信はないので,こちらから元論文を読みましょう*1

手法 概要
BD ギブスサンプラーを使ったベイジアンNMF
BM バイナリのMF
ICM Iterated conditional modesを用いたNMF*2
LFNMF 局所特徴量を用いたフィッシャーのNMF
LSNMF 最小二乗法を用いたNMF
NMF 通常のNMF(更新式としてユークリッド/KL情報量,損失関数としてFrobenius/divergence/connectivityが指定可能)
NSNMF non-smoothなNMF
PMF 確率的NMF
PSMF 確率的スパースMF
SNMF 最小二乗制約に基づく非負性を用いたスパースNMF
SNMNMF スパース正則化ネットワークNMF
PMFCC 制約クラスタリングによる罰則MF

ということで,実際に回してみました.前回のマンションポエムデータ,218サンプル*1797次元のデータを10次元に圧縮します.これを10回繰り返して得られた10の圧縮行列に対して,適当なidを選んで類似度上位10件のデータを抜き出し,その一致度を集計しました.

結果は以下の通りで,時間がかかるものほど一致率も高く安定的な結果ということのようです.とはいえ安定しているから結果が良いかというと,パッとみた感じそんなに手法ごとに精度の差が歴然としているかといわれると,若干首をひねらざるを得ない感はあります*3.にしても,全体的に安定性はイマイチです... そしてBDとかPMFとかは,とにかく重すぎてパパッと結果も帰ってこず.まぁギブスサンプラーとか使ってたら思いに決まってるわけですが...

手法 一致度 NMFの算出にかかった時間 [秒]
NMF 16.7% 0.45秒
LSNMF 30.4% 0.94秒
BMF 17.8% 0.33秒
SNMF 40.7% 47.95秒

もう少しちゃんとパラメタとかチューニングしないといけないなぁという思いしかない.

*1:自分は読んでないです.

*2:この資料をみる限りICMは画像の復元手法として用いられているものみたいですね.

*3:単に類似性を目でみて判断しただけなので,完全にただの印象ではあります.