Python:数据拟合 scipy.optimize.curve_fit 且 sigma = 0

Python: Data fitting with scipy.optimize.curve_fit with sigma = 0

我正在尝试用 scipy.optimize.curve_fit 拟合一条曲线,到目前为止效果很好,除非我的 sigma 数组中的值为零。我知道该算法无法处理这个问题,因为在这种情况下我除以零。来自 scipy 文档:

sigma : None or M-length sequence, optional 如果不是 None,ydata 数组中的不确定性。这些在最小二乘问题中用作权重,即最小化 np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 ) 如果 None,假设不确定性为是 1.

我的代码如下所示:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

x = [0.125, 0.375, 0.625, 0.875, 1.125, 1.375, 1.625, 1.875, 2.125, 2.375, 2.625, 2.875, 3.125, 3.375, 3.625, 3.875, 4.125, 4.375]
y_para = [0, 0, 0.0414, 0.2164, 0.2616, 0.4254, 0.5698, 0.5921, 0.6286, 0.6452, 0.5879, 0.6032, 0.6667, 0.6325, 0.7629, 0.7164, 0.7091, 0.7887]
err = [0, 0, 0.0391, 0.0331, 0.0943, 0.0631, 0.1219, 0.1063, 0.0912, 0.0516, 0.0365, 0.0327, 0.0227, 0.103, 0.1344, 0.0697, 0.0114, 0.0465]   

def logistic_growth(x, A1, A2, x_0, p):
    return A2 + (A1-A2)/(1+(x/x_0)**p)

x_plot = np.linspace(0, 4.5, 100)

bounds_para = ([0.,0,-np.inf,-np.inf],[0.0000000001, 1,np.inf,np.inf])

paras, paras_cov = curve_fit(logistic_growth, x, y_para, bounds = bounds_para, sigma = err, absolute_sigma=True)
para_curve = logistic_growth(x_plot, *paras)

plt.figure()
plt.errorbar(x,y_para, err, color = 'b', fmt = 'o', label = "Data")
plt.plot(x_plot, para_curve, color = 'b', label = "Fit")    
plt.show()

在 curve_fit 中不使用 sigma 选项执行此操作工作正常,但包括它会引发:

ValueError: Residuals are not finite in the initial point.

,由错误数组中的零产生。 有谁知道解决这个问题的方法吗?

为什么不直接删除变量?如果方差为零,则无法对您的分析做出任何有意义的贡献。

这就是 scipy 文档关于 curve_fit sigma parameter: 'These are used as weights in the least-squares problem ...' 那么,在我看来,它们应该与错误相反。这是我的建议。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

x = [0.125, 0.375, 0.625, 0.875, 1.125, 1.375, 1.625, 1.875, 2.125, 2.375, 2.625, 2.875, 3.125, 3.375, 3.625, 3.875, 4.125, 4.375]
y_para = [0, 0, 0.0414, 0.2164, 0.2616, 0.4254, 0.5698, 0.5921, 0.6286, 0.6452, 0.5879, 0.6032, 0.6667, 0.6325, 0.7629, 0.7164, 0.7091, 0.7887]
err = [0, 0, 0.0391, 0.0331, 0.0943, 0.0631, 0.1219, 0.1063, 0.0912, 0.0516, 0.0365, 0.0327, 0.0227, 0.103, 0.1344, 0.0697, 0.0114, 0.0465]   

weights = [1/max(_,0.001) for _ in err]
print (weights)

def logistic_growth(x, A1, A2, x_0, p):
    return A2 + (A1-A2)/(1+(x/x_0)**p)

x_plot = np.linspace(0, 4.5, 100)

bounds_para = ([0.,0,-np.inf,-np.inf],[0.0000000001, 1,np.inf,np.inf])

paras, paras_cov = curve_fit(logistic_growth, x, y_para, bounds = bounds_para, 
    absolute_sigma=True,
    sigma = weights)
para_curve = logistic_growth(x_plot, *paras)

plt.figure()
plt.errorbar(x,y_para, err, color = 'b', fmt = 'o', label = "Data")
plt.plot(x_plot, para_curve, color = 'b', label = "Fit")    
plt.show()

这导致了下图,其中那些初始数据点非常靠近拟合线。