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
例如
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