Python Numpy svd与Scipy.sparse svd

Python Numpy svd与Scipy.sparse svd,python,numpy,scipy,sparse-matrix,svd,Python,Numpy,Scipy,Sparse Matrix,Svd,我正在用Python实现稀疏待定系统的解算器(已讨论),并尝试使用svd的SciPy.sparse版本(SciPy.sparse.linalg.svd)在SciPy中重建使用标准numpy svd函数(numpy.linalg.svd)的nullspace函数但它为我运行的示例输出不同的左奇异向量和右奇异向量-包括矩阵: [[1,1,0,0,0],[0,0,1,1,0],[1,1,1,1,1]] [[1,0,1],[1,1,0],[0,1,1]] 为什么这两个解算器为上述矩阵生成两个不同的

我正在用Python实现稀疏待定系统的解算器(已讨论),并尝试使用svd的SciPy.sparse版本(
SciPy.sparse.linalg.svd
)在SciPy中重建使用标准numpy svd函数(
numpy.linalg.svd
)的nullspace函数但它为我运行的示例输出不同的左奇异向量和右奇异向量-包括矩阵:

[[1,1,0,0,0],[0,0,1,1,0],[1,1,1,1,1]]  
[[1,0,1],[1,1,0],[0,1,1]]
为什么这两个解算器为上述矩阵生成两个不同的svd输出?如何确保输出相同

编辑 这里有一个例子:表是一个
csc\u矩阵
,这样

table.todense()  = matrix([[1,1,0,0,0],[0,0,1,1,0],[1,1,1,1,1]],dtype=int64)
因此,下面的代码输出

numpy.linalg.svd(table.todense()) =  
[[ -3.64512933e-01   7.07106781e-01  -6.05912800e-01]  
[ -3.64512933e-01  -7.07106781e-01  -6.05912800e-01]  
[ -8.56890100e-01   2.32635116e-16   5.15499134e-01]]  
-----------------------------------------------------
[ 2.58873755  1.41421356  0.54629468]
-----------------------------------------------------
[[ -4.7181e-01 -4.7181e-01 -4.7181e-01 -4.7181e-01 -3.3101e-01]
[5e-01   5e-01  -5e-01  -5e-01 6.16450329e-17]
[-1.655e-01  -1.655e-01  -1.655e-01  -1.655e-01  9.436e-01]
[5e-01  -5e-01  -5e-01   5e-01 -1.77302319e-16]
[-5e-01  5e-01  -5e-01   5e-01 2.22044605e-16]]
以及以下

scipy.sparse.linalg.svds(table,k=2)=  
[[  7.07106781e-01,  -3.64512933e-01],
[ -7.07106781e-01,  -3.64512933e-01],
[  2.73756255e-18,  -8.56890100e-01]]
-------------------------------------
[ 1.41421356,  2.58873755]
-------------------------------------
[[  5e-01,   5e-01,  -5e-01, -5e-01,   1.93574904e-18],
[ -4.71814e-01,  -4.71814e-01,  -4.71814e-01, -4.71814e-01,  -3.31006e-01]]

请注意,两个解决方案之间有相当多的值重叠。另外,
scipy.sparse.linalg.svds
函数不允许k大于或等于
min(table.shape)
,这就是我选择k=2的原因。

我觉得您发布的问题中的输出很好。在numpy调用中,您计算每个奇异值,在scipy代码中,您只计算前k个奇异值,它们与numpy输出中的前k个奇异值匹配

稀疏顶k奇异值分解不允许你计算每个奇异值,因为如果你想这样做,你可以使用完整的奇异值分解函数

下面我为您提供了代码,供您自己检查。需要注意的是,尽管numpy和scipy full svd都可以很好地重新创建原始矩阵,但top k svd不能。这是因为您正在丢弃数据。通常情况下,这是很好的,因为你可以与足够接近。问题是,SVD如果与top k一起使用,则可以用作原始矩阵的低秩近似,而不是替换

为清楚起见,我在这方面的经验来自为原作者实现本文的python并行版本

等于

u,sigma,v = scipy.sparse.linalg.svds(A,k=min(A.shape[0],A.shape[1]))
u = -u[:,::-1]
v = -v[::-1,:]
sigma = sigma[::-1]

请你举一个输入数据的例子,看看你是如何运行这些函数和输出的?这将极大地改善这个问题。我会查看链接问题,我会在那里更好地解释它。对于这两个函数,
奇异值(
s
)是它们承诺的主要内容。k最大的
s
值匹配。SVD不是唯一的。看起来是个有用的答案。它讨论了截断的SVD,并提到了
ARPACK
实现,而
svds
也引用了它。MATLAB既有
svd
又有
svd
。也很有趣。我不知道svd不是独一无二的。这肯定会破坏我的计划。这很有趣。是否可以从截断的奇异值分解计算矩阵的零空间?如果没有,python中是否有针对稀疏矩阵的完整svd解算器?恕我直言,我不相信您可以使用截断的svd来计算空值空间,因为您需要所有的奇异值。稀疏版本和完整版本之间有两个主要区别。完整版本的速度快了一整倍(O(n^3)v O(n^4),但根据内存中矩阵的大小进行缩放。稀疏版本在内存中缩放非零的数量。在您的情况下,只要矩阵不太大,我就使用完整版本。您还可以查看是否需要稀疏。我使用的示例几乎不可能将矩阵存储在非稀疏版本中表单由于数据的大小。不幸的是,sparsesvd还计算一个截断的svd,所以我这里没有太多的选项。你知道一种硬编码完整svd的稀疏版本的方法吗?你有没有尝试过将稀疏矩阵传递给scipy.linalg.svd?是的,我得到了…我得到了这个函数不支持稀疏矩阵。可能是scipy函数之一.sparse.linalg函数将起作用。这是如何回答问题的?(这并不是说上面没有试图回答
为什么这两个解算器产生两个不同的svd输出
,或者无法正确执行-但是,请:explain.Heed)
u,sigma,v = numpy.linalg.svd(A)
u,sigma,v = scipy.sparse.linalg.svds(A,k=min(A.shape[0],A.shape[1]))
u = -u[:,::-1]
v = -v[::-1,:]
sigma = sigma[::-1]