微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有变量和常量参数的 Scipy curve_fit

如何解决带有变量和常量参数的 Scipy curve_fit

我正在尝试使用带有两个变量参数和一个常量的 curve_fit 方程拟合数据点。由于我想测试常量的不同值,所以我想避免将其写入函数

使用 Scipy 中的示例,我尝试这样做:

def func(x,a,b,c):
    return a * np.exp(-b * x) + c

a_test = 3

popt,pcov = curve_fit(func,xdata,ydata,bounds=([a_test,0],[a_test,1.,0.5]))

但是我得到一个错误,因为第一个参数的下限和上限相等。

有没有办法在不使用其他库(例如 lmfit)的情况下做到这一点?

解决方法

我不知道之前的答案是什么,但我认为你应该这样做:

import numpy as np
from scipy.optimize import *

a_test = 3

def func(x,b,c,a=a_test ):
    return a * np.exp(-b * x) + c

xdata = range(11,17)
ydata = [a_test * np.exp(-0.8 * x) + 0.2 for x in xdata]

popt,pcov = curve_fit(func,xdata,ydata,bounds=([0,0],[1.,0.5]))

print(popt,pcov)

导致

popt = [0.79999036 0.19999999]
pcov = [[2.78472686e-11 4.44800146e-14]
 [4.44800146e-14 1.50965321e-16]]
,

编写一个函数,该函数返回一个将拟合函数与变量常量包装在一起的函数(是的:即三个函数):

def func(x,a,c):
    return a * np.exp(-b * x) + c

def wrapperfunc(a_test):
    def tempfunc(x,a=a_test):
        return func(x,c)
    return tempfunc

a_test = 3

xdata = range(11,17)
ydata = [a_test * np.exp(-0.8 * x) + 0.2 for x in xdata]

# Note: run `wrapperfunc`,so that the actual fitting func (`tempfunc`) is returned
popt,pcov = curve_fit(wrapperfunc(a_test),pcov)

a_test = 4

xdata = range(11,pcov)
,

为了清楚起见,如原始问题所述,使用 lmfit 可以轻松完成此类操作。这样的事情会做:

import lmfit
import numpy as np
def func(x,c):
    return a * np.exp(-b * x) + c

model = lmfit.Model(func)
params = lmfit.Parameters() 
params.add('a',value=3,vary=False)
params.add('b',value=0.5,min=0,max=1)
params.add('c',value=0.25,max=1)

# test values for a,find one with lowest chi-square
best_result,best_a,best_chisqr = None,None,1e199
for aval in np.linspace(0,10,21):
    params['a'].value = aval
    result = model.fit(ydata,params,x=xdata)
    if result.chisqr < best_chisqr:
       best_chisqr = result.chisqr
       best_result = result
       best_a = aval

print(f"### best value for a = {best_a:.2f}")
print(best_result.fit_report())

请注意,尝试通过设置值的下限和上限来冻结变量会导致统计分析中关于问题中是否有 2 个或 3 个变量的混淆。另一方面,此处所示的循环显然一次使用 2 个变量,但它确实忽略了 a 是一种可变参数。为了最稳健,您可能希望允许 a 变化。

使用 lmfit 的“负担”是必须运行“pip install lmfit”,这可能需要几秒钟的时间——甚至可能需要您阅读此消息的时间。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。