我有一些来自实验室的数据,我正在用它来适应这个功能
F(S,参数)=AMP*(S/SP)/(1+S/SP+1.041)+BG(不知如何打字设置)
我将absolute_sigma=True
设置为curve_fit
,以获得参数(SP、AMP、BG)的绝对不确定度,但np.sqrt(np.diag(pcov))
的计算误差似乎不合理.请看下面的图表.蓝点是数据.红线是f(s, *popt)
.绿线将最优sp值替换为从np.sqrt(np.diag(pcov))
计算得出的sp-it误差.橙色的线是SP+相同的值.
我预计+/-线将更接近红线.
下面是一个最小的例子:
# Function for fitting
def scattering_rate(s, sp, amp, bg):
return amp * (s/sp) / (1 + s/sp + (-20/19.6)**2) + bg
# data
s = np.array([0.6, 1.2, 2.3, 4.3, 8.1, 15.2, 28.5, 53.4])
y = np.array([8.6, 8.5, 8.9, 9.5, 10.6, 12.6, 15.5, 18.3])
# Fit data to saturated scattering rate
popt, pcov = curve_fit(scattering_rate, s, y, absolute_sigma=True)
print('Fit parameters', popt)
print('Fit uncertainties', np.sqrt(np.diag(pcov)))
# Construct fit from optimized parameters
fit_s = np.linspace(np.min(s), np.max(s), 100)
fit = scattering_rate(fit_s, *popt)
# Consider one error difference in sp value
fit_plus_err = saturation_power(fit_s, popt[0] + np.sqrt(np.diag(pcov))[0], popt[1], popt[2])
fit_minus_err = saturation_power(fit_s, popt[0] - np.sqrt(np.diag(pcov))[0], popt[1], popt[2])
# Plot
plt.plot(s, y, '-o', markeredgecolor='k', label='data')
plt.plot(fit_s, fit_plus_err, label='sp + err')
plt.plot(fit_s, fit_minus_err, label='sp - err')
plt.plot(fit_s, fit, '-r', label='opt sp')
plt.xlabel('s')
plt.ylabel('y')
plt.legend()
plt.grid()
plt.show()
编辑
Following @jlandercy's answer, we need the error bars of the original data which are y_err = array([0.242, 0.231, 0.282, 0.31 , 0.373])
. Including that in curve_fit
's sigma
argument, the results look much better though still a bit distance