洋食の日記

「だ・である」調ではなく「です・ます」調で書きはじめれば良かったなと後悔してる人のブログです

SVMKitにクラスタリングと行列分解を実装した

svmkit | RubyGems.org | your community gem host

クラスタリングはK-MeansとDBSCAN、行列分解は主成分分析(Principal Component Analysis, PCA)と非負値行列因子分解(Non-negative Matrix Factorization, NMF)を実装した。K-Meansは、K-Means++による初期値設定を実装した。PCAはベーシックなアルゴリズムでは固有値分解が必要になるが、Numo::NArrayには固有値分解はない(Numo::Linalgにある)ので、今回は不動点法(Fixed-point algorithm)によるものを実装した。DBSCANとNMFはベーシックな手法を実装した。

これ以前に、0.4系では、RMSPropやNADAMといったOptimizerを実装した。Optimizerは深層学習で使われるイメージが強いが、最適化法が確率的勾配降下法(Stochastic Gradient Descent, SGD)であれば、SVMやロジスティック回帰でも有効である。動機としては、SGDなFactorization Machine(FM)が安定せず、その解決策に導入した。FMは、勾配に二乗が含まれるため、学習率のスケジュールがシンプルだと、一時的にでも大きな値が入ると、NaNが出まくるということがあった。また学習率の初期値が適切ではないと、ものすごく低い分類精度になったりした(これら最初は実装誤りを疑ったがlibfmなどでも同じ現象が見られた)。RMSProp系のOptimizerは、勾配を正規化するような形の学習率を求めるので、FMにおいて多少勾配が大きくなっても、NaNが出まくるような暴走はしなくなった。

これで、SVMKitでは、教師あり学習(分類・回帰)と教師なし学習(クラスタリング・次元圧縮)の基本的なことができるようになった。これからはコード整備とパフォーマンスの向上をメインに据えつつ、ちょこちょことアルゴリズムを増やしていこうと思う。