我正在测试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
2条答案
按热度按时间ctzwtxfj1#
我不知道为什么你会期待一个不同的协方差矩阵。文档说:
如果解的雅可比矩阵不是满秩的,则“lm”方法返回一个填充了np的矩阵。inf
据我所知,雅可比矩阵是在优化过程中估计的,根据你使用的初始化,上面的情况可能会发生。注意,
popt
的结果仍然收敛!bqf10yzr2#
协方差矩阵实际上只有在每个变量都被优化时才有用(通常只能计算),这通常意味着变量被从其初始值移开,并且以某种方式可以确定拟合质量(通常为卡方)与变量值变化的依赖性。
如果最初的猜测是错误的,可能就找不到答案--有些变量可能不会从它们的初始值移动。我想这就是你正在发生的事情。
初始值为“0”特别麻烦,因为拟合实际上不知道“多为零”。这是“星等小于1 e-16”还是“星等小于1”?即使使用初始值
[4, 0.01, 0.01]
也会得到好的解。另一个潜在的问题是,你的“数据”是由模型函数和值精确给出的。在“正确的解决方案”下,残差将真的非常非常接近于零,并将导数的雅可比矩阵转换为(关于变量的错配)与协方差的关系在数值上是不稳定的。这在真实的数据中是非常不可能的,但是您可能希望向建模的数据中添加少量的噪声。