まぃふぇいばりっと

機械学習やってます.Julia大好きです.勉強したことの殴り書きです.

Python SVDによる低ランク近似

PythonでSVDで入力行列Aのランクをrankに落とすプログラム. ちなみに,C++バージョンはこっち

import numpy as np
import scipy as sp

def SVD(A, rank):
    u, s, v = np.linalg.svd(A)
    ur = u[:, :rank]
    sr = np.matrix(sp.linalg.diagsvd(s[:rank], rank, rank))
    vr = v[:rank, :]

    Rr = ur*sr*vr

    return Rr

ちなみにこのコードだと,O(n3)かかる.Arpack使うと,O(n2 r)でできるはず... scipy.sparse.linalg.svds を参考.(スパース行列じゃなくてもできる)

噂では,sklearn.decomposition.truncatedSVD も使えるようだ. 計算量をさらにO(n2 log r + r2 n)まで落とすこともできるようで,これはこちらの論文に載っている(らしい.私は読んでない)