如何在Python中对低秩矩阵执行SVD分解?
低秩矩阵SVD分解Python实现方案
numpy自带的numpy.linalg.svd默认执行全秩分解,会返回所有奇异值及对应的正交矩阵,对于秩仅为10的80*50矩阵来说存在大量计算冗余,不符合低秩场景的使用需求,不需要完全自行手写SVD实现,有现成的优化方案可以直接使用:
方案一:使用scipy优化的截断SVD接口(推荐,低秩场景效率最高)
scipy.sparse.linalg.svds专门针对低秩、稀疏矩阵场景设计,可以直接指定返回前k个最大奇异值的分解结果,示例代码如下:import numpy as np from scipy.sparse.linalg import svds # 替换为你的实际矩阵 mat = np.random.rand(80, 50) # k设置为矩阵的秩10 k = 10 u, s, vt = svds(mat, k=k) # svds默认返回升序排列的奇异值,如需和numpy svd一致的降序结果,执行以下重排 s = s[::-1] u = u[:, ::-1] vt = vt[::-1, :]该方案计算复杂度远低于全秩SVD,尤其适合矩阵尺寸大、秩远小于矩阵尺寸的场景。
方案二:基于numpy原生svd做截断(适合无法安装scipy的场景)
你的矩阵尺寸很小,就算全秩分解开销也不大,可以直接取numpy svd结果的前k项即可:import numpy as np mat = np.random.rand(80, 50) u, s, vt = np.linalg.svd(mat, full_matrices=False) # 截断前10个最大奇异值对应的结果 k = 10 u = u[:, :k] s = s[:k] vt = vt[:k, :]
你提到的SAD运算可以基于上述截断SVD的结果重构低秩矩阵后计算,也可以利用奇异值的特性直接计算,不需要重构完整矩阵。
内容的提问来源于stack exchange,提问作者Madi
相关产品推荐
相关产品推荐

