在 loglog 轴上拟合指数函数的稳健方法
A robust way to fit an exponential function in loglog axis
我有以下脚本来拟合 loglog 轴上的指数函数:
start_exp = 21 # Start of fit
end_exp = 40 # end of fit
# fix the parameters of exponential Y = exponent1 *a*exp(exponent2 *b*t)
exponent1 = 3.
exponent2 = 2.
### The original data to perform the fit ###
bin_centers = np.array([9.31939514e-01, 1.71773809e+00, 2.58227857e+00, 3.16611120e+00,
3.88194374e+00, 4.75962032e+00, 5.83573259e+00, 7.15514527e+00,
8.77286667e+00, 1.07563420e+01, 1.31882653e+01, 1.61700271e+01,
1.98259415e+01, 2.43084291e+01, 2.98043714e+01, 3.65429025e+01,
4.48049619e+01, 5.49350072e+01, 6.73553750e+01, 8.25838892e+01,
1.01255449e+02, 1.24148500e+02, 1.52217488e+02, 1.86632650e+02,
2.28828807e+02, 2.80565179e+02, 3.43998732e+02, 4.21774108e+02,
5.17133876e+02, 6.34053729e+02, 7.77408231e+02, 9.53174043e+02,
1.16867911e+03])
norm_counts = np.array([7.47683145e-02, 2.44802278e-02, 6.40790461e-02, 4.24335863e-02,
2.91339699e-02, 2.34427016e-02, 1.63884469e-02, 2.19590994e-02,
1.42326906e-02, 1.64066907e-02, 1.03597068e-02, 1.03504798e-02,
9.22668847e-03, 6.22943476e-03, 6.37955519e-03, 5.30701726e-03,
3.61688252e-03, 3.48879003e-03, 2.46230484e-03, 1.91634352e-03,
1.45802119e-03, 9.72116428e-04, 8.17790259e-04, 4.57538385e-04,
3.66533958e-04, 2.17783386e-04, 1.36803586e-04, 7.28849304e-05,
4.84365929e-05, 2.93293649e-05, 2.24564621e-05, 1.19448771e-05,
4.87111765e-06])
def expo(x, a, b) :
return a*np.exp(-b*x)
x_exp = bin_centers[start_exp:end_exp]
y_exp = norm_counts[start_exp:end_exp]
a_exp,b_exp = sc.optimize.curve_fit(lambda t,a,b: exponent1*a*np.exp(-b*t*(exponent2)), x_exp, y_exp, p0=(0.0005, 0.0058))
expon = (expo(bin_centers[start_exp:end_exp],a_exp[0],a_exp[1]))
plt.plot(bin_centers[start_exp:end_exp], expon,'-.',color='black',linewidth='0.8',label='${\propto} $ $e^{%.4f}$' %(-a_exp[1] ))#, 'r-',label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
plt.legend()
plt.plot(bin_centers, norm_counts)
plt.yscale('log')
plt.xscale('log')
我得到的效果还不错。
然而,我每次都必须非常努力地找到合适的参数。而且我必须做到这一点适合许多曲线。
有没有办法使这个过程自动化?一个更强大的算法,可以让我估计最合适的?
为了阐明图表上的符号,请定义下一个新变量:
当 Y 被绘制为 X^2 的函数时,可以看到完全线性化。
因此正确的线性模型可能是:Y=a+b.X^2
最小均方拟合很简单:
作为结论,您不应该使用该软件来拟合数据 (x,y),而是用来拟合转换后的数据 (X=log(x), Y=log(y))。
当然,除了以 10 为底的对数,您也可以使用相同的自然对数。
我有以下脚本来拟合 loglog 轴上的指数函数:
start_exp = 21 # Start of fit
end_exp = 40 # end of fit
# fix the parameters of exponential Y = exponent1 *a*exp(exponent2 *b*t)
exponent1 = 3.
exponent2 = 2.
### The original data to perform the fit ###
bin_centers = np.array([9.31939514e-01, 1.71773809e+00, 2.58227857e+00, 3.16611120e+00,
3.88194374e+00, 4.75962032e+00, 5.83573259e+00, 7.15514527e+00,
8.77286667e+00, 1.07563420e+01, 1.31882653e+01, 1.61700271e+01,
1.98259415e+01, 2.43084291e+01, 2.98043714e+01, 3.65429025e+01,
4.48049619e+01, 5.49350072e+01, 6.73553750e+01, 8.25838892e+01,
1.01255449e+02, 1.24148500e+02, 1.52217488e+02, 1.86632650e+02,
2.28828807e+02, 2.80565179e+02, 3.43998732e+02, 4.21774108e+02,
5.17133876e+02, 6.34053729e+02, 7.77408231e+02, 9.53174043e+02,
1.16867911e+03])
norm_counts = np.array([7.47683145e-02, 2.44802278e-02, 6.40790461e-02, 4.24335863e-02,
2.91339699e-02, 2.34427016e-02, 1.63884469e-02, 2.19590994e-02,
1.42326906e-02, 1.64066907e-02, 1.03597068e-02, 1.03504798e-02,
9.22668847e-03, 6.22943476e-03, 6.37955519e-03, 5.30701726e-03,
3.61688252e-03, 3.48879003e-03, 2.46230484e-03, 1.91634352e-03,
1.45802119e-03, 9.72116428e-04, 8.17790259e-04, 4.57538385e-04,
3.66533958e-04, 2.17783386e-04, 1.36803586e-04, 7.28849304e-05,
4.84365929e-05, 2.93293649e-05, 2.24564621e-05, 1.19448771e-05,
4.87111765e-06])
def expo(x, a, b) :
return a*np.exp(-b*x)
x_exp = bin_centers[start_exp:end_exp]
y_exp = norm_counts[start_exp:end_exp]
a_exp,b_exp = sc.optimize.curve_fit(lambda t,a,b: exponent1*a*np.exp(-b*t*(exponent2)), x_exp, y_exp, p0=(0.0005, 0.0058))
expon = (expo(bin_centers[start_exp:end_exp],a_exp[0],a_exp[1]))
plt.plot(bin_centers[start_exp:end_exp], expon,'-.',color='black',linewidth='0.8',label='${\propto} $ $e^{%.4f}$' %(-a_exp[1] ))#, 'r-',label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
plt.legend()
plt.plot(bin_centers, norm_counts)
plt.yscale('log')
plt.xscale('log')
我得到的效果还不错。
然而,我每次都必须非常努力地找到合适的参数。而且我必须做到这一点适合许多曲线。
有没有办法使这个过程自动化?一个更强大的算法,可以让我估计最合适的?
为了阐明图表上的符号,请定义下一个新变量:
当 Y 被绘制为 X^2 的函数时,可以看到完全线性化。
因此正确的线性模型可能是:Y=a+b.X^2
最小均方拟合很简单:
作为结论,您不应该使用该软件来拟合数据 (x,y),而是用来拟合转换后的数据 (X=log(x), Y=log(y))。
当然,除了以 10 为底的对数,您也可以使用相同的自然对数。