具有约束方程的ipython非线性最小二乘法

时间:2014-06-13 17:10:15

标签: scipy least-squares

我是iPython的新手,需要解决特定的曲线拟合问题,我有这个概念,但我的编程知识还是太有限了。我有实验数据(x, y)以适应具有四个系数(a,b,c,d)的方程(曲线拟合),我想将这些系数之一(例如a)修复为特定值并重新调整我的实验数据(非线性最小二乘)。系数b,c和d不是独立于另一个,意味着它们与方程组相关。

使用curve_fitlmfit更合适吗?

我用curve_fit启动了这个:

def fitfunc(x,a,b,c,d):
    return a+b*x+c/x+log10(x)*d
popt, fitcov = curve_fit(fitfunc, x, y)

或使用lmfit的此类代码:

import scipy as sp
from lmfit import minimize, Parameters, Parameter, report_fit

def fctmin(params, x, y):
    a = params['a'].value
    b = params['b'].value
    c = params['c'].value
    d = params['d'].value

    model = a+b*x+c/x+d*np.log10(x)

    return model - y

#create parameters
params = Parameters()
params.add('a', value = -89)
params.add('b', value =b)
params.add('c', value = c)
params.add('d', value = d)

#fit leastsq model
result = minimize(fctmin, params, args=(x, y))

#calculate results
final = y +  result.residual
report_fit(params)

1 个答案:

答案 0 :(得分:0)

我承认自己有偏见。 curve_fit()旨在通过假设您将y(x)数据拟合到y(x,参数)的模型来简化scipy.optimize.leastsq(),因此传递给curve_fit()的函数将是一个计算的函数要适合的值的模型。 lmfit有点更通用和灵活,因为你的目标函数必须使数组在最小二乘意义上最小化,但你的目标函数必须返回" model-data"而不是"模型"

但是,lmfit的功能似乎完全符合您的要求:修复模型中的一个参数而无需重写目标函数。
也就是说,你可以说

params.add('a', value = -89, vary=False)

和参数' a'将保持固定。要使用curve_fit()执行此操作,您必须重写模型函数。

另外,你说b,c和d是用方程式相关的,但是没有给出细节。使用lmfit,您可以将这些方程作为约束包含在内。

params.add('b', value =b)
params.add('c', value = c)
params.add('d', value = d)

虽然我没有看到b的值。即使假设存在一个值,也会创建三个具有相同起始值的自变量。您可能意味着"变化b,并强制c和d具有相同的值"。 lmfit可以这样做:

params.add('b', value = 10)
params.add('c', expr = 'b')
params.add('d', expr = 'c')

这将有一个自变量,c的值将被强制为b(和d到c)的值。您可以使用(近似)任何有效的python语句作为约束约束表达式,例如:

params.add('b', value = 10)
params.add('c', expr = 'sqrt(b/10)')
params.add('d', expr = '1-c')

我认为这可能是你正在寻找的那种东西。