使用 Python lmfit 进行曲线拟合的参数估计
Parameters estimation for curve fitting with Python lmfit
我正在使用 Python lmfit
对 2005-2016 年的月平均数据进行最小二乘拟合。我构建了如下函数:
equation
原代码如下:
# t is in fractional years, e.g. 2017+122./365.
def fun(t, a, b, c, A1, A2, A3, A4, B1, B2, B3, B4):
An=[A1,A2,A3,A4]
Bn=[B1,B2,B3,B4]
sum=np.sum([An[i] * np.sin(2 * np.pi * (i + 1) * t+Bn[i]) for i in range(len(An))])
return a+b*t+c*t*t+sum
mod = Model(fun)
pars = mod.make_params(a=-10, b=0.003, c=0.01, A1=-1., A2=1., A3=1., A4=1., B1=-1., B2=1., B3=1., B4=1.)
result = mod.fit(y, pars, t=t)
print(result.fit_report())
plt.plot(t, y, 'bo')
plt.plot(t, result.best_fit, 'r-')
plt.show()
fitted line and the original data dots
傅里叶项似乎不起作用。因此,我很好奇如何对A1
、A2
、A3
...等函数参数给出一个合适的初始估计?
np.sum
没有按照您的意愿行事。它会将您的表达式加起来为单个标量值,而不是与 t
长度相同的数组。然后,该标量值会将您的参数 A1
、... B4
折叠为单个值,并且拟合将无法确定这些值。
我想你想制作一个形状为 (4, len(t)
) 的二维数组,然后仅对第一个维度求和,留下 len(t)
的数组,即第 4 个维度的总和傅里叶分量。
尝试更换您的
sum=np.sum([An[i]*np.sin(2*np.pi*(i+1)*t+Bn[i]) for i in range(len(An))])
和
sum=np.array([An[i]*np.sin(2*np.pi*(i+1)*t+Bn[i]) for i in range(len(An))]).sum(axis=0)
我正在使用 Python lmfit
对 2005-2016 年的月平均数据进行最小二乘拟合。我构建了如下函数:
equation
原代码如下:
# t is in fractional years, e.g. 2017+122./365.
def fun(t, a, b, c, A1, A2, A3, A4, B1, B2, B3, B4):
An=[A1,A2,A3,A4]
Bn=[B1,B2,B3,B4]
sum=np.sum([An[i] * np.sin(2 * np.pi * (i + 1) * t+Bn[i]) for i in range(len(An))])
return a+b*t+c*t*t+sum
mod = Model(fun)
pars = mod.make_params(a=-10, b=0.003, c=0.01, A1=-1., A2=1., A3=1., A4=1., B1=-1., B2=1., B3=1., B4=1.)
result = mod.fit(y, pars, t=t)
print(result.fit_report())
plt.plot(t, y, 'bo')
plt.plot(t, result.best_fit, 'r-')
plt.show()
fitted line and the original data dots
傅里叶项似乎不起作用。因此,我很好奇如何对A1
、A2
、A3
...等函数参数给出一个合适的初始估计?
np.sum
没有按照您的意愿行事。它会将您的表达式加起来为单个标量值,而不是与 t
长度相同的数组。然后,该标量值会将您的参数 A1
、... B4
折叠为单个值,并且拟合将无法确定这些值。
我想你想制作一个形状为 (4, len(t)
) 的二维数组,然后仅对第一个维度求和,留下 len(t)
的数组,即第 4 个维度的总和傅里叶分量。
尝试更换您的
sum=np.sum([An[i]*np.sin(2*np.pi*(i+1)*t+Bn[i]) for i in range(len(An))])
和
sum=np.array([An[i]*np.sin(2*np.pi*(i+1)*t+Bn[i]) for i in range(len(An))]).sum(axis=0)