2011-02-11 154 views
5

我想将一些代码从Matlab移植到Python,并且遇到了问题。我似乎无法找到相当于svds的。Python:相当于Matlab的大数组svds(A,k)?

我试过使用numpy.corrcoef,然后numpy.linalg.eig,但numpy.corrcoef不适用于大型数组(例如500 x 20000)。

这里是在MATLAB代码,如果这有什么差别:

s = size(data, 2) 
mean = sum(data, 2)/s 
m_data = (data - repmat(mean, 1, s))/sqrt(s - 1) 
[res_u,res_s] = svds(m_data, s) 
eigenvals = diag(res_s).^2 
eigenvecs = res_u 
+0

`numpy.linalg.svd`还不够? – kwatford 2011-02-11 22:55:01

+0

@kwatford问题不是eig/svd,它是corrcoef。为了让eig或svd工作,我必须先使用corrcoef。那么,用我目前的方法。可能有另一种方法来处理它,我不知道。 – digdin 2011-02-11 22:59:47

回答

2

如果你的矩阵是稀疏的,你可以在最近的SciPy的分配使用scipy.sparse.linalg.svds。它将稀疏的SVD例程包装在ARPACK中。根据我的经验,这是错误的(不确定这是scipy还是ARPACK的错误),所以我建议运行测试以检查奇异值是否与预期一致。

如果您的矩阵很密集,那么在商品桌面上,500乘20000会很大,但在商品桌面上难以处理。你调用numpy.linalg.svdfull_matrices=False,对吧?

你在用什么numpy.corrcoef?没有那样的东西出现在你发布的MATLAB代码片段中。

3

您正在寻找这样的内容,会是这样的pythonnumpy(我冒昧不“直接翻译”的matlab -code到pythonnumpy,而是我重构它一点点地“的感觉“更pythonic [of'course颇为相似的重构可以应用到matlab -code以及]):

import numpy as np 

def _cas(D): 
    """Center at mean and standardize.""" 
    return (D- D.mean(1)[:, None])/ (D.shape[1]- 1)** .5 

def example(D): 
    """Eigenvalues and -vectors, based on SVD.""" 
    u, s, v= np.linalg.svd(D, full_matrices= False); 
    return np.diag(s)** 2, u 

if __name__ == '__main__': 
    data= np.random.rand(5, 20) 
    data= _cas(data) # preprocess data according to your requirements 
    eigenvals, eigenvecs= example(data) 
    print eigenvals 
    print eigenvecs 

但你必须与它的性能问题?

您现在可以更具体地了解您当前的表现,以及您真正期望应该增强多少?在我的普通计算机上的FTIW中,随机(500,20000)矩阵将花费大约20秒执行example(.)

我可以平凡(由于基本的线性代数)将执行时间降低到2.5秒的水平(总共提高10倍)!现在,如果您正在寻找比此更好的性能,请详细说明您的data的“性质”!

您的数据来自哪里?利用计算出的特征值和 - 矢量的具体情况是什么?即你的主要目标是什么?