在https://math.stackexchange.com/a/2233298/340174中,提到了通过LU分解来求解线性方程“ M·x = b”(矩阵M为平方)的速度较慢(但使用QR分解的速度甚至更慢)。现在我注意到numpy.linalg.solve
实际上正在使用LU分解。实际上,我想针对最小平方的非平方范德蒙设计矩阵V求解“ V·x = b”。我不要正则化。我看到了多种方法:
numpy.linalg.lstsq
解决“ V·x = b”,该问题使用基于SVD的Fortran“ xGELSD”。 SVD应该比LU分解还要慢,但是我不需要计算“(V ^ T·V)”。numpy.linalg.solve
解决“(V ^ T·V)·x =(V ^ T·b)”,它使用LU分解。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看来,solve
比lstsq
更快,包括计算“ 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。答案 0 :(得分:2)
我将忽略该问题的Vandermonde部分( bubble 的注释指出它具有解析逆函数),而是回答有关其他矩阵的更一般的问题。
我认为这里可能会混淆一些事情,因此我将区分以下几点:
V x = b
的精确解决方案V x = b
的精确解决方案V x = b
的最小二乘解V x = b
的最小二乘解V^T V x = V^T b
的精确解决方案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.solve
与assume_a="pos"
一起使用。否则,您将完成5。
我还没有找到在numpy
或scipy
中执行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()
!
让我们回顾一下求解线性最小二乘的不同例程和方法:
numpy.linalg.lstsq()
包装LAPACK的xGELSD()
,如第2841+行的umath_linalg.c.src所示。该例程使用“先征服法”将矩阵V简化为对角线形式,并计算该对角线矩阵的SVD。
scipy的scipy.linalg.lstsq()
包装了LAPACK的[[rich(john), healthy(john)], happy(john), 0.6]
[[wins(john), True], happy(john), 0.162]
[[True, True], happy(john), 0.1134]
,xGELSY()
和xGELSS()
:参数lapack_driver='gelsy'
可以修改为从一个切换到另一个。根据LAPACK的基准,xGELSD()
比lapack_driver
慢,而xGELSS()
比xGELSD()
快5。 xGELSY()
通过列旋转使用V的QR因式分解。好消息是此开关为already available in scipy 1.1.0!
xGELS()
利用矩阵V的QR分解,但假定该矩阵具有完整秩。根据LAPACK的基准,on可以预期xGELSD()
比xGELSY()
快5倍,但它也更容易受到矩阵条件数的影响,并且可能变得不准确。在The difference between C++ (LAPACK, sgels) and Python (Numpy, lstsq) results中查看详细信息和更多参考。 cython-lapack interface of scipy中提供了xGELS()。 尽管很诱人,但计算和使用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。