当在numpy
(1.15.4)中查找如何计算伪逆时,我注意到numpy.linalg.pinv
有一个参数rcond
,其描述为:
rcond:(...)浮点数的array_like
切去小奇异值。奇异值较小(以 模数)大于rcond *最大_奇异值(再次以模数表示) 设置为零。针对矩阵堆栈进行广播
据我了解,如果rcond
是标量浮点数,则所有条目
应该将pinv
的输出中小于rcond
的值设置为零(这将非常有用),但这不会发生,例如:
>>> A = np.array([[ 0., 0.3, 1., 0.],
[ 0., 0.4, -0.3, 0.],
[ 0., 1., -0.1, 0.]])
>>> np.linalg.pinv(A, rcond=1e-3)
array([[ 8.31963531e-17, -4.52584594e-17, -5.09901252e-17],
[ 1.82668420e-01, 3.39032588e-01, 8.09586439e-01],
[ 8.95805933e-01, -2.97384188e-01, -1.49788105e-01],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]])
此参数实际上是做什么的?而且只能通过再次遍历整个输出矩阵来获得我真正想要的行为吗?
答案 0 :(得分:2)
在幕后,使用singular value decomposition计算伪逆。初始矩阵A=UDV^T
反转为A^+=VD^+U^T
,其中D
是具有正实数值(奇异值)的对角矩阵。 rcond
用于将D
中的小条目清零。例如:
import numpy as np
# Initial matrix
a = np.array([[1, 0],
[0, 0.1]])
# SVD with diagonal entries in D = [1. , 0.1]
print(np.linalg.svd(a))
# (array([[1., 0.],
# [0., 1.]]),
# array([1. , 0.1]),
# array([[1., 0.],
# [0., 1.]]))
# Pseudoinverse
c = np.linalg.pinv(a)
print(c)
# [[ 1. 0.]
# [ 0. 10.]]
# Reconstruction is perfect
print(np.dot(a, np.dot(c, a)))
# [[1. 0. ]
# [0. 0.1]]
# Zero out all entries in D below rcond * largest_singular_value = 0.2 * 1
# Not entries of the initial or inverse matrices!
d = np.linalg.pinv(a, rcond=0.2)
print(d)
# [[1. 0.]
# [0. 0.]]
# Reconstruction is imperfect
print(np.dot(a, np.dot(d, a)))
# [[1. 0.]
# [0. 0.]]
仅将矩阵的小值归零:
a = np.array([[1, 2],
[3, 0.1]])
a[a < 0.5] = 0
print(a)
# [[1. 2.]
# [3. 0.]]