【问题标题】:Multiple coefficient sets for least squares fitting in numpy/scipynumpy/scipy中最小二乘拟合的多个系数集
【发布时间】:2019-03-29 07:11:17
【问题描述】:

有没有办法在numpy.linalg.lstsq 或scipy.linalg.lstsq 中执行多个同时(但不相关)的最小二乘拟合与不同的系数矩阵?例如,这是一个简单的线性拟合,我希望能够用不同的 x 值但相同的 y 值来做。目前,我必须写一个循环:

x = np.arange(12.0).reshape(4, 3)
y = np.arange(12.0, step=3.0)
m = np.stack((x, np.broadcast_to(1, x.shape)), axis=0)

fit = np.stack(tuple(np.linalg.lstsq(w, y, rcond=-1)[0] for w in m), axis=-1)

这会产生一组具有相同斜率和不同截距的拟合,因此 fit[n] 对应于系数 m[n]。

线性最小二乘法不是一个很好的例子,因为它是可逆的,而且这两个函数都可以选择多个 y 值。但是,它可以说明我的观点。

理想情况下,我想将此扩展到a 和b 的任何“可广播”组合,其中a.shape[-2] == b.shape[0] 精确,并且最后一个维度必须匹配或为一个(或缺失)。我并不关心a 的哪个维度代表不同的矩阵:将其设为第一个以缩短循环只是方便。

numpy 或 scipy 中是否有内置方法来避免 Python 循环?我对使用 lstsq 而不是手动转置、乘法和反转矩阵非常感兴趣。

【问题讨论】:

  • 如果你只是想摆脱for循环,你可以使用pinv然后矩阵乘法:fit=np.linalg.pinv(m)@y

标签: python numpy scipy least-squares


【解决方案1】:

您可以将scipy.sparse.linalg.lsqr 与scipy.sparse.block_diag 一起使用。我只是不确定它会更快。

例子:

>>> import numpy as np
>>> from scipy.sparse import block_diag
>>> from scipy.sparse import linalg as sprsla
>>> 
>>> x = np.random.random((3,5,4))
>>> y = np.random.random((3,5))
>>> 
>>> for A, b in zip(x, y):
...     print(np.linalg.lstsq(A, b))
... 
(array([-0.11536962,  0.22575441,  0.03597646,  0.52014899]), array([0.22232195]), 4, array([2.27188101, 0.69355384, 0.63567141, 0.21700743]))
(array([-2.36307163,  2.27693405, -1.85653264,  3.63307554]), array([0.04810252]), 4, array([2.61853881, 0.74251282, 0.38701194, 0.06751288]))
(array([-0.6817038 , -0.02537582,  0.75882223,  0.03190649]), array([0.09892803]), 4, array([2.5094637 , 0.55673403, 0.39252624, 0.18598489]))
>>> 
>>> sprsla.lsqr(block_diag(x), y.ravel())
(array([-0.11536962,  0.22575441,  0.03597646,  0.52014899, -2.36307163,
        2.27693405, -1.85653264,  3.63307554, -0.6817038 , -0.02537582,
        0.75882223,  0.03190649]), 2, 15, 0.6077437777160813, 0.6077437777160813, 6.226368324510392, 106.63227777368986, 1.3277892240815807e-14, 5.36589277249043, array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]))

【讨论】:

  • 因此,您正在使用沿对角线的原始矩阵创建一组解耦块,然后将整个事情作为一个巨大的系统来解决。如果矩阵不必是稀疏的,这绝对是一个好主意。我会仔细看看时间安排。
  • @MadPhysicist 是的,我只是不知道算法浪费了多少时间,因为没有人告诉它块是解耦的,事实上根本就存在块。好吧,我想你会看到你的时间安排。
  • 我之所以选择这个,是因为它可能是我得到的最佳答案,直到我自己开始弄乱原始函数。
猜你喜欢
  • 2018-05-16
  • 2019-07-31
  • 2012-03-11
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
  • 2013-01-21
  • 2012-02-05
  • 2019-07-19
相关资源
最近更新 更多