我对python相当陌生,我正尝试使用lmfit进行一些曲线拟合。代码运行得很好,但我想通过原点(0,0)强制拟合。我在stakoverlow看到过,使用“曲线拟合”,你可以添加和属性“sigma”来达到这个目的,但这在“最小化”中不起作用。你有什么解决办法吗???在
到目前为止,这是我的代码:
##############################################################################
###################### IMPORT MODULES ########################################
##############################################################################
import numpy as np
import matplotlib.pyplot as plt
from lmfit import minimize, Parameters
from lmfit import report_fit
##############################################################################
##################### DATA ##################################
##############################################################################
x=np.array([0,1, 4, 6, 8, 9, 11, 13, 15, 18, 20, 27])
data=np.array([0, 67, 208, 339, 460, 539, 599, 635, 659, 685, 701, 731])
##############################################################################
######################## GOMPERTZ FUNCTION DEFINITION#########################
##############################################################################
def BMP_Gompertz(params, x, data):
BMPmax=params['BMPmax'].value
Rmax=params['Rmax'].value
Lambda=params['Lambda'].value
model=BMPmax*np.exp(-np.exp(Rmax*np.exp(1)/BMPmax*(Lambda-x)+1))
global model_data
model_data=[BMPmax,Rmax,Lambda]
return data-model
params=Parameters()
params.add('BMPmax', value=300., min=0.)
params.add('Rmax', value=25., min=0.)
params.add('Lambda',value=0.5, min=0.)
model_data=[]
##############################################################################
###################### GOMPERTZ CURVE FITTING & REPORT #######################
##############################################################################
result=minimize(BMP_Gompertz, params, args=(x,data))
report_fit(result.params)
##############################################################################
########################## GOMPERTZ PLOTTING #################################
##############################################################################
plt.plot(x, data, 'bo')
t=np.linspace(0.,100,10000)
plt.plot(t,model_data[0]*np.exp(-np.exp(model_data[1]*np.exp(1)/model_data[0]*(model_data[2]-t)+1)))
plt.xlabel('Days')
plt.ylabel('BMP (NLbiogas/kg SV)')
plt.show()
如您所见,拟合不是从(0,0)开始,而是在(0,10)左右开始,我希望始终强制它从(0,0)开始。。。看起来我还不能上传图片(还没有个人任务)。。。不管怎样,我想你能明白。在
还有一个问题,有没有其他方法来存储参数和绘制结果?。现在要存储模型返回的参数,我将它们存储在名为“model_data”的全局变量中。然后,在plot部分,我使用linspace创建了一个名为“t”的新“x”数组,然后使用存储在“model_data”中的参数绘制t vs BMP_Gompertz(myfunction)。工作很完美,但看起来应该是其他更好的方法。在
非常感谢你的帮助
我不确定你所有不同的问题都能得到完全的回答,但以下是一些评论:
可以为配合添加权重。在使用
minimize
的示例中,您可以传递一个数组sigma
,并将return data-model
更改为return (data-model)/sigma
。下面,我将推荐使用lmfit.Model
,它有一个稍微不同的方法来指定权重。让你当前的模型通过(0,0)将是一个挑战,即使使用加权。也就是说,指数函数会衰减,但永远不会达到0,所以你可能需要决定什么是“足够零”。如果这是物理需求,则可能需要修改模型。
拟合结果将被存储,您不需要使用
model_data
。返回的result.params
包含最适合的参数,您可以得到result.params['Rmax'].value
等。{{{你建议使用cd9}来简化曲线拟合。使用
lmfit.Model
您在目标函数中所做的大部分工作都是为您完成的,您的脚本将变成:要将权重添加到模型拟合中,可以定义一个用于乘
^{pr2}$data-model
的权重数组,并将其传递给Model.fit
。要强调具有最小值的数据(并将拟合推向(0,0),可以使用如下方法:同样,这将强调较小的
y
值,并倾向于将x=0
处的模型值向下推,但不会真正强制结果精确到(0,0)。在相关问题 更多 >
编程相关推荐