python curve_fit不适用于僵硬的模型

时间:2016-02-02 16:07:38

标签: python algorithm numpy scipy curve-fitting

我正在尝试找到x0参数,该参数尽可能地匹配绿色曲线上的蓝色模型(x0控制垛口的宽度;见下文)。

enter image description here

这是我的尝试:

from pylab import *
from scipy.optimize import curve_fit

x=linspace(0,2*pi,1000)    
def crenel(x):return sign(sin(x))
def inverter(x,x0): return (crenel(x-x0)+crenel(x+x0))/2

p,e = curve_fit(inverter,x,sin(x),1)    
plot(x,inverter(x,*p),x,sin(x))
ylim(-1.5,1.5)

手动,最佳值为x0 = arcsin(1/2) # 0.523598,但curve_fit并未估算任何值("优化警告:无法估计参数的协方差" )。我怀疑模型的刚度。 docs通知:

  

该算法通过leastsq使用Levenberg-Marquardt算法。其他关键字参数将直接传递给该算法。

所以我的问题是:在这种情况下,是否有关键字参数可以帮助curve_fit估计参数?或另一种方法?

感谢您的任何建议。

1 个答案:

答案 0 :(得分:1)

问题是curve_fit试图最小化的目标函数不是连续的。 x0控制inverter函数中不连续点的位置。当不连续性穿过x中的一个网格点时,目标函数会跳跃。在这些点之间,目标函数是不变的。 curve_fit(实际上,leastsqcurve_fit使用的函数)并非旨在处理此类函数。

以下函数sse(实际上)curve_fit尝试最小化的函数,x与示例中定义的x相同,y = sin(x) 1}}:

def sse(x0, x, y):
    f = inverter(x, x0)
    diff = y - f
    s = (diff**2).sum()
    return s

如果使用代码(例如

)在精细网格上绘制此函数
xx = np.linspace(0, 1, 10000)
yy = [sse(x0, x, y) for x0 in xx]
plot(xx, yy)

并放大,你会看到

plot

要使用scipy找到最佳值,您可以使用fmin平滑的目标函数。例如,这里是连续目标函数,仅使用区间[0,pi / 2](quadscipy.integrate.quad):

def func(x0):
    s0, e0 = quad(lambda x: np.sin(x)**2, 0, x0)
    s1, e0 = quad(lambda x: (1 - np.sin(x))**2, x0, 0.5*np.pi)
    return s0 + s1

scipy.optimize.fmin可用于查找该函数的最小值,如ipython会话中的此片段所示:

In [202]: fmin(func, 0.3, xtol=1e-8)
Optimization terminated successfully.
         Current function value: 0.100545
         Iterations: 28
         Function evaluations: 56
Out[202]: array([ 0.52359878])

In [203]: np.arcsin(0.5)
Out[203]: 0.52359877559829882