numpy.linalg.lstsq和scipy.linalg.lstsq有什么区别?

时间:2015-03-31 15:34:39

标签: python numpy scipy least-squares

lstsq尝试解决Ax=b最小化问题|b - Ax|。 scipy和numpy都提供了一个具有非常相似接口的linalg.lstsq函数。文档没有提到使用哪种算法,scipy.linalg.lstsqnumpy.linalg.lstsq都没有,但它似乎做的几乎相同。

scipy.linalg.lstsqnumpy.linalg.lstsq的实施似乎有所不同。两者似乎都使用LAPACK,两种算法似乎都使用SVD。

区别在哪里?我应该使用哪一个?

注意:不要将linalg.lstsqscipy.optimize.leastsq混淆,这也可以解决非线性优化问题。

2 个答案:

答案 0 :(得分:19)

如果我正确阅读源代码(Numpy 1.8.2,Scipy 0.14.1 ),numpy.linalg.lstsq()使用LAPACK例程xGELSDscipy.linalg.lstsq()使用xGELSS

LAPACK Manual Sec. 2.4

  

子程序xGELSD明显快于旧版xGELSS,特别是对于大问题,但根据矩阵尺寸可能需要更多工作空间。

这意味着Numpy更快但使用更多内存。

2017年8月更新:

Scipy现在默认使用xGELSD https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.lstsq.html

答案 1 :(得分:14)

Numpy 1.13 - 2017年6月

从Numpy 1.13和Scipy 0.19开始, scipy.linalg.lstsq()numpy.linalg.lstsq()默认调用相同的LAPACK代码DSGELD(参见LAPACK documentation)。

然而,两个函数之间当前的重要区别在于采用的默认RCOND LAPACK参数(Numpy称为rcond,Sci​​py称为cond),它定义了奇异值的阈值。

Scipy使用良好而强大的默认阈值RCOND=eps*max(A.shape)*S[0],其中S[0]A的最大奇异值,而Numpy使用默认阈值RCOND=-1,相当于无论A的值如何,都在LAPACK中设置等于机器精度的阈值。

Numpy的默认方法在实际应用中基本无用,并且当A几乎排名不足时通常会导致非常简并的解决方案,浪费DSGELD使用的奇异值分解SVD的准确性。这意味着在Numpy中,可选参数rcond始终使用。

更新:Numpy 1.14 - 2018年1月

我在numpy.linalg.lstsq()中报告了rcond的错误默认值(参见上面的部分),现在该函数在Numpy 1.14中引发FutureWarning(请参阅Future Changes)。

未来的行为在scipy.linalg.lstsq()numpy.linalg.lstsq()中都是相同的。换句话说,Scipy和Numpy不仅会使用相同的LAPACK代码,还会使用相同的默认值。

要开始在Numpy 1.14中使用正确的(即将来的)默认值,应该使用明确的rcond=None来调用numpy.linalg.lstsq()