scipy.optimize curve_fit()即使使用正确的参数也不会收敛

rbpvctlc  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(323)

我找不到高斯曲线拟合的参数。
网站https://mycurvefit.com/很快就给出了一个很好的答案,但是,我用python的curve_fit()(来自scipy.optimize库)实现的结果并不好(即使在输入答案时)。
例如,我试图拟合的方程如下:

def gauss_func(x, a, b, c):
    return a * np.exp(-(x-b)**2/(2*c**2))

带输入点:

x_main = np.array([19.748, 39.611, 59.465])
y_main = np.array([0.438160379, 0.008706677, 0.000160106])

在这里我想找到参数aBc。从mycurvefit网站上,我得到了答案:
a = 4821416个单位
B = -154.0293的平均值
c = 30.51661单位
它很好地拟合了给定的点。但是当我尝试运行curve_fit()时:

poptMain, pcovMain = curve_fit(gauss_func, x_main, y_main, p0=(1, -1, 1),sigma=np.array([1,1,1]))

我得到**“运行时错误:未找到最佳参数:对函数的调用次数已达到maxfev = 800。"**错误。
我尝试过:

  • 将maxfev更改为其他值,如5000、10000、100000(无影响)。
  • 将初始猜测p0替换为更接近mycurvefit答案的值(无效果)和诸如[1,1,1]、[1,0,1]等的公共值(无效果)。

即使在输入答案时,它仍然找不到参数!我以前在其他类似的案例中使用过同样的代码,效果很好。但这次它根本不收敛。我该怎么做才能解决这个问题?

vulvrdjw

vulvrdjw1#

您的问题是尝试用三个未知数(a,b,c)和三个点来拟合一个方程,这有时会有收敛问题。您需要在用于拟合的数组中给予更多的值,用于拟合的点的数量应该至少比未知数的数量多一个,在您的情况下,最小值将是4个值,但最好给出更多的值。
如果不是这样,你可能会遇到问题。例如,使用你给a b和c的值,a已经创建了一些数据,通过绘制这些值,你可以看到数组的点确实在曲线的边缘,这表明你给的a*bc**的值肯定是不正确的。

import numpy as np

def gauss_func(x, a, b, c):
    return a * np.exp(-(x-b)**2/(2*c**2))

# create data using the values of a b and c you have give

x = np.linspace(-360, 60, 100)

# create y values and add random noise

y = gauss_func(x, 4821416, -154.0293, 30.51661) + np.random.normal(0, 100000, x.shape)

# fit the created data

poptMain, pcovMain = curve_fit(gauss_func, x, y, p0=(2000, -1, 1))

# plot data

plt.figure()
plt.plot(x, y, label='created data')
plt.plot(x, gauss_func(x, *poptMain), label='fit created data')
plt.scatter(x_main, y_main, label='points given', color='r', zorder=3)
plt.legend()
plt.show()

注意所创建的数据是使用您认为是真值的值创建的:

a = 4821416; B = -154.0293和c = 30.51661 x1c 0d1x

相关问题