scipy.optimize.curve_fit 未能估计协方差
scipy.optimize.curve_fit failing to estimate the covariance
我想将数据拟合到 Logistic (Sigmoid) 函数并且得到无限协方差。我有 2 个参数,假设我有 5 个数据点。我的数据在变量 xdata
和 ydata
中。这是生成完全相同警告的代码示例:
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: Covariance of the parameters could not be estimated
category=OptimizeWarning)
我看到了一个导致同样问题的相关问题,但问题是数据点和参数的数量是相同的,这在我的情况下是不正确的。
编辑:请注意,上面我已经提到我有数据点,但这只是为了举例。实际上有 60 个。这是原始数据的图表,可以看出 S 形函数似乎确实合适:
鉴于您提供的数据,我会说您得到的协方差矩阵警告表明 s 型函数在拟合此类数据方面非常糟糕。
此外,5 分很难形成趋势...特别是如果您的第一个点是 5,然后一直跳到 75。在我看来,这些数据看起来就像噪音。特别是因为您必须指向 y 值为 0 的点。
例如,如果您尝试拟合一条线
def line(x,m,n):
return x*m+n
你会得到两个看似合理的点(第一个和第二个)和一个定义明确的协方差矩阵(没有警告)。
更新
您还可以在数据之上绘制生成的 sigmoid 函数,以查看生成的拟合是否合适。我怀疑它不会,因此你会得到一个定义不明确的协方差矩阵。
一种可能的情况是拟合找不到合适的参数,从而迷路了。我建议您为拟合过程提供一些参数的起始值,以将其推向正确的解决方案。也许 x_0=800
和 k=1
.
使用 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?
我想将数据拟合到 Logistic (Sigmoid) 函数并且得到无限协方差。我有 2 个参数,假设我有 5 个数据点。我的数据在变量 xdata
和 ydata
中。这是生成完全相同警告的代码示例:
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: Covariance of the parameters could not be estimated category=OptimizeWarning)
我看到了一个导致同样问题的相关问题
编辑:请注意,上面我已经提到我有数据点,但这只是为了举例。实际上有 60 个。这是原始数据的图表,可以看出 S 形函数似乎确实合适:
鉴于您提供的数据,我会说您得到的协方差矩阵警告表明 s 型函数在拟合此类数据方面非常糟糕。
此外,5 分很难形成趋势...特别是如果您的第一个点是 5,然后一直跳到 75。在我看来,这些数据看起来就像噪音。特别是因为您必须指向 y 值为 0 的点。
例如,如果您尝试拟合一条线
def line(x,m,n):
return x*m+n
你会得到两个看似合理的点(第一个和第二个)和一个定义明确的协方差矩阵(没有警告)。
更新
您还可以在数据之上绘制生成的 sigmoid 函数,以查看生成的拟合是否合适。我怀疑它不会,因此你会得到一个定义不明确的协方差矩阵。
一种可能的情况是拟合找不到合适的参数,从而迷路了。我建议您为拟合过程提供一些参数的起始值,以将其推向正确的解决方案。也许 x_0=800
和 k=1
.
使用 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?