【问题标题】:Python: Data fitting with scipy.optimize.curve_fit with sigma = 0Python:数据拟合与 scipy.optimize.curve_fit 与 sigma = 0
【发布时间】:2017-05-31 14:58:55
【问题描述】:

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

sigma :无或 M 长度序列,可选 如果不是 None,则 ydata 数组中的不确定性。这些被用作最小二乘问题中的权重,即最小化 np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 ) 如果没有,则假定不确定性为 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-option 的情况下执行此操作可以正常工作,但包含它会引发:

ValueError: Residuals are not finite in the initial point.

,由 err-array 中的零导致。 有谁知道解决这个问题的方法吗?

【问题讨论】:

    标签: python-2.7 optimization scipy curve-fitting nonlinear-optimization


    【解决方案1】:

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

    【讨论】:

    • 这个效果很好。也许这甚至是正确解决这个问题的唯一方法。但实际上我也想考虑这些数据点,因为缺少的误差条是该数据点的值在多次复制中没有变化的结果。这也可能发生在非零值上,但不太可能发生。在这种情况下为错误设置一个非常低的值也不起作用,因为它完全弄乱了曲线。我仍然会接受你的建议,因为它给出了很好的结果,在统计上似乎正确并解决了问题。所以,谢谢!
    【解决方案2】:

    这是 scipy doc所说的关于 curve_fit stront> sigma 参数:'这些用作最小二乘问题的权重。 ..“那么,在我看来,他们应该反向错误。这是我建议的。

    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()
    

    这导致以下绘图,其中使得这些初始数据点非常靠近安装线。

    【讨论】:

    • 我认为错误是最小化最小二乘问题的误差。从Scipy Doc:“最小二乘问题中的权重,即最小化NP.sum(((f(xdata,* popt) - ydata)/ sigma)** 2)”,这意味着更大的错误/ sigma值将导致更大的错误/ sigma值各个数据点的重量较低。我实际上尝试了你的建议方法,并知道它对这个特殊情况产生了良好的结果,但我认为这不是这种问题的正确方法。 span>
    • 我想我的问题是,如果 err i>的零值是因为一些数据点被认为是表示已经精确确定的那些点或者它们已经不精确地确定决定?逐次更高的 err i>的值暗示更高或更精度? span>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多