在 scipy.optimize.curve_fit 中添加约束条件?

11

我可以选择为sio.curve_fit添加边界。有没有一种扩展这个边界特性的方法,涉及到参数的函数?换句话说,假设我有一个带有两个或更多未知常数的任意函数。然后也让我们假设我知道所有这些常数的总和小于10。我是否可以实现这个最后的限制?

import numpy as np
import scipy.optimize as sio
def f(x, a, b, c):
    return a*x**2 + b*x + c

x = np.linspace(0, 100, 101)
y = 2*x**2 + 3*x + 4

popt, pcov = sio.curve_fit(f, x, y, \
     bounds = [(0, 0, 0), (10 - b - c, 10 - a - c, 10 - a - b)]) # a + b + c < 10

现在,这显然会出错,但我认为它有助于表达观点。我是否可以将涉及参数的约束函数并入到曲线拟合中呢?

谢谢!

2个回答

8

使用lmfit,您需要定义4个参数(abcdelta)。ab可以自由变化。delta允许变化,但最大值为10表示不等式。c将受到限制,其值应为delta-a-b(因此仍然有3个变量:c会变化,但不独立于其他变量)。如果需要,还可以对abc的值进行限制。没有测试的情况下,您的代码将大致如下:

import numpy as np
from lmfit import Model, Parameters

def f(x, a, b, c):
    return a*x**2 + b*x + c

x = np.linspace(0, 100.0, 101)
y = 2*x**2 + 3*x + 4.0

fmodel = Model(f)
params = Parameters()
params.add('a', value=1, vary=True)
params.add('b', value=4, vary=True)
params.add('delta', value=5, vary=True, max=10)
params.add('c', expr = 'delta - a - b')

result = fmodel.fit(y, params, x=x)
print(result.fit_report())

请注意,如果实际上约束表达式或边界规定了参数的值,那么可能无法估计不确定性。

1

curve_fit和least_squares只接受盒式约束。在scipy.optimize中,SLSQP可以处理更复杂的约束。 对于曲线拟合,您可以查看lmfit包。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接