为什么numpy.linalg.lstsq比手动求解最小二乘法速度慢?
numpy.linalg.lstsq性能慢于手动正规方程求解的原因
你观测到的性能差异是两种求解方法的底层实现逻辑、适用场景和额外计算开销共同导致的,具体原因如下:
- 底层求解算法不同
你手动实现的是正规方程法,基于最小二乘的闭式解公式 ((ATA){-1}ATb)。你的测试场景中n=10,计算得到的(ATA)是仅10×10的极小矩阵,不管是inv求逆还是solve解线性方程组的开销都极低。而numpy.linalg.lstsq默认使用SVD(奇异值分解)求解最小二乘问题,SVD的计算复杂度常数项远高于正规方程法,在小n、A满秩的场景下速度劣势非常明显。 - 鲁棒性带来的额外开销
正规方程法仅在A列满秩、且(A^TA)可逆的场景下才能正常工作,一旦A存在共线性、秩亏的情况,结果会直接报错或者误差爆炸。而lstsq不需要依赖这个前提,哪怕A秩亏也能返回最小范数的最小二乘解,兼容更多边界场景的逻辑本身就会带来额外的计算开销。 - 额外返回值的计算开销
numpy.linalg.lstsq除了返回拟合系数外,默认还会计算残差平方和、矩阵A的秩、A的奇异值这三个额外结果,哪怕你只取返回值的第一个元素,这些计算过程依然会执行,进一步拉高了耗时。
注意:这个性能差异仅存在于你测试的「A列满秩、n远小于m、矩阵条件数小」的理想场景。如果A是病态矩阵、或者存在共线性,正规方程法的解精度会远低于
lstsq的SVD求解结果,实际使用时不要单纯为了速度优先选择手动正规方程实现。
内容的提问来源于stack exchange,提问作者Behrooz Ns
相关产品推荐
相关产品推荐

