Python: 用scipy differential_evolution拟合参数,如何强制一个参数小于另一个?

Python: fitting parameters with scipy differential_evolution, how to enforce one parameter be smaller than another one?

例如

from scipy.optimize import differential_evolution
import numpy as np

def func(parameters, *data):

    a,b,c = parameters
    x,y = data

    result = (a*x**2 + b*x+ c - y)**2

    return sum(result)

bounds = [(0.5, 1), (0.5, 1), (0.5, 1)]
x = np.array([1,2,3,4,5])
y = np.array([1,4,9,16,25])
args = (x,y)

parameters = differential_evolution(func, bounds, args=args,seed=np.random.seed(7))
print(parameters.x)

然后 a、b、c = [0.85699693 0.5 0.5]

现在,如果有人想强制要求c必须大于a,即c>a作为参数拟合结果。我怎样才能做到这一点?

我自己的解决方案是对定义的函数使用条件return,因此将return sum(result)替换为return sum(result) if c>a else np.Inf。这给了我一组新的 a, b, c = [0.83454878 0.50031474 0.83487768]

from scipy.optimize import differential_evolution
import numpy as np

def func(parameters, *data):

a,b,c = parameters
x,y = data

result = (a*x**2 + b*x+ c - y)**2

return sum(result) if c>a else np.Inf

bounds = [(0.5, 1), (0.5, 1), (0.5, 1)]
x = np.array([1,2,3,4,5])
y = np.array([1,4,9,16,25])
args = (x,y)

parameters = differential_evolution(func, bounds, args=args,seed=np.random.seed(7))
print(parameters.x)

[0.83454878 0.50031474 0.83487768]

一个更好的方法是使用约束。在本例中为 LinearConstraint。您要使用的约束是 c - a > 0。这个解决方案类似于 Warren 的建议。

from scipy.optimize import differential_evolution
from scipy.optimize import LinearConstraint
import numpy as np

def func(parameters, *data):

    a,b,c = parameters
    x,y = data

    result = (a*x**2 + b*x+ c - y)**2

    return sum(result)

bounds = [(0.5, 1), (0.5, 1), (0.5, 1)]
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 4, 9, 16, 25])
args = (x, y)

lc = LinearConstraint(np.array([-1, 0, 1]), [0], [np.inf])
parameters = differential_evolution(func, bounds, args=args, seed=np.random.seed(7), constraints=(lc,))
print(parameters.x, parameters.x[2] > parameters.x[0])

[0.83546612 0.50000016 0.83546635] True