SciPy.sparse.linalg.svd是否给出矩阵秩



我有一个较大的稀疏二进制值矩形矩阵,M,其中nM。我对矩阵秩的理解表明,最大可能的秩是m,我对SVD的理解表明矩阵的秩可以通过识别非零奇异值的数量来找到。

我正在尝试使用SciPy.sparse.linalg.svd来确定m的级别。第一个问题是我不能计算m奇异值,因为k只能上升到p=m-1。所以我觉得我应该很聪明,计算p最高值和p最低值,将它们组合起来,运行set来找到唯一的值,最后得到一个最多m值的列表。这没有按计划进行。

这是MWE:

import scipy.sparse
import scipy.sparse.linalg
import numpy
import itertools  
m = 6
n = 10
test = scipy.sparse.rand(m, n, density=0.25, format='lil', dtype=None, random_state=None)
for i, j in itertools.product(list(range(m)), list(range(n))):
test[i, j] = 1 if test[i, j] > 0 else 0
U1, S1, VT1 = scipy.sparse.linalg.svds(test, k = min(test.shape) - 1, ncv = None, tol = 1e-5, which = 'LM', v0 = None, maxiter = None, 
return_singular_vectors = True)
U2, S2, VT2 = scipy.sparse.linalg.svds(test, k = min(test.shape) - 1, ncv = None, tol = 1e-5, which = 'SM', v0 = None, maxiter = None, 
return_singular_vectors = True)
S = list(set(numpy.concatenate((S1, S2), axis = 0)))
len(S)

以下是输出示例:

10

S

[0.5303120147925737,
1.0725314055439354,
2.7940865631779643,
1.5060744813473148,
1.8412737686034186,
0.3208993522030293,
0.5303120147925728,
1.072531405543936,
1.5060744813473153,
1.841273768603419]

mXn矩阵与m<n是否具有n的秩?我上面的假设是错误的,还是我误用了函数?我的实数M是稀疏的,二进制值,大约为300 X 500。

谢谢你的光临!


在@tch的帮助下,我想出了以下破解方法。要检查rank=m,我只需要检查最小的值,并将其附加到从svds最高值函数获得的m-1值。事实证明,svds在阈值化时不会报告0s,因此最低值函数将为rank<m。这是修改后的代码:

import scipy.sparse
import scipy.sparse.linalg
import numpy
import itertools
m = 6
n = 10
test = scipy.sparse.rand(m, n, density=0.25, format='lil', dtype=None, random_state=None)
test = test > 0
test = test.astype('d')
U1, S1, VT1 = scipy.sparse.linalg.svds(test, k = min(test.shape) - 1, ncv = None, tol = 1e-5, which = 'LM', v0 = None, maxiter = None, 
return_singular_vectors = True)
U2, S2, VT2 = scipy.sparse.linalg.svds(test, k = 1, ncv = None, tol = 1e-5, which = 'SM', v0 = None, maxiter = None, 
return_singular_vectors = True)
S = list(set(numpy.concatenate((S1, S2), axis = 0)))
print(sum(x > 1e-10 for x in S))
S

您试图做的是精确算术(假设矩阵没有重复奇异值)。然而,由于数值舍入误差,它在实践中不起作用。

要查看此信息,请尝试

C = np.random.randn(10,3)
u,s,vt = np.linalg.svd(C@C.T)

注意,C@C.T是秩为3的10x10矩阵。但是,您将看到没有一个奇异值完全为零(但是7接近0)。

当用数值计算矩阵的秩时,阈值通常用于确定奇异值为0意味着什么。例如,低于1e-10的所有值都可以设置为零。

如果矩阵具有精确的秩k,希望您将看到k奇异值远离0,然后min(m,n)-k奇异值非常接近零。然而,根据矩阵的不同,甚至可能没有一个定义明确的"下降"。

因此,对于您的示例,您可以尝试删除彼此在某个阈值内的元素。然而,如果矩阵具有重复奇异值,这当然会遇到问题。

你可以运行最小的奇异值,看看有多少奇异值接近于零。假定矩阵至少为秩,因此第一个奇异值将为非零。

关于查找test[i,j] > 0的注意事项,您可以只查找test>0,它将给出一个布尔数组,其中True位于非零条目中,False位于其他条目中。您也可以将随机矩阵的dtype设置为bool,只要随机数为非零时,它就会是True

相关内容

  • 没有找到相关文章

最新更新