由于数据值看起来太小,无法使用 lmfit 进行高斯拟合
Trouble fitting Gaussian fit using lmfit due to data values appearing to be too small
我正在尝试使用 lmfit 模块对以下数据进行高斯拟合:
x = np.array([-1.36534351e-09, -1.29984067e-09, -1.23433782e-09, -1.16883498e-09,
-1.10333214e-09, -1.03782929e-09, -9.72326447e-10, -9.06823602e-10,
-8.41320758e-10, -7.75817913e-10, -7.10315069e-10, -6.44812224e-10,
-5.79309380e-10, -5.13806535e-10, -4.48303691e-10, -3.82800846e-10,
-3.17298002e-10, -2.51795157e-10, -1.86292313e-10, -1.20789468e-10,
-5.52866238e-11, 1.02162207e-11, 7.57190652e-11, 1.41221910e-10,
2.06724754e-10, 2.72227599e-10, 3.37730443e-10, 4.03233288e-10,
4.68736132e-10, 5.34238977e-10, 5.99741821e-10, 6.65244666e-10,
7.30747510e-10, 7.96250355e-10, 8.61753199e-10, 9.27256043e-10,
9.92758888e-10, 1.05826173e-09, 1.12376458e-09, 1.18926742e-09,
1.25477027e-09, 1.32027311e-09, 1.38577595e-09, 1.45127880e-09,
1.51678164e-09, 1.58228449e-09, 1.64778733e-09, 1.71329018e-09,
1.77879302e-09, 1.84429587e-09])
y = np.array([ 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 2, 4, 7, 8, 17, 13, 45,
77, 182, 346, 494, 512, 443, 327, 192, 115, 62, 28, 20, 16, 13, 5, 6, 2, 1, 0,
0, 2, 4, 1, 2, 2, 1, 2, 2, 1, 2, 2, 0, 1])
当我拟合数据并绘制它时,我得到以下结果:
有趣的是,如果我将 x 数据数组乘以 100,拟合效果似乎很好:
我怀疑这可能是由于最初的猜测不准确,但我仍然不太清楚为什么会这样,以及我该如何解决这个问题。我在下面包含了完整的代码:
import matplotlib.pyplot as plt
from lmfit.models import GaussianModel
import numpy as np
x = np.array([-1.36534351e-09, -1.29984067e-09, -1.23433782e-09, -1.16883498e-09,
-1.10333214e-09, -1.03782929e-09, -9.72326447e-10, -9.06823602e-10,
-8.41320758e-10, -7.75817913e-10, -7.10315069e-10, -6.44812224e-10,
-5.79309380e-10, -5.13806535e-10, -4.48303691e-10, -3.82800846e-10,
-3.17298002e-10, -2.51795157e-10, -1.86292313e-10, -1.20789468e-10,
-5.52866238e-11, 1.02162207e-11, 7.57190652e-11, 1.41221910e-10,
2.06724754e-10, 2.72227599e-10, 3.37730443e-10, 4.03233288e-10,
4.68736132e-10, 5.34238977e-10, 5.99741821e-10, 6.65244666e-10,
7.30747510e-10, 7.96250355e-10, 8.61753199e-10, 9.27256043e-10,
9.92758888e-10, 1.05826173e-09, 1.12376458e-09, 1.18926742e-09,
1.25477027e-09, 1.32027311e-09, 1.38577595e-09, 1.45127880e-09,
1.51678164e-09, 1.58228449e-09, 1.64778733e-09, 1.71329018e-09,
1.77879302e-09, 1.84429587e-09])
y = np.array([ 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 2, 4, 7, 8, 17, 13, 45,
77, 182, 346, 494, 512, 443, 327, 192, 115, 62, 28, 20, 16, 13, 5, 6, 2, 1, 0, 0, 2,
4, 1, 2, 2, 1, 2, 2, 1, 2, 2, 0, 1])
mod = GaussianModel()
pars = mod.guess(y, x=x)
final_fit = mod.fit(y, pars, x=x)
plt.plot(x, final_fit.init_fit, label='Initial fit')
plt.plot(x, final_fit.best_fit, label='Gaussian fit')
plt.scatter(x, y, label='data points')
plt.show()
更新:
我已经在另一台计算机上测试了完全相同的程序,结果证明它在那里工作得很好。现在,我不太确定。
正如 Jan Christoph Terasa 评论的那样,您的 x
值的精度几乎肯定是问题所在。进行拟合时,底层算法需要对参数值进行较小的相对更改,以查看这对拟合有何影响。更改通常在 1.e-7 级别。这意味着当使用 1e.-9 级别的值时,更改将接近机器精度并且可能对结果没有影响(并且,是的,这可能取决于机器细节)。
解决方案是更改 x
和/或 y
数据的比例,使其在 1.e-6 到 1.e6 的范围内.幸运的是,对于您的情况,您似乎可以通过乘以 1e9 并以 "nano-x".
为单位来更改 x
我正在尝试使用 lmfit 模块对以下数据进行高斯拟合:
x = np.array([-1.36534351e-09, -1.29984067e-09, -1.23433782e-09, -1.16883498e-09,
-1.10333214e-09, -1.03782929e-09, -9.72326447e-10, -9.06823602e-10,
-8.41320758e-10, -7.75817913e-10, -7.10315069e-10, -6.44812224e-10,
-5.79309380e-10, -5.13806535e-10, -4.48303691e-10, -3.82800846e-10,
-3.17298002e-10, -2.51795157e-10, -1.86292313e-10, -1.20789468e-10,
-5.52866238e-11, 1.02162207e-11, 7.57190652e-11, 1.41221910e-10,
2.06724754e-10, 2.72227599e-10, 3.37730443e-10, 4.03233288e-10,
4.68736132e-10, 5.34238977e-10, 5.99741821e-10, 6.65244666e-10,
7.30747510e-10, 7.96250355e-10, 8.61753199e-10, 9.27256043e-10,
9.92758888e-10, 1.05826173e-09, 1.12376458e-09, 1.18926742e-09,
1.25477027e-09, 1.32027311e-09, 1.38577595e-09, 1.45127880e-09,
1.51678164e-09, 1.58228449e-09, 1.64778733e-09, 1.71329018e-09,
1.77879302e-09, 1.84429587e-09])
y = np.array([ 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 2, 4, 7, 8, 17, 13, 45,
77, 182, 346, 494, 512, 443, 327, 192, 115, 62, 28, 20, 16, 13, 5, 6, 2, 1, 0,
0, 2, 4, 1, 2, 2, 1, 2, 2, 1, 2, 2, 0, 1])
当我拟合数据并绘制它时,我得到以下结果:
有趣的是,如果我将 x 数据数组乘以 100,拟合效果似乎很好:
我怀疑这可能是由于最初的猜测不准确,但我仍然不太清楚为什么会这样,以及我该如何解决这个问题。我在下面包含了完整的代码:
import matplotlib.pyplot as plt
from lmfit.models import GaussianModel
import numpy as np
x = np.array([-1.36534351e-09, -1.29984067e-09, -1.23433782e-09, -1.16883498e-09,
-1.10333214e-09, -1.03782929e-09, -9.72326447e-10, -9.06823602e-10,
-8.41320758e-10, -7.75817913e-10, -7.10315069e-10, -6.44812224e-10,
-5.79309380e-10, -5.13806535e-10, -4.48303691e-10, -3.82800846e-10,
-3.17298002e-10, -2.51795157e-10, -1.86292313e-10, -1.20789468e-10,
-5.52866238e-11, 1.02162207e-11, 7.57190652e-11, 1.41221910e-10,
2.06724754e-10, 2.72227599e-10, 3.37730443e-10, 4.03233288e-10,
4.68736132e-10, 5.34238977e-10, 5.99741821e-10, 6.65244666e-10,
7.30747510e-10, 7.96250355e-10, 8.61753199e-10, 9.27256043e-10,
9.92758888e-10, 1.05826173e-09, 1.12376458e-09, 1.18926742e-09,
1.25477027e-09, 1.32027311e-09, 1.38577595e-09, 1.45127880e-09,
1.51678164e-09, 1.58228449e-09, 1.64778733e-09, 1.71329018e-09,
1.77879302e-09, 1.84429587e-09])
y = np.array([ 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 2, 4, 7, 8, 17, 13, 45,
77, 182, 346, 494, 512, 443, 327, 192, 115, 62, 28, 20, 16, 13, 5, 6, 2, 1, 0, 0, 2,
4, 1, 2, 2, 1, 2, 2, 1, 2, 2, 0, 1])
mod = GaussianModel()
pars = mod.guess(y, x=x)
final_fit = mod.fit(y, pars, x=x)
plt.plot(x, final_fit.init_fit, label='Initial fit')
plt.plot(x, final_fit.best_fit, label='Gaussian fit')
plt.scatter(x, y, label='data points')
plt.show()
更新: 我已经在另一台计算机上测试了完全相同的程序,结果证明它在那里工作得很好。现在,我不太确定。
正如 Jan Christoph Terasa 评论的那样,您的 x
值的精度几乎肯定是问题所在。进行拟合时,底层算法需要对参数值进行较小的相对更改,以查看这对拟合有何影响。更改通常在 1.e-7 级别。这意味着当使用 1e.-9 级别的值时,更改将接近机器精度并且可能对结果没有影响(并且,是的,这可能取决于机器细节)。
解决方案是更改 x
和/或 y
数据的比例,使其在 1.e-6 到 1.e6 的范围内.幸运的是,对于您的情况,您似乎可以通过乘以 1e9 并以 "nano-x".
x