繁体   English   中英

如何在二维数组上加速python curve_fit?

[英]How to speed up python curve_fit over a 2D array?

我必须对大量数据 (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")

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

加快速度的一种方法是向 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 您可以在此处阅读有关它们的信息。

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

底层的 Fortran 77 例程(MINPACK lmder.f 和 lmdif.f)不可重入,因此无法释放 GIL。 (因此没有机会与线程并行处理。)

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM