我正在测试scipy.optimize
函数curve_fit()
。我正在测试一个二次函数,我已经为这个问题手动分配了x和y数据。我确实得到了我的参数值的预期答案,基本上是我输入的每一个猜测。但是,我注意到,对于第一个参数不接近于0的猜测(特别是在1之后),我得到了一个充满无穷大的协方差矩阵。我不知道为什么这么简单的测试失败了。
# python version: 3.9.7
# using a venv
# numpy version: 1.23.2
# scipy version: 1.9.0
import numpy as np
from scipy.optimize import curve_fit
# data taken from a quadratic function of: y = 3*x**2 + 2
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=np.float64)
y = np.array([2, 5, 14, 29, 50, 77, 110, 149, 194, 245, 302], dtype=np.float64)
# quadratic function
def func(x, a, b, c):
return a * x**2 + b * x + c
# test to reproduce success case - notice that we have success when changing the first value upto a value of 1.0
success = [0, 0, 0]
# test to reproduce failure case
failure = [4, 0, 0]
popt, pcov = curve_fit(func, x, y, p0=failure) # change p0 to success or failure
print(popt) # expected answer is [3, 0, 2]
print(pcov) # covariance matrix
发布于 2022-09-03 14:02:28
我不知道你为什么要期待一个不同的协方差矩阵。文件上说:
如果解处的雅可比矩阵没有满秩,那么‘lm’方法返回一个填充了np.inf的矩阵
据我所知,雅可比矩阵是在优化过程中估计出来的,取决于您使用的是哪种初始化,可能会发生上述情况。请注意,popt
的结果仍然收敛!
发布于 2022-10-04 20:27:51
当每个变量被优化时,协方差矩阵才是真正有用的(而且通常只能计算)。这通常意味着变量从它的初始值移开,并且以某种方式,这样就可以确定不改变这个变量的值对拟合质量(通常是卡方)的依赖。
结果还表明,如果初始猜测是错误的,则可能找不到解决方案--有些变量可能实际上不会从它们的初始值中移出。我想这就是你现在所发生的事。
"0“的初始值特别麻烦,因为fit不知道”如何为零“。是“小于1e-16级”还是“小于1级”?即使使用[4, 0.01, 0.01]
的初始值,也会得到一个很好的解决方案。
另一个潜在的问题是,您的“数据”正是由模型函数和值提供的。在“正确的解”中,残差将非常接近于零,并且将导数的Jacobian矩阵(关于变量的失配)转换为协方差在数值上是不稳定的。对于实际数据来说,这是非常不可能的,但是您可能希望在建模的数据中添加少量的噪声。
https://stackoverflow.com/questions/73576000
复制