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?
答案 0 :(得分:2)
加快速度的一种方法是向curve_fit添加一些先验知识。
如果您知道您希望参数的范围,并且如果您不需要精确到第100个有效数字,则可以大大加快计算速度。
这是一个适合param1
和param2
的示例:
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")
请注意额外的关键参数bounds
,ftol
和xtol
。你可以阅读它们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
来计算雅可比,它将节省时间。它会给您带来显着的速度提升,尤其是在您处理大量可优化参数时。