【发布时间】:2021-08-24 08:12:42
【问题描述】:
我以 scipy optimize curve_fit.(https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html) 的官方文档页面为例,稍微修改了示例中的函数,scipy 抛出警告“无法估计参数的协方差”并给我不合适。在我看来,这样一个不是很特殊的函数的拟合应该可以正常工作,所以 curve_fit 似乎工作得很糟糕,或者我错过了一些点并且开始不好?有人可以给我一个提示是什么问题或我可以使用哪个库。
from scipy.optimize import curve_fit
def func(x, a, b, c):
return a - b*np.exp(-c*x)
xdata = np.linspace(0, 4, 50)
y = func(xdata, 823.5, 5.3, 8.2)
rng = np.random.default_rng()
y_noise = 0.2 * rng.normal(size=xdata.size)
ydata = y + y_noise
plt.plot(xdata, ydata, 'b-', label='data')
popt, pcov = curve_fit(func, xdata, ydata)
plt.plot(xdata, func(xdata, *popt), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
plt.plot(xdata, y, 'g--', label='Original')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()```
【问题讨论】:
-
一如既往....这是起始值。
curve_fit假设,如果没有另外给出,顺序值1。现在a明显关闭了,但是chi^2也可以通过增加c来减少。这正是算法所做的。只有到最后(我猜)a才会进一步提高(可能会同时发生)。然而,在这一点上,解决方案与真正的全局最小值相差甚远,以至于“收敛”停止在参数空间中定义不太明确的位置;可能不是抛物线最小值。给出合理的良好起始值,它就会起作用。 -
您好 Mikus,感谢您的回复。我尝试代替
a(a+820') 和xdata = np.linspace(0, 4, 50)(xdata = np.linspace(0.1, 4, 50))。我想我没明白你的意思?起点和值的顺序是什么意思?上面的代码是完整的,可以模拟问题。你能按照你的意思修复上面的代码吗? -
解决方案是
popt, pcov = curve_fit( func, xdata, ydata, p0=( 800, 10, 1) )。请注意,线性拟合只是一组线性方程的解。对于非线性拟合,可以通过在一组参数处线性化方程并继续求解来迭代地执行此操作。然而,这需要一些起点。但是,非线性方程可以在 chi^2 曲面中具有局部最小值,并且起点的梯度可能指向该方向。或者,更像您的情况,梯度指向远离全局最小值但指向不存在真正最小值的方向。 -
请注意,您的方程可以使用此处介绍的技术以线性方式拟合:de.scribd.com/doc/14674814/Regressions-et-equations-integrales 您不需要太多法语就可以理解这一点。
-
非常感谢您的帮助。所以,我仍然会保留我的笔并保存一些白纸;-)。
标签: python curve-fitting scipy-optimize