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
混淆,后者也可以解决非线性优化问题。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
Numpy 1.13 - 2017 年 6 月scipy.linalg.lstsq() 和 numpy.linalg.lstsq() 默认调用相同的 LAPACK 代码 DSGELD(请参阅 LAPACK 文档)。
然而,当前两个函数之间的一个重要区别在于采用的默认 RCOND LAPACK 参数(Numpy 称为 rcond
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
FutureWarning
(请参阅未来更改)。
未来的行为在scipy.linalg.lstsq() 和 numpy.linalg.lstsq() 中将是相同的。换句话说,Scipy 和 Numpy 不仅会使用相同的 LAPACK 代码,而且还会使用相同的默认值。
要开始使用 Numpy 1.14 中正确的(即未来的)默认值,应该使用显式 rcond=None
来调用 numpy.linalg.lstsq()