How to speed-up python curve_fit over a 2D array?

时间:2015-06-26 10:15:37

标签: python performance numpy curve-fitting

I have to use the curve_fit numpy function over a large set of data (5 000 000). So basically I've created a 2D array. First dimension is the number of fittings to perform, second dimension is the number of points used for the fitting.

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 can be used to speed up the full process, but it is still quite slow. Is there a way to use curve_fit in a "vectorized" manner?

3 个答案:

答案 0 :(得分:2)

加快速度的一种方法是向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.

答案 1 :(得分:1)

Curve fit扩展了scipy.optimize.leastsq的功能,lmdif本身就是底层MINPACK lmder$(window).bind('scroll', function () { var h = $('.header').height(); if ($(window).scrollTop() > h) { $('.mail2, .optimize').addClass('fixed'); } else { $('.mail2, .optimize').removeClass('fixed'); } }); fortran例程的包装器。看起来无法进行多线程,请查看此link,其中说明了

  

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

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

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

答案 2 :(得分:0)

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