我尝试使用scipy中的curve_fit函数,用高斯函数和洛伦兹函数拟合一条曲线。
def gaussian(x, a, x0, sig):
return a * np.exp(-1/2 * (x - x0)**2 / sig**2)
def lorentzian(x, a, b, c):
return a*c**2/((x-b)**2+c**2)
def decompose(x, z, n, b, *par):
hb_n = gaussian(x, par[0], 4861.3*(1+z), n)
hb_b = lorentzian(x, par[1], 4861.3*(1+z), b)
return hb_b + hb_n
而当我设置p0参数时,我可以得到一个合理的结果,它很好地拟合了曲线。
guess = [0.0001, 2, 10, 3e-16, 3e-16]
p, c = curve_fit(decompose, wave, residual, guess)
fitting parametersthe fitting model and data figure when I set the p0 parameter显示器
但是如果我同时设置p0和bounds参数,curve_fit函数会将初始猜测作为最终拟合结果,这与数据有很大的偏差。
guess = [0.0001, 2, 10, 3e-16, 3e-16]
p, c = curve_fit(decompose, wave, residual, guess, bounds=([-0.001, 0, 0, 0, 0], [0.001, 10, 100, 1e-15, 1e-15]))
fitting parametersthe fitting model and data figure when I set the p0 and bounds parameters simultaneously打印机
“我尝试了很多种不同的参数边界组合,但是拟合的结果总是返回初始的猜测值。我已经在这个问题上困了很长时间了。如果有人能给予我一些解决这个问题的建议,我将非常感激。”
1条答案
按热度按时间aij0ehis1#
这是由于优化算法及其参数的组合而发生的。
从official documentation:
方法('lm','trf','dogbox'},可选
用于优化的方法。有关详细信息,请参阅least_squares。对于无约束的问题,默认值为'lm';如果提供了界限,则默认值为'trf'。当观察值的数量小于变量的数量时,方法'lm'将不起作用,在这种情况下,请使用'trf'或'dogbox'。
所以当你添加边界约束时
curve_fit
将使用不同的优化算法(信赖域而不是Levenberg-Marquardt)。要调试该问题,您可以尝试将
full_output=True
设置为注解中提到的Warren Weckesser。在边界拟合的情况下,您将看到类似于以下内容的内容:
所以优化在第一次迭代后就停止了,这就是为什么找到了与最初猜测相似的参数。
要解决此问题,您可以指定较低的
gtol
参数。您可以在此处找到可用参数的完整列表:https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.least_squares.html#scipy.optimize.least_squares示例:x1c 0d1x
编码: