scipy.optimize.curve_fit无法估计协方差

时间:2017-06-19 13:25:22

标签: python python-3.x scipy curve-fitting data-fitting

我想将数据拟合到Logistic(Sigmoid)函数,并获得无限的协方差。我有2个参数,假设我有5个数据点。我的数据位于变量xdataydata中。这是一个代码示例,它生成完全相同的警告:

from scipy.optimize import curve_fit

def sigmoid(x, x0, k):
     y = 1 / (1 + np.exp(-k*(x-x0)))
     return y

xdata = np.array([  5.,  75.,  88.,  95.,  96.])
ydata = np.array([ 0.04761905, 0.02380952, 0, 0.04761905, 0])


popt, pcov = curve_fit(sigmoid, xdata, ydata)

pcov

array([[ inf,  inf],
       [ inf,  inf]])

以及以下警告:

  

OptimizeWarning:无法估计参数的协方差     类别= OptimizeWarning)

我看到一个导致同样问题here的相关问题,但问题是数据点和参数的数量是相同的,在我的情况下不是这样。

编辑:请注意,上面我提到过我有数据点,但这只是用于示例。实际上有60.这是一个原始数据的图,看看确实一个sigmoid函数似乎合适:enter image description here

2 个答案:

答案 0 :(得分:2)

Given the data you provided, I'd say that the warning you get with the resulting covariance matrix is an indication that the sigmoid function is very bad at doing the job of fitting such data.

Moreover, with 5 points is hard to make trends... particularly if you have the first point at 5 and then a jump all the way up to 75. In my opinion, that data looks just like noise. Particularly because you have to points with a y value of 0.

For example, if you try to fit a line

def line(x,m,n):
  return x*m+n

you'll get two points that seem plausible (first and second) and a well-defined covariance matrix (no warnings).

Update

You can also plot the resulting sigmoid function on top of your data to see if the resulting fit is a good one. I suspect that it won't be and thus you get such an ill-defined covariance matrix.

One possible situation is that the fitting cannot find the proper parameters, thus getting lost. I would recommend you to give the fitting procedure some starting values for the parameters that nudge it towards the correct solution. Perhaps x_0=800 and k=1.

答案 1 :(得分:0)

使用scipy.optimize.curve_fit()需要提防的另一个问题:(静静地)关于x和y数据的dtype十分详细。

尤其是,没有充分的理由使curve_fit在float32上失败但在float64数据上成功。它甚至应该处理int数据。但是,如果它对您来说神秘,请尝试将数据强制为float64。

请参阅 Why does scipy.optimize.curve_fit not produce a line of best fit for my points?