所以我阅读了关于curve_fit
here的文档。它包含以下示例:
import numpy as np
import scipy.optimize as so
def func(x, a,b,c ):
return a * np.exp(-b * x) + c
a,b,c = 2.5, 1.3, 0.5
nx = 500
noiseAlpha = 0.5
#
xdata = np.linspace(0, 4, nx)
y = func(xdata, a,b,c)
ydata = y + noiseAlpha * np.random.normal(size=len(xdata))
如果我现在调用
curve_fit
,它将近似导数,因为我没有提供任何东西。让我们计时:%%timeit
popt, pcov = so.curve_fit(func, xdata, ydata )
1000 loops, best of 3: 787 µs per loop
实际上
curve_fit
调用leastsq
(doc here),它接受一个Dfun
参数来计算Jacobian。所以我这么做了:def myDfun( abc, xdata, ydata, f ) :
a,b,c = abc
ebx = np.exp(-b * xdata)
res = np.vstack( ( ebx, a * -xdata * ebx, np.ones(len(xdata)) ) ).T
return res
我再次计时:
%%timeit
popt, pcov = so.curve_fit(func, xdata, ydata, Dfun=myDfun )
1000 loops, best of 3: 858 µs per loop
休斯敦大学?使用雅可比比近似慢?我做错什么了吗?
最佳答案
不是一个真正的答案,但我的感觉是这取决于问题的大小。对于小尺寸(n=500),在评估jacobian(使用提供的jac)时所花费的额外时间最终可能不会得到回报。
n=500,带刺针:
100 loops, best of 3: 1.50 ms per loop
没有:
100 loops, best of 3: 1.57 ms per loop
n=5000,带刺针:
100 loops, best of 3: 5.07 ms per loop
没有:
100 loops, best of 3: 6.46 ms per loop
n=50000,带刺针:
100 loops, best of 3: 49.1 ms per loop
没有:
100 loops, best of 3: 59.2 ms per loop
另外,您可能需要考虑重写jacobian函数,例如,去掉昂贵的
.T()
可以带来大约15%的速度:def myDfun2( abc, xdata, ydata, f ) :
a,b,c = abc
ebx = np.exp(-b * xdata)
res = np.hstack( ( ebx.reshape(-1,1), (a * -xdata * ebx).reshape(-1,1), np.ones((len(xdata),1)) ) )
return res
关于python - 给定雅可比矩阵时,Scipy的curve_fit/minimumsq变慢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24391242/