对包含非矢量化函数(如定积分)的模型执行拟合(使用 LMFIT)的正确方法是什么?
What is the correct way to perform fitting (using LMFIT) for a model which contains a non vectorized function such as a definite integral?
我想用一个包含定积分的函数对一些数据进行拟合,就拟合而言,积分极限之一也是自变量。我想具体知道如何使用 'lmfit' 来实现。
考虑以下示例:
import numpy as np
import scipy.optimize
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import scipy.integrate as integrate
from lmfit import minimize, Parameters, report_fit
def integrand(x,amp,xc,w):
return amp*np.exp((-(x-xc)**2)/w)
def curve(x0,amp,xc,w):
res = integrate.quad(integrand, 0, x0, args=(amp,xc,w)) #x0 is the independent variable here
return res[0]
vcurve = np.vectorize(curve, excluded=set([1]))
# vectorizing the output of the function which includes the integration step
# Generating the data with noise
xdata = np.linspace(0,10,20)
ydata = vcurve(xdata,1,5,1) + 0.1 * np.random.randn(len(xdata))
def residual(params, x, data):
amp = params['amp']
xc = params['xc']
w = params['w']
model = vcurve(xdata,amp,xc,w)
return data-model
# defining the parameters and providing the initial values
params = Parameters()
params.add('amp', value=1,vary=True)
params.add('xc', value=5,vary=True)
params.add('w', value=1,vary=True)
out = minimize(residual, params, args=(xdata, ydata))
然而这会导致错误:
---> out = minimize(residual, params, args=(xdata, ydata))
...
...
...
TypeError: __array__() takes 1 positional argument but 2 were given
似乎参数的初始值没有被正确读取
使用 scipy 曲线拟合,我可以使其按如下方式工作:
popt, pcov = curve_fit(vcurve, xdata, ydata, p0=[2,2,2])
fig, ax = plt.subplots(1,1)
ax.plot(xdata,ydata,label='Observed',ls='',marker='o')
#Plotting the best fit
xx = np.linspace(0,10,50)
ax.plot(xx,vcurve(xx,popt[0],popt[1],popt[2]),label='Best Fit')
ax.legend()
print(popt)
这为我提供了最佳拟合参数的合理值。
任何关于如何使用 lmfit 进行这项工作的建议将不胜感激
您需要在 residual
函数中解压 params
并使用正确的参数调用 vcurve
-- 参数值而不是参数对象:
def residual(params, x, data):
amp = params['amp'].value
xc = params['xc'].value
w = params['w'].value
model = vcurve(xdata,amp,xc,w)
return data-model
我想用一个包含定积分的函数对一些数据进行拟合,就拟合而言,积分极限之一也是自变量。我想具体知道如何使用 'lmfit' 来实现。 考虑以下示例:
import numpy as np
import scipy.optimize
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import scipy.integrate as integrate
from lmfit import minimize, Parameters, report_fit
def integrand(x,amp,xc,w):
return amp*np.exp((-(x-xc)**2)/w)
def curve(x0,amp,xc,w):
res = integrate.quad(integrand, 0, x0, args=(amp,xc,w)) #x0 is the independent variable here
return res[0]
vcurve = np.vectorize(curve, excluded=set([1]))
# vectorizing the output of the function which includes the integration step
# Generating the data with noise
xdata = np.linspace(0,10,20)
ydata = vcurve(xdata,1,5,1) + 0.1 * np.random.randn(len(xdata))
def residual(params, x, data):
amp = params['amp']
xc = params['xc']
w = params['w']
model = vcurve(xdata,amp,xc,w)
return data-model
# defining the parameters and providing the initial values
params = Parameters()
params.add('amp', value=1,vary=True)
params.add('xc', value=5,vary=True)
params.add('w', value=1,vary=True)
out = minimize(residual, params, args=(xdata, ydata))
然而这会导致错误:
---> out = minimize(residual, params, args=(xdata, ydata))
...
...
...
TypeError: __array__() takes 1 positional argument but 2 were given
似乎参数的初始值没有被正确读取
使用 scipy 曲线拟合,我可以使其按如下方式工作:
popt, pcov = curve_fit(vcurve, xdata, ydata, p0=[2,2,2])
fig, ax = plt.subplots(1,1)
ax.plot(xdata,ydata,label='Observed',ls='',marker='o')
#Plotting the best fit
xx = np.linspace(0,10,50)
ax.plot(xx,vcurve(xx,popt[0],popt[1],popt[2]),label='Best Fit')
ax.legend()
print(popt)
这为我提供了最佳拟合参数的合理值。 任何关于如何使用 lmfit 进行这项工作的建议将不胜感激
您需要在 residual
函数中解压 params
并使用正确的参数调用 vcurve
-- 参数值而不是参数对象:
def residual(params, x, data):
amp = params['amp'].value
xc = params['xc'].value
w = params['w'].value
model = vcurve(xdata,amp,xc,w)
return data-model