解决线性最小二乘法的最快方法

时间:2019-03-26 22:24:06

标签: python numpy scipy

https://math.stackexchange.com/a/2233298/340174中,提到了通过LU分解来求解线性方程“ M·x = b”(矩阵M为平方)的速度较慢(但使用QR分解的速度甚至更慢)。现在我注意到numpy.linalg.solve实际上正在使用LU分解。实际上,我想针对最小平方的非平方范德蒙设计矩阵V求解“ V·x = b”。我不要正则化。我看到了多种方法:

  1. numpy.linalg.lstsq解决“ V·x = b”,该问题使用基于SVD的Fortran“ xGELSD”。 SVD应该比LU分解还要慢,但是我不需要计算“(V ^ T·V)”。
  2. numpy.linalg.solve解决“(V ^ T·V)·x =(V ^ T·b)”,它使用LU分解。
  3. numpy.linalg.solve解决“ A·x = b”,该方法使用LU分解,但直接根据https://math.stackexchange.com/a/3155891/340174计算“ A = xV ^ T·V”

或者,我可以使用scipy(https://docs.scipy.org/doc/scipy-1.2.1/reference/generated/scipy.linalg.solve.html)中最新的solve,它可以对对称矩阵“ A”使用对角线旋转(我想这比使用LU分解要快),但是scipy卡在1.1.0上,所以我无权访问。

https://stackoverflow.com/a/45535523/4533188看来,solvelstsq更快,包括计算“ V ^ T·V”,但是当我尝试时,lstsq更快。也许我做错了什么?

解决线性问题的最快方法是什么?


没有实际选择

  • statsmodels.regression.linear_model.OLS.fit使用Moore-Penrose伪逆或QR分解+ np.linalg.inv + np.linalg.svd + numpy.linalg.solve,对我来说似乎不太有效。
  • sklearn.linear_model.LinearRegression使用scipy.linalg.lstsq。
  • scipy.linalg.lstsq也使用xGELSD。
  • 我期望计算“(V ^ T·V)”的逆数会非常昂贵,因此我放弃了直接计算“ x =(V ^ T·V)^-1·(V ^ T·b) )”

2 个答案:

答案 0 :(得分:2)

我将忽略该问题的Vandermonde部分( bubble 的注释指出它具有解析逆函数),而是回答有关其他矩阵的更一般的问题。

我认为这里可能会混淆一些事情,因此我将区分以下几点:

  1. 使用LU的V x = b的精确解决方案
  2. 使用QR的V x = b的精确解决方案
  3. 使用QR的V x = b的最小二乘解
  4. 使用SVD的V x = b的最小二乘解
  5. 使用LU的V^T V x = V^T b的精确解决方案
  6. 使用Cholesky的V^T V x = V^T b的精确解决方案

您链接到的第一个maths.stackexchange答案是关于情况1和2。当它说LU慢时,表示相对于特定类型矩阵的方法,例如正定的,三角形的,带状的...

但是我想您实际上是在询问3-6。最后一个stackoverflow链接指出6比4快。正如您所说,4应该比3慢,但是4是唯一适用于排名不足的V的链接。 6应该比5一般快。

我们应该确保您做的是6,而不是5。要使用6,您需要将scipy.linalg.solveassume_a="pos"一起使用。否则,您将完成5。

我还没有找到在numpyscipy中执行3的单个函数。 Lapack例程是xGELS,在scipy中似乎没有公开。您应该可以使用scupy.linalg.qr_multiply,然后加上scipy.linalg.solve_triangular

答案 1 :(得分:1)

尝试使用Explaining happy(john). An explanation is: [rich(john), healthy(john)] with probability 0.6 Explaining rich(john). An explanation is: [wins(john)] with probability 0.3 Explaining healthy(john). An explanation is: [True] with probability 0.9 Explaining happy(john). An explanation is: [wins(john), True] with probability 0.162 Explaining wins(john). An explanation is: [True] with probability 0.7 Explaining rich(john). An explanation is: [True] with probability 0.21 Explaining healthy(john). An explanation is: [True] with probability 0.9 Explaining happy(john). An explanation is: [True, True] with probability 0.1134 scipy.linalg.lstsq()

让我们回顾一下求解线性最小二乘的不同例程和方法:

尽管很诱人,但计算和使用dgels()来求解法线方程可能不是可行的方法。实际上,该精度受到该矩阵的条件数(约the square of the condition number of the matrix V)的威胁。从Vandermonde matrices tend to be badly ill-conditioned, except for the matrices of the discrete Fourier transform开始,它可能变得很危险... 最后,您甚至可以继续使用dgelsd()来避免与条件相关的问题。如果您切换到V^T·V,请考虑使用estimating the error