使用 scipy.optimize.curve_fit 时如何将参数传递给拟合函数

Nis*_*sfa 2 curve-fitting scipy python-3.x

我正在尝试使用 scipy.optimize.curve_fit 拟合一些数据。我的拟合函数是:

def fitfun(x, a):
    return np.exp(a*(x - b))
Run Code Online (Sandbox Code Playgroud)

我想要的是定义a为拟合参数,以及b根据我想要拟合的数据而变化的参数。这意味着对于一组数据,我希望拟合函数:np.exp(a*(x - 10))而对于另一组数据,我希望拟合函数np.exp(a*(x - 20))。原则上,我希望参数 b 作为任何值传入。

我目前调用 curve_fit 的方式是:

coeffs, coeffs_cov = curve_fit(fitfun, xdata, ydata)
Run Code Online (Sandbox Code Playgroud)

但我想要的是这样的:

b=10     
coeffs, coeffs_cov = curve_fit(fitfun(b), xdata, ydata)
b=20     
coeffs2, coeffs_cov2 = curve_fit(fitfun(b), xdata, ydata)
Run Code Online (Sandbox Code Playgroud)

这样我就可以得到两种情况下的系数 a(b=10 和 b=20)。

我是 python 的新手,所以我无法让它工作,即使我试图阅读文档。任何帮助将不胜感激。

MPA*_*MPA 6

我不知道这是否是“正确”的做事方式,但我通常将我的函数包装在一个类中,以便我可以从self. 您的示例将如下所示:

class fitClass:

    def __init__(self):
        pass

    def fitfun(self, x, a):
        return np.exp(a*(x - self.b))

inst = fitClass()

inst.b = 10
coeffs, coeffs_cov = curve_fit(inst.fitfun, xdata, ydata)

inst.b = 20
coeffs, coeffs_cov = curve_fit(inst.fitfun, xdata, ydata)
Run Code Online (Sandbox Code Playgroud)

这种方法避免使用通常被认为是邪恶的全局参数。


M N*_*lle 5

让我也推荐 lmfit ( http://lmfit.github.io/lmfit-py/ ) 及其模型类来解决此类问题。Lmfit 为曲线拟合和优化问题提供了更高级别的抽象。

有了lmfit,模型中的每一个参数都变成了一个对象,可以在不改变拟合函数的情况下,固定、自由变化,或者给定上下界。此外,您可以为任何模型定义多个“自变量”。

这为您提供了两种可能的方法。首先,定义参数并修复b

from lmfit import Model
def fitfun(x, a, b):
    return np.exp(a*(x - b))

# turn this model function into a Model:
mymodel = Model(fitfun)

# create parameters with initial values.  Note that parameters are 
# **named** according to the arguments of your model function:
params = mymodel.make_params(a=1, b=10)

# tell the 'b' parameter to not vary during the fit
params['b'].vary = False

# do fit
result = mymodel.fit(ydata, params, x=xdata)
print(result.fit_report())
Run Code Online (Sandbox Code Playgroud)

params不是在合适的改变(更新PARAMS是result.params),所以,以适应另一组数据,你可以只是做:

params['b'].value = 20  #  Note that vary is still False
result2 = mymodel.fit(ydata2, params, x=xdata2)
Run Code Online (Sandbox Code Playgroud)

另一种方法是定义b为自变量:

mymodel = Model(fitfun, independent_vars=['x', 'b'])

params = mymodel.make_params(a=1)
result = model.fit(ydata, params, x=xdata, b=10)
Run Code Online (Sandbox Code Playgroud)

Lmfit 有许多其他不错的曲线拟合功能,包括组合复杂模型和置信区间评估。