SciPy.sparse.linalg.svds 是否给出矩阵秩?
Does SciPy.sparse.linalg.svds give matrix rank?
我有一个较大的稀疏二进制值矩形矩阵,M,其中 n > m.我对矩阵秩的理解表明最大可能的秩是 m,而我对 SVD 的理解表明可以通过识别非零奇异值的数量来找到矩阵的秩。
我正在尝试使用 SciPy.sparse.linalg.svds 来确定 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]
m X n 矩阵如何 m < n 的排名是 n?我的上述假设不正确,还是我误用了该功能?我的真实 M 是稀疏的二进制值,大约 300 X 500。
感谢观看!
在@tch 的帮助下,我想出了以下技巧。要检查 rank = m,我只需要检查最小值,并将其附加到从 svds 最高值获得的 m - 1 值功能。事实证明,svds 在阈值化时不报告 0,因此最低值函数将为 return nan for 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
是一个 10x10 矩阵,秩为 3。但是,您会看到 none 的奇异值恰好为零(但有 7 个接近于 0)。
在以数值方式查找矩阵的秩时,通常使用阈值来确定奇异值 0
的含义。例如,1e-10
以下的所有内容都可能设置为零。
如果矩阵具有精确秩 k
,希望您会看到 k
个奇异值远离 0
,然后 min(m,n)-k
个奇异值非常接近零。但是,根据矩阵,甚至可能没有明确定义的 "drop".
因此,对于您的示例,您可以尝试删除彼此之间某个阈值内的元素。但是,如果矩阵具有重复的奇异值,这当然会 运行 成为问题。
你可以只 运行 最小的奇异值,看看有多少让你接近于零。据推测矩阵至少是秩 ` 所以第一个奇异值将是非零的。
作为关于查找 test[i,j] > 0
位置的注释,您可以只输入 test>0
,它将给出一个布尔数组,其中非零条目为 True
,其他条目为 False
.您还可以将随机矩阵的 dtype
设置为 bool
,只要随机数非零,它就会 True
。
我有一个较大的稀疏二进制值矩形矩阵,M,其中 n > m.我对矩阵秩的理解表明最大可能的秩是 m,而我对 SVD 的理解表明可以通过识别非零奇异值的数量来找到矩阵的秩。
我正在尝试使用 SciPy.sparse.linalg.svds 来确定 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]
m X n 矩阵如何 m < n 的排名是 n?我的上述假设不正确,还是我误用了该功能?我的真实 M 是稀疏的二进制值,大约 300 X 500。
感谢观看!
在@tch 的帮助下,我想出了以下技巧。要检查 rank = m,我只需要检查最小值,并将其附加到从 svds 最高值获得的 m - 1 值功能。事实证明,svds 在阈值化时不报告 0,因此最低值函数将为 return nan for 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
是一个 10x10 矩阵,秩为 3。但是,您会看到 none 的奇异值恰好为零(但有 7 个接近于 0)。
在以数值方式查找矩阵的秩时,通常使用阈值来确定奇异值 0
的含义。例如,1e-10
以下的所有内容都可能设置为零。
如果矩阵具有精确秩 k
,希望您会看到 k
个奇异值远离 0
,然后 min(m,n)-k
个奇异值非常接近零。但是,根据矩阵,甚至可能没有明确定义的 "drop".
因此,对于您的示例,您可以尝试删除彼此之间某个阈值内的元素。但是,如果矩阵具有重复的奇异值,这当然会 运行 成为问题。
你可以只 运行 最小的奇异值,看看有多少让你接近于零。据推测矩阵至少是秩 ` 所以第一个奇异值将是非零的。
作为关于查找 test[i,j] > 0
位置的注释,您可以只输入 test>0
,它将给出一个布尔数组,其中非零条目为 True
,其他条目为 False
.您还可以将随机矩阵的 dtype
设置为 bool
,只要随机数非零,它就会 True
。