带加权误差条的非线性拟合 - Minimizer / scipy.curve_fit / model.fit

时间:2017-05-11 06:31:09

标签: python lmfit

我正在研究Michaelies-Menten的Python拟合代码,这是一个非线性方程,能够包含加权误差条。目前,我尝试使用Minimizer中的model.fitlmfit。虽然Minimizer不包含加权错误栏,但model.fit似乎不如Minimizer统计。 有没有办法在Minimizer中加入加权错误栏? scipy.optimize.curve_fit是否是更适合此代码的方法?
或者是否有更好的适合程序?

我的代码在

下面
def michealies_menten(path, conc, substrate):
os.chdir(path)
h = open('average_STD_data.dat', 'r')
f = open('concentration.dat', 'r')

x = []
y = []
std = []
std_1 = []

for line in h:
    line = line.split(',')
    y.append(line[0])
    std.append(line[1])

for line in f:
    x = line.split(',')

for i in range(len(std)):
    new = 1.0/(float(std[i])**2.0)
    std_1.append(float(new))

std.insert(0, '0')
std_1.insert(0, '0')
x.insert(0, '0')
y.insert(0, '0')
y=map(float,y)
x=map(float,x)
std=map(float,std)
std_1=map(float,std_1)

x=np.array(x)
y=np.array(y)
std_1=np.array(std_1)

####Model.fit code:
def my_model(x, Vmax, Km):
    return Vmax * x / (Km + x)
gmodel = Model(my_model)
result = gmodel.fit(y, x=x, Vmax=4000.0, Km=3.0, weights=std_1)
print result.fit_report()
Vmax_1=result.params['Vmax'].value
Km_1=result.params['Km'].value

model = (Vmax_1*x/(Km_1+x))



###Minimizer code:
def get_residual(params, x, y):
    Vmax = params['Vmax']
    Km = params['Km']
    model = Vmax * x / (Km + x)
    return model - y

#Parameters definition for LmFit
params = Parameters()
params.add('Vmax',value=4000., min=0)
params.add('Km',value=3., min=0)

#Produces the Km and Vmax value which is then extranted
minner = Minimizer(get_residual, params, fcn_args=(x,y))
result = minner.minimize()
print "Result of minization, deviation from y value:", result.residual

#Resulting in the final y-data, which gives the fitted data.
final = y + result.residual
print "I am here, Final:", final

#Gives report over the minimize function
print "Result.params:"
result.params.pretty_print()
print "Report_fit:"
report_fit(result)

#Transfer lmFit output of the minimize(result) to variable for further use
Vmax=result.params['Vmax'].value
Km=result.params['Km'].value
print "Fitted - Heres Km", Km
print "Fitted - Heres Vmax", Vmax

#Draw the different graphs
#plt.plot(x,fitfunc_michment(x, *popt),'b',label='curve_fit')
plt.plot(x,final,'r',label='lmfit')
plt.plot(x,model,'b',label='model')
plt.plot(x,y,'rs',label='Raw')
plt.errorbar(x,y,yerr=std, ecolor='r', linestyle="None")
plt.xlabel(s.join(['Concentration of ', subst ,' [', conc_unit,']']),fontsize=12)
plt.ylabel('Intensity [A.U.]', fontsize=12)
plt.savefig('Michaelis_Menten_plot.png', bbox_inches='tight')
plt.show()
print 'Hello World, i am the Km value: ', Km
print 'Vmax value: ', Vmax
希望你能帮助我! 干杯

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您希望将my_model中描述的模型拟合到数据y(x)(在数组yx中)并使用y中的不确定性1}},std,用于加权拟合 - 最小化(数据模式)/不确定性而不仅仅是数据 - 模型

要使用lmfit.Model执行此操作,您希望传入1./std的权重(可能检查divde-by-zero),如下所示:

result = gmodel.fit(y, x=x, Vmax=4000.0, Km=3.0, weights=1.0/(std))

(我不清楚为什么同时有stdstd_1

要使用Minimize执行此操作,请将std添加为fcn_args元组(要传递给目标函数的参数),并更改目标函数以替换

return model - y

return (model -y)/std

有了这个,你应该准备好了。

FWIW,Model.fit使用Minimizer,因此它不是真的"统计数据较少,而且只是一个不同的重点。

顺便说一下,加载数据可能是更有效的方法(可能是numpy.loadtxt的某些变体),但这不是主要问题。