lstsq
试图解决Ax=b
最小化|b - Ax|
的问题,scipy和numpy都提供了一个linalg.lstsq
函数,接口非常相似,文档没有提到使用哪种算法,scipy.linalg.lstsq和numpy.linalg.lstsq都没有,但看起来做的差不多。
scipy.linalg.lstsq和numpy.linalg.lstsq的实现方式似乎不同。两者似乎都使用LAPACK,两种算法似乎都使用SVD。
区别在哪里?我应该用哪一个?
**注意:**不要将linalg.lstsq
与scipy.optimize.leastsq
混淆,后者也可以解决非线性优化问题。
2条答案
按热度按时间6ljaweal1#
如果我没有看错源代码(Numpy 1.8.2,Scipy 0.14.1),
numpy.linalg.lstsq()
使用LAPACK例程xGELSD
,scipy.linalg.lstsq()
使用xGELSS
。LAPACK手册第2.4节规定
子例程xGELSD比旧的xGELSS快得多,特别是对于大型问题,但可能需要更多的工作空间,具体取决于矩阵维数。
这意味着Numpy速度更快,但使用更多的内存。
2017年8月更新:
Scipy现在默认使用xGELSD https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.lstsq.html
sdnqo3pr2#
纽比1.13 - 2017年6月
从Numpy 1.13和Scipy 0.19开始,scipy.linalg.lstsq()和numpy.linalg.lstsq()默认调用相同的LAPACK代码DSGELD(参见LAPACK documentation)。
然而,这两个函数之间当前的重要区别在于所采用的默认RCOND LAPACK参数(Numpy称为
rcond
,Scipy称为cond
),该参数定义奇异值的阈值。Scipy使用了一个很好的、健壮的默认阈值
RCOND=eps*max(A.shape)*S[0]
,其中S[0]
是A
的最大奇异值,而Numpy使用默认阈值RCOND=-1
,这对应于在LAPACK中设置等于机器精度的阈值,而不管A
的值是什么。Numpy的默认方法在实际应用中基本上是无用的,并且当
A
接近秩亏时,通常会导致非常退化的解,浪费了DSGELD使用的奇异值分解SVD的精度,这意味着在Numpy中,应该总是**使用可选参数rcond
。更新:Numpy 1.14 - 2018年1月
我在numpy.linalg.lstsq()中报告了
rcond
的错误默认值(参见上面的部分),并且该函数现在在Numpy 1.14中引发了FutureWarning
(参见未来的更改)。scipy.linalg.lstsq()和numpy.linalg.lstsq()的未来行为将是相同的。换句话说,Scipy和Numpy不仅使用相同的LAPACK代码,而且使用相同的默认值。
要在Numpy 1.14中使用正确的(即未来的)默认值,应该使用显式的
rcond=None
调用numpy.linalg.lstsq()。