Pythonの特異値分解SVD (singular value decomposition)の速度を比較してみました。
NumPyで特異値分解SVDを実施していると、随分時間が掛かり、動作しているコアは1つでした。
調査
NumPyの高速化について調べてみると、以下の記事でPython3とOpenCV3の環境構築に利用したAnacondaが、マルチコアを有効活用できるIntel MKL (Math Kernel Library)に対応していることがわかりました。
また、以下の記事でNumPyのSVDの代わりにscikit-learnのtruncated SVDを使用すると高速化できることがわかりました。
http://blog.explainmydata.com/2016/01/how-much-faster-is-truncated-svd.html
速度比較
実際に速度を比較してみました。
下の左図がMKL非対応のSystemのNumPyとscikit-learnを使用したとき、下の右図がMKLに対応したAnacondaのNumPyとscikit-learnを使用したときの結果です。
縦軸は処理時間なので、MKL非対応NumPyのSVDが特に遅いことがわかります。
下の図は、上の図の縦軸のスケールを変更したものです。
ランク等の条件によって結果は異なると思いますが、大きな行列では、randomizedアルゴリズムのtruncated SVDが早い傾向にあるようです。Anacondaのscikit-learnもNumPyと同様にMKLに対応しているはずですが、scikit-learnのtruncated SVDについては、MKLの効果はほとんどないようです。
なお、NumPyのMKL対応を調べるには、以下のコマンドを実行します。
$ python -c "import numpy; numpy.show_config()"
MKL非対応の場合、
$ python -c "import numpy; numpy.show_config()" ... openblas_info: libraries = ['openblas'] ... lapack_opt_info: libraries = ['lapack', 'f77blas', 'cblas', 'atlas'] ... lapack_mkl_info: NOT AVAILABLE ... mkl_info: NOT AVAILABLE
MKL対応の場合、
$ python -c "import numpy; numpy.show_config()" ... openblas_lapack_info: NOT AVAILABLE mkl_info: libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread'] ... lapack_mkl_info: libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread'] ...
のような表示となります。
まとめ
Pythonの特異値分解SVDについて調査してみたところ、NumPyのSVDについては、AnacondaのNumPyを使用することで高速化できることがわかりました。また、NumPyのSVDよりもscikit-learnのtruncated SVDを使用すると高速化できることがわかりました。