ブログの方で数式を扱えるようになったので加筆修正は今後はブログで行う予定です。こっちの更新は行いません。悪しからず。
まあ今のところ大きな変更はないですが。
おばんです! localminと申します。現在M2で、普段の研究ではあえてぼかした言い方をすると行列演算について考えたり、パソコンをカタカタしています。本記事は#今年読んだ一番好きな論文2018の11日目の記事です。本記事でも少し古いですが行列にまつわる論文について紹介していきたいと思います。
非負値行列因子分解(Non-negative Matrix Factorization)(以下NMFとします)の高速化に関する論文です。NMFは反復更新式を用いて最適化を行いますが、既存手法では全変数を等しく更新(要するに更新しなくてもよい要素を更新してしまう)という欠点があります。この論文では目的関数にフロベニウスノルムの二乗を用いたときに、必要な変数のみを選択し更新を行う手法を提案をしています。
また目的関数にKL-divergenceを用いた場合の新しい手法も提案してます(ただし変数選択は用いない)。
各提案手法と既存手法を実データを用いて比較を行い、提案手法の収束の速さを確認してます。
…と小難しく書きましたが、これからなるべくわかりやすく説明していく予定です。たぶん。
もちろん今年読んだ中で印象に残った論文だからというのもありますが、
といった理由もあります。この記事をきっかけにNMFにはMultiplicative Updateだけでなく、速いアルゴリズムがあるよ!ということを少しでも理解してもらえば冥利に尽きます。
っていうか速いアルゴリズムってかっこいいじゃないですか!!(個人の感想)
NMFについては論文内でも説明されていますが、少しあっさり風味なのでここでは少し詳しめに説明します。
世の中のデータには非負値の行列で表現できるものが多々あり(例えばテキスト、画像、音響信号のパワースペクトルなど)、その特徴を解析したいといった需要があります。
NMFは各要素が非負で与えられる行列を二つの非負値行列の積に近似分解してあげる手法です。具体的には各要素が非負である観測行列
NMFはいわゆる次元削減と呼ばれる手法に分類され、観測行列をより小さなランクの行列で近似することを目的とします。
行列に馴染みがある人は基底行列、係数行列と言われてすぐにわかるかもしれませんが、そうでない人のためにもう少し詳しく説明すると、
観測行列
と表現することができます。
すなわちNMFは観測行列の各列を
線形結合に使用されるベクトル(基底)を格納した行列なので基底行列、そして線形結合に置ける係数を格納した列ベクトル
NMF以外にも行列を分解する手法で有名なものに特異値分解(SVD)や固有分解(スペクトル分解)などがあります。しかし非負値行列を適用した場合に、分解した結果に負の値が出現してしまったり、得られるベクトルが直交してしまうため、結果の解釈が難しくなる欠点が存在します。
そこでNMFでは与えられたデータはもちろん、分解結果にも非負の制約与えることでデータの見通しが良くなる長所があります。また分解して得られた基底ベクトルは必ずしも直交しません。
次にどうやって
人によっては行列を二つの積にバラすのは簡単では?と思う人もいるかもしれません。でもそれは具体例をみれば難しいとわかるでしょう。
では以下の方程式をを
どうですか?難しくないですか?っていうかそもそも解あるのか?ってなると思います。実際のデータは何百、何千のサイズになるのでもっと大変です。
実際にこのような行列
ここで目的関数を用意します
この式は観測行列
よってNMFは上述の関数を最小化するような
この論文では反復更新の方法として一変数ごとの座標降下法を用いています。具体的には
のような更新を収束するまで行います。
座標降下法ではある一つの要素に注目して他の変数は固定し、その変数での部分最適化問題を解くということを繰り返していくことになります。
この式から読み取れるのは
ではどんな
要するに
となり、
という結果になります。max関数を使用することで非負性を保持できます(実際に値が負になるような数値を代入してもmax関数のおかげで0になります)。
これによって
と更新することができます(ちなみに
従来手法(Multiplicative Update[2], FastHALS[4])では上に似たような更新式を導出した後、全変数に対して等しい回数更新を行います。しかし、その場合更新しなくても良い変数を更新してしまうという欠点があります。ここでいう更新しなくても良い変数とは、更新しても目的関数の値が減少しない変数のことであり、そのような変数を更新してしまうことで余計な計算量をくうことになります。
よってこの論文では重要な変数、すなわち目的関数の値を大きく減少させることができる変数のみを選択し貪欲に更新し続ける手法を提案しています。
まず変数選択法の説明の前に更新手順について説明します。この論文では便宜上、注目する行列を変えることをOuter Iteration、注目している行列内での更新をInner Updateとしています。
Outer Iterationでは
そして一回のOuter Iterationの間にInner Updateという行列内の更新を行います。
実際の変数選択はInner Update内で行います。
要するに、
といった処理を目的関数の値が収束するまで繰り返す、これが基本的な流れになります。
変数選択の方法はシンプルで、目的関数の減少量が多い変数を選択します。そのために
当然のことながら更新を行えば
よってこのオーバーヘッドを軽減するために
以下の式で
これらの計算量は
これがこの論文のキモであり、変数選択による計算の軽減に成功しています。
このことから更新が各行列に及ぼす影響は
そのため
のようにして選択されることになります。
このように変数選択しながらを更新していく手法をGreedy Coordinate Descent(以下GCD)と論文では名付けています。いいかんじですね。
いろいろややこしいことを書いてきましたが要は速いのかって話ですよ。実データを用いて実験をします。この論文では二種類の実験を行なっています。
一つは密なデータに対して、もう一つはスパースなデータに対してです。
比較する手法はGCD、FastHALS[4]、ProjGrad[5], BlockPivot[6](あれ?Multiplicativeは?)。
各アルゴリズムにおいてデータセット毎に設定した相対誤差になるまでの計算時間及び浮動小数点数演算の回数(FLOPs)を比較します。
もちいたデータは以下のようになっています。
dataset | m | n | k | relative error | GCD | FastHALS | ProjGrad | BlockPivot |
---|---|---|---|---|---|---|---|---|
Synth03 | 500 | 1000 | 10 | 0.6/0.7G | 2.3/2.9G | 2.1/1.4G | 1.7/1.1G | |
Synth03 | 500 | 1000 | 30 | 4.0/5.0G | 9.3/16.1G | 26.6/23.5G | 12.4/8.7G | |
Synth08 | 500 | 1000 | 10 | 0.21/0.11G | 0.43/0.38G | 0.53/0.41G | 0.56/0.35G | |
Synth08 | 500 | 1000 | 30 | 0.43/0.46G | 0.77/1.71G | 2.54/2.70G | 2.86/1.43G | |
CBCL | 361 | 2429 | 49 | 0.0410 | 2.3/2.3G | 4.0/10.2G | 13.5/14.4G | 10.6/8.1G |
CBCL | 361 | 2429 | 49 | 0.0376 | 8.9/8.8G | 18.0/46.8G | 45.6/49.4G | 30.9/29.8G |
CBCL | 361 | 2429 | 49 | 0.0373 | 14.6/14.5G | 29.0/75.7G | 84.6/91.2G | 51.5/53.8G |
ORL | 10304 | 400 | 25 | 0.0365 | 1.8/2.7G | 6.5/14.5G | 9.0/9.1G | 7.4/5.4G |
ORL | 10304 | 400 | 25 | 0.0335 | 14.1/20.1G | 30.3/66.9G | 98.6/9.1G | 33.9/38.2G |
ORL | 10304 | 400 | 25 | 0.0332 | 33.0/51.5G | 63.3/139.0G | 256.8/193.5G | 76.5/82.4G |
表での各手法の値はTime(in seconds)/FLOPSを表しており、小さいほどいいです。いずれの場合もGCD(提案手法)が高速であることがわかります。 |
比較する手法はGCD, FastHALS[4]、BlockPivot[6]。
もちいたデータは
時間における相対誤差の推移を計測しています。
論文7ページFigure2のグラフを見てください(重ね重ねごめんなさい…)。この場合も提案手法が高速かつ良い局所最適解に達していることがわかります。
論文での実装はMATLABです。しかしMATLABはforループが遅いため、GCDの反復部分をmex(Cで作った関数を呼び出す)で高速化しているそうです。
公平な比較じゃない気がしますが、筆者曰くFLOPsでも比較してるから公平性はあるとのこと。あまり腑に落ちないですが。
時間がないので今回は概略にととどめますが、この論文ではKL-divergenceにおける新しいアルゴリズムも提案しています。
フロべニウスノルムの二乗の場合と異なり、変数選択は用いない循環座標降下法(CCD)になっています。
更新幅
この手法は同じ密なデータでMultiplicative Updateと比較されており、高速化に成功しています。
結果は論文8ページTable3。
ただKL-divergenceに関しては2012年にsBCD[7]というより高速な手法が提案されています…。
本論文では目的関数がフロべニウスノルムの二乗に用いた時に、変数選択を用いた座標降下法を提案しました。またKL-divergenceにおいてもニュートン法を利用した循環座標降下法を提案しました。この二つの手法に関して実データを用いて実験を行い、高速化に成功したことを確認できました。
以上が論文の内容になります。KL-divergenceの話もそうですが、収束の保証の議論、Inner Updateの停止条件、各ステップでの計算量の議論などここに書ききれなかった話が論文にはあるので興味がある人は是非。
フロべニウスノルムの二乗を用いた際のNMFの高速化に関しては、この論文の手法(GCD)現在が最速だと思われます。そう、この場合の高速化に関してはこの論文(2011)を最後に終わってしまったのです(もしあったら是非教えて下さい!)。かっこいいですね。僕も一分野を終わらせる論文を書いてみたかったです。
ただGCDはあまり人気がなく、基本的にNMFに使用されているアルゴリズムはMultiplicative Updateが多い印象です。実装が明らかにMultiplicative Updateの方が簡単で、欲しい結果が得られているからなのかなーとか思いますが実際のところはわかりません。おしえてエロい人。
NMFの研究は現在も続けられており、毎年多くの論文が出ています。特にNMFの亜種や使用条件を絞った場合に性能を向上させる手法などが多い印象です。それには現実に欲しい結果と誤差の小ささが必ずしも関係してないことや、初期値依存性(反復更新の際にどの初期値を入れるのがベストかは基本不明な問題)など、残された問題や改良できる余地が多くあるからだと思います。とにかく今後も目が離せないですね。
来年からは少なくとも仕事で論文を読むようなことはないでしょうが、せっかく大学で論文を読む能力を身につけたのだから、年に一回こういう場でアウトプットできるぐらいには論文を読んでいきたいと思います。
これを読んでNMFに興味を持った方はぜひ参考にしてみてください。
[1]. Fast Coordinate Descent Methods with Variable Selection for Non-negative Matrix Factorization :今回紹介した論文です。コードは筆者のホームページに公開されています。
[2]. Learning the parts of objects by non-negative matrix factorization:NMFが最初に世に出た時の論文です。
[3]. Algorithms for Non-negative Matrix Factorization:一番有名なNMFのアルゴリズムであるMultiplicative Updateの論文です。
[4].Fast local algorithms for large scale nonnegative matrix and tensor factorizations:FastHALSの論文です。
[5]. Projected gradient methods for nonnegative matrix factorization:実験の比較に出てきた手法です。
[6]. Toward Faster Nonnegative Matrix Factorization: A New Algorithm and Comparisons:実験の(ry
[7]. Fast Bregman Divergence NMF using Taylor Expansion and Coordinate Descent:2012に出てきた手法です。僕はこの手法はFastHALSの一般化と解釈しています。
非負値行列因子分解:NTT研究所の方によるNMFの解説記事です。非常にわかりやすいです。
Nonnegative Matrix Factorization:NMFの最適化法についてのまとめ:色々なNMFのアルゴリズムの概説が載っています。
誤字脱字の指摘から記事の内容に関するツッコミなどなんでも歓迎です!
twitterアカウントlocalminやメールアドレス localmin9201009"at"gmail.comまでお願いします!