SciPy's documentation表示lstsq
返回观察矩阵的奇异值。但是当我直接使用singular value decomposition(来自SciPy的相同实现scipy.linalg.svd
)计算它们时,我得到了一组不同的值。
两者的趋势肯定是一样的,但是它们的最小值和最大值似乎是不同的,这一点特别重要,因为它改变了条件数的估计,为什么它们不同呢?
下面的代码可以复制这个:
import numpy as np
from scipy.linalg import svd, lstsq
import matplotlib.pyplot as plt
# Let's generate some interesting X
X = np.arange(100*50, dtype=float).reshape(100,50)
X = np.sin(X) + np.tan(X) + np.cos(X)
X += np.random.normal(0,3, size=(100,50))
# And some function which we want to fit
# (for now it does't matter)
Y = np.sin(X)
# Let's compute the signular values of the observation matrix X
W, res, rank, s = lstsq(X, Y, cond=0) # cond=0 to deactivate sing-val truncation
_, S, _ = svd(X.T @ X)
# They should match exactly
plt.semilogy(S, label='from svd')
plt.semilogy(s, label='from lstsq')
plt.legend()
字符串
的数据
1条答案
按热度按时间iyfjxgzm1#
你在计算,一方面,X的奇异值,另一方面,X的奇异值,所以,不是相同的结果。
为了更准确,第二个结果是第一个的平方。因此,对数尺度上的乘法因子。
如果你想确信这一点,只要画出svd的平方根
字符串
或者,与正确的计算相比
型
(same结果)
在你的代码中,
s
是X
的奇异值,S
是X.T@X
的奇异值。这是不同的东西。但是为什么一个是另一个的平方是因为奇异值的定义:奇异值是X*X
的特征值的平方根(这里=XᵀX
,因为这些都是实值)。因此,XᵀX
部分已经由svd完成。设λ是
XᵀX
的特征值,即如果λ u <$0,X <$Xu = λu,则(X <$X)<$(X <$X)=(X <$X)(X <$X)u = X <$X λu = λ²u,所以λ²是(X <$X)<$(X <$X)的特征值。因此,如果
s
是X的奇异值,也就是说如果s²是X <$X的特征值,那么s <$是(X <$X)<$(X <$X)的特征值,那么s²是X <$X的奇异值。所以,这里没什么奇怪的,奇异值是奇异值的平方,这和你的图显示的一样。