【问题标题】:How to speed up python curve_fit over a 2D array?如何在二维数组上加速 python curve_fit?
【发布时间】:2015-06-26 10:15:36
【问题描述】:

我必须对大量数据 (5 000 000) 使用 curve_fit numpy 函数。 所以基本上我已经创建了一个二维数组。第一个维度是要执行的拟合数,第二个维度是用于拟合的点数。

t = np.array([0 1 2 3 4])

for d in np.ndindex(data.shape[0]):
  try:
    popt, pcov = curve_fit(func, t, np.squeeze(data[d,:]), p0=[1000,100])
  except RuntimeError:
    print("Error - curve_fit failed")

多处理可以用来加速整个过程,但它仍然很慢。 有没有办法以“矢量化”的方式使用curve_fit?

【问题讨论】:

  • 有可能使用 Python 的 multiprocessing 内置模块。 This answer 应该能帮到你

标签: python performance numpy curve-fitting


【解决方案1】:

加快速度的一种方法是在curve_fit中添加一些先验知识。

如果您知道您期望参数的范围,并且不需要精确到第 100 个有效数字,则可以大大加快计算速度。

这里有一个例子,你适合param1param2

t = np.array([0 1 2 3 4])
def func(t, param1, param2):
  return param1*t + param2*np.exp(t)

for d in np.ndindex(data.shape[0]):
  try:
    popt, pcov = curve_fit(func, t, np.squeeze(data[d,:]), p0=[1000,100], 
                           bounds=([min_param1, min_param2],[max_param1, max_param2]),
                           ftol=0.5, xtol=0.5)
  except RuntimeError:
    print("Error - curve_fit failed")

注意额外的关键参数boundsftolxtol。你可以阅读他们here.

【讨论】:

    【解决方案2】:

    曲线拟合扩展了scipy.optimize.leastsq 的功能,它本身就是底层MINPACK lmdiflmder fortran 例程的包装器。看起来多线程是不可能的,看看这个link,上面写着,

    底层的 Fortran 77 例程(MINPACK lmder.f 和 lmdif.f)不是 可重入,所以 GIL 不能被释放。 (因此没有机会并行 用线程处理。)

    还有一个开放的ticket 来开发它,但它看起来无法完成......您需要使用不同的库或在较低级别的代码中编写包装器/函数。关于并行 Levenberg-Marquardt 算法的实现有papers

    也许还有另一种解决方案,使用更少的数据或作为粗略估计,您可以将数据随机拆分为多个部分,将每个部分曲线拟合到单独的线程(使用多处理器)上并取系数的平均值最后。

    【讨论】:

    • 感谢您的回答。我目前正在尝试通过不进行所有计算来节省时间...
    • 您链接的工单似乎已被 5 月 5 日合并的 PR 关闭
    【解决方案3】:

    根据我的经验,如果可能,您应该将 jacobian 提供给 curve_fit。通过避免一次又一次地调用func 来计算雅可比,它将节省时间。它会给您带来显着的速度提升,尤其是在您处理大量可优化参数时。

    【讨论】:

      猜你喜欢
      • 2020-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      • 2016-11-05
      相关资源
      最近更新 更多