Curvefit() 没有正确拟合我的数据。如何给一个好的契合?
Curvefit() not fitting my data correctly. How to give a good fit?
我目前正在尝试使用 python 中的 curvefit() 函数按数据进行拟合。形状应该是倒置的 'hump' 形状。然而,这给了我一个抛物线形状。这是代码和图片。任何帮助将不胜感激![1]: https://i.stack.imgur.com/fmRBn.png
def model(x, a, p,q):
return a*np.exp(p*x+q*x**2)
# Input data
x = np.array([11, 11, 11,15,15,15,20,20,20,25,25,25,29,29,29])
y = np.array([2.048, 1.56, 1.18, 2.6116,2.35,2.1036,2.97, 2.97, 2.97, 2.463,2.05,1.6679,1.825,1.0939,0.534])
[enter image description here][1]
# Fit
popt, pcov = curve_fit(model, x, y)
# prepare some data for a plot
xx = np.linspace(-20, 60)
yy = model(xx, *popt)
plt.plot(x, y, 'o', xx, yy)
plt.title('Exponential Fit')
plt.ylim(0,5)
plt.xlim(-5,30)
plt.grid()
plt.show()
print(popt)
看看你的数据,我建议放弃指数模型,只保留抛物线函数
def simple_model(x, a, p,q):
return p*x + q*x**2 + a
对于复杂的非线性函数,曲线拟合无法发挥魔力,保持简单,然后您可能会向模型中添加更多内容。
无论如何,如果您更愿意坚持自己的模型,您可以设置 curve_fit 将尝试优化的 a、p 和 q 初始值的种子:
popt, pcov = curve_fit(model, x, y, p0=[a_seed, p_seed, q_seed])
对 a_seed、p_seed、q_seed 进行合理的初步猜测可能会有所帮助。祝你好运!
curve_fit
(与许多迭代拟合和优化方法一样)在给定合理起点时表现最佳。 curve_fit
的默认初始猜测是全 1,这对你的问题来说是一个非常糟糕的猜测——产生警告,发生溢出,返回的 pcov
是所有 inf
的数组值(你检查了吗?)。
经过反复试验,我能够通过使用 p0=[0.1, 0.1, -0.001]
:
获得看起来合理的匹配
In [123]: popt, pcov = curve_fit(model, x, y, p0=[0.1, 0.1, -0.001])
In [124]: popt
Out[124]: array([ 0.0847053 , 0.36886652, -0.00961928])
In [125]: pcov
Out[125]:
array([[ 2.96403174e-03, -3.64981635e-03, 8.97783126e-05],
[-3.64981635e-03, 4.61677436e-03, -1.15963105e-04],
[ 8.97783126e-05, -1.15963105e-04, 2.96960195e-06]])
这是您的数据图和拟合曲线:
我目前正在尝试使用 python 中的 curvefit() 函数按数据进行拟合。形状应该是倒置的 'hump' 形状。然而,这给了我一个抛物线形状。这是代码和图片。任何帮助将不胜感激![1]: https://i.stack.imgur.com/fmRBn.png
def model(x, a, p,q):
return a*np.exp(p*x+q*x**2)
# Input data
x = np.array([11, 11, 11,15,15,15,20,20,20,25,25,25,29,29,29])
y = np.array([2.048, 1.56, 1.18, 2.6116,2.35,2.1036,2.97, 2.97, 2.97, 2.463,2.05,1.6679,1.825,1.0939,0.534])
[enter image description here][1]
# Fit
popt, pcov = curve_fit(model, x, y)
# prepare some data for a plot
xx = np.linspace(-20, 60)
yy = model(xx, *popt)
plt.plot(x, y, 'o', xx, yy)
plt.title('Exponential Fit')
plt.ylim(0,5)
plt.xlim(-5,30)
plt.grid()
plt.show()
print(popt)
看看你的数据,我建议放弃指数模型,只保留抛物线函数
def simple_model(x, a, p,q):
return p*x + q*x**2 + a
对于复杂的非线性函数,曲线拟合无法发挥魔力,保持简单,然后您可能会向模型中添加更多内容。
无论如何,如果您更愿意坚持自己的模型,您可以设置 curve_fit 将尝试优化的 a、p 和 q 初始值的种子:
popt, pcov = curve_fit(model, x, y, p0=[a_seed, p_seed, q_seed])
对 a_seed、p_seed、q_seed 进行合理的初步猜测可能会有所帮助。祝你好运!
curve_fit
(与许多迭代拟合和优化方法一样)在给定合理起点时表现最佳。 curve_fit
的默认初始猜测是全 1,这对你的问题来说是一个非常糟糕的猜测——产生警告,发生溢出,返回的 pcov
是所有 inf
的数组值(你检查了吗?)。
经过反复试验,我能够通过使用 p0=[0.1, 0.1, -0.001]
:
In [123]: popt, pcov = curve_fit(model, x, y, p0=[0.1, 0.1, -0.001])
In [124]: popt
Out[124]: array([ 0.0847053 , 0.36886652, -0.00961928])
In [125]: pcov
Out[125]:
array([[ 2.96403174e-03, -3.64981635e-03, 8.97783126e-05],
[-3.64981635e-03, 4.61677436e-03, -1.15963105e-04],
[ 8.97783126e-05, -1.15963105e-04, 2.96960195e-06]])
这是您的数据图和拟合曲线: