【发布时间】:2022-02-13 21:30:34
【问题描述】:
到目前为止我做了什么:
我正在尝试将噪声数据(我通过向我的函数添加随机噪声自己生成)拟合到我定义的 Gauss-Hermite 函数。在某些情况下,它适用于较低的 h3 和 h4 值,但每隔一段时间,即使对于较低的 h3、h4 值,它也会产生非常糟糕的拟合,而对于较高的 h3、h4 值,它总是会产生不好的拟合。
我的代码:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as mpl
import matplotlib.pyplot as plt
# Let's define the Gauss-Hermite function
#a=amplitude, x0=location of peak, sig=std dev, h3, h4
def gh_func(x, a, x0, sig, h3, h4):
return a*np.exp(-.5*((x-x0)/sig)**2)*(1+h3*((-np.sqrt(3))*((x-x0)/sig)+(2/np.sqrt(3))*((x-x0)/sig)**3)+ h4*((np.sqrt(6)/4)+(-np.sqrt(6))*((x-x0)/sig)**2+(np.sqrt(6)/3)*(((x-x0)/sig)**4)))
#generate clean data
x = np.linspace(-10, 20, 100)
y = gh_func(x, 10, 5, np.sqrt(3), -0.10,-0.03) #it gives okay fit for h3=-0.10, h4=-0.03 but bad fits for higher values like h3=-0.4 and h4=-0.3.
#add noise to data
noise=np.random.normal(0,np.sqrt(0.5),size=len(x))
yn = y + noise
fig = mpl.figure(1)
ax = fig.add_subplot(111)
ax.plot(x, y, c='k', label='analytic function')
ax.scatter(x, yn, s=5, label='fake noisy data')
fig.savefig('model_and_noise_h3h4.png')
# Executing curve_fit on noisy data
popt, pcov = curve_fit(gh_func, x, yn)
#popt returns the best fit values for parameters of the given model (func)
print('Fitted Parameters (Gaus_Hermite):\na = %.10f , x0 = %.10f , sig = %.10f\nh3 = %.10f , h4 = %.10f' \
%(popt[0],popt[1],popt[2],popt[3],popt[4]))
ym = gh_func(x, popt[0], popt[1], popt[2], popt[3], popt[4])
ax.plot(x, ym, c='r', label='Best fit')
ax.legend()
fig.savefig('model_fit_h3h4.png')
plt.legend(loc='upper left')
plt.xlabel("v")
plt.ylabel("f(v)")
我想做什么:
我想找到比 scipy.optimize 中的 curve_fit 更好的拟合方法,但我不确定我可以使用什么。即使我们最终使用curve_fit,我也需要一种方法来通过为自动生成的参数提供初始猜测来产生更好的拟合,例如这篇文章的公认答案(Jean Jacquelin 的方法)描述了一种仅用于单峰高斯的方法:gaussian fitting inaccurate for lower peak width using Python。但这仅适用于 mu、sigma 和振幅而不是 h3、h4。
除了来自 scipy.optimize 的 curve_fit,我认为还有一个叫做 lmfit:https://lmfit.github.io/lmfit-py/ 但我不确定我将如何在我的代码中实现它。我不想对参数使用手动初始猜测。我希望能够自动找到配件。
非常感谢!
【问题讨论】:
-
(1) 对我来说,无噪声数据(黑线)的拟合(红线)非常好。添加的噪声大于红线和黑线之间的差异。减少噪音的标准差可能会导致更好的拟合。 (2) 两个不同的参数集(有 33-50% 的不同
h4)可以产生相似的曲线。这是您在此处拥有的 GH 函数的固有模型可识别性问题。 (3) 考虑使用 MAE 或截断的 MAE(例如:min(MAE, 3.5))作为目标函数。 MSE 严厉惩罚大错误,导致小错误被忽略。截断的 MAE 对我来说效果最好(不完美)。
标签: python numpy scipy curve-fitting gaussian