当给定雅可比系数时,Scipy的曲线拟合/leastsq会变慢?

2024-09-27 07:29:38 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我阅读了关于curve_fithere的文档。它包含以下示例:

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,它将近似于导数,因为我没有提供任何东西。我们来计时:

^{pr2}$

实际上,curve_fit调用leastsq(doc here),它接受一个Dfun参数来计算雅可比。所以我这样做了:

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

呃?使用雅可比比比近似它慢吗?我做错什么了吗?在


Tags: importlenreturnsodefasnpfit
1条回答
网友
1楼 · 发布于 2024-09-27 07:29:38

这不是一个真正的答案,但我觉得这取决于问题的大小。对于小尺寸(n=500),在计算jacobian(使用提供的jac)上花费的额外时间最终可能不会得到回报。在

n=500,有刺拳:

100 loops, best of 3: 1.50 ms per loop

没有:

^{pr2}$

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

相关问题 更多 >

    热门问题