【问题标题】:Scipy.optimize - curve fitting with fixed parametersScipy.optimize - 具有固定参数的曲线拟合
【发布时间】:2017-02-26 17:42:31
【问题描述】:

我正在使用scipy.optimize.leastsq 进行曲线拟合。例如。对于高斯:

def fitGaussian(x, y, init=[1.0,0.0,4.0,0.1]):
    fitfunc = lambda p, x: p[0]*np.exp(-(x-p[1])**2/(2*p[2]**2))+p[3] # Target function
    errfunc = lambda p, x, y: fitfunc(p, x) - y # Distance to the target function
    final, success = scipy.optimize.leastsq(errfunc, init[:], args=(x, y))
    return fitfunc, final

现在,我想选择性地修复拟合中某些参数的值。我发现建议是使用不同的包lmfit,我想避免,或者非常笼统,比如here。 因为我需要一个解决方案,

  1. 适用于 numpy/scipy(没有其他包等)
  2. 独立于参数本身,
  3. 灵活,参数固定或不固定,

我想出了以下内容,对每个参数使用条件:

def fitGaussian2(x, y, init=[1.0,0.0,4.0,0.1], fix = [False, False, False, False]):
    fitfunc = lambda p, x: (p[0] if not fix[0] else init[0])*np.exp(-(x-(p[1] if not fix[1] else init[1]))**2/(2*(p[2] if not fix[2] else init[2])**2))+(p[3] if not fix[3] else init[3]) 
    errfunc = lambda p, x, y: fitfunc(p, x) - y # Distance to the target function
    final, success = scipy.optimize.leastsq(errfunc, init[:], args=(x, y))
    return fitfunc, final

虽然这很好用,但它既不实用也不美观。 所以我的问题是:有没有更好的方法在 scipy 中为固定参数执行曲线拟合?或者是否有包装器,其中已经包含此类参数修复?

【问题讨论】:

  • 在 scipy 中有这个功能会很好,但我不确定它是否存在。出于好奇,为什么要避免使用lmfit?根据我的经验,它使用起来非常简单。
  • 我想避免使用其他软件包的原因是,我需要确保它们已正确安装在运行此程序的任何计算机上。

标签: numpy scipy curve-fitting


【解决方案1】:

上面使用 symfit 的例子肯定只是拟合方法的语法,但是,给出的例子真的限制了变量 c 吗?

如果您查看fit_result.param,您会得到以下信息:

OrderedDict([('a', 16.374368575343127), ('b', 0.49201249437123556), ('c', 0.5337962977235504), ('d', -9.55593614465743)])

参数c不是4.0。

【讨论】:

  • 这不是一个真正的答案,是吗?相反,您可能会评论其他答案以要求澄清。但无论如何,symfit 不是这个问题所要求的。
  • 这原来是 0.4.0 中的一个错误,现在已经修复 :)。但是@ImportanceOfBeingErnest 是对的,因为这应该是对我的回答的评论,而不是单独的回答。
【解决方案2】:

使用scipy,没有我知道的内置选项。你总是需要像你已经做的那样做一个变通方法。

但是,如果您愿意使用 wrapper 包,我可以推荐我自己的 symfit 吗?这是scipy 的包装器,以可读性和更少的样板代码为核心原则。在symfit,您的问题将被解决为:

from symfit import parameters, variables, exp, Fit, Parameter

a, b, c, d = parameters('a, b, c, d')
x, y = variables('x, y')

model_dict = {y: a * exp(-(x - b)**2 / (2 * c**2)) + d}

fit = Fit(model_dict, x=xdata, y=ydata)
fit_result = fit.execute()

a, b, c, d = parameters('a, b, c, d') 行产生了四个 Parameter 对象。修复例如将参数c 设置为其初始值,在调用fit.execute() 之前在任何地方执行以下操作:

c.value = 4.0
c.fixed = True

所以可能的最终结果可能是:

from symfit import parameters, variables, exp, Fit, Parameter

a, b, c, d = parameters('a, b, c, d')
x, y = variables('x, y')

c.value = 4.0
c.fixed = True

model_dict = {y: a * exp(-(x - b)**2 / (2 * c**2)) + d}

fit = Fit(model_dict, x=xdata, y=ydata)
fit_result = fit.execute()

如果您想在您的代码中更加动态,您可以使用以下方法立即创建 Parameter 对象:

c = Parameter(4.0, fixed=True)

有关更多信息,请查看文档:http://symfit.readthedocs.io/en/latest/tutorial.html#simple-example

【讨论】:

    猜你喜欢
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 2016-02-12
    相关资源
    最近更新 更多