出于某种目的,在我的代码的一部分中,我想猜测5次多项式,它最适合我的数据,并且在某些方面不减。
示例代码是:
import numpy as np
import scipy.optimize as optimize
def make_const(points):
constr = []
for point in points:
c = {'type' : 'ineq', 'fun' : der, 'args' : (point,)}
constr.append(c)
return constr
def der(args_pol, bod):
a, b, c, d, e, f = args_pol
return (5*a*bod**4 + 4*b*bod**3 + 3*c*bod**2 + 2*d*bod + e)
def squares(args_pol, x, y):
a, b, c, d, e, f = args_pol
return ((y-(a*x**5 + b*x**4 + c*x**3 + d*x**2 + e*x + f))**2).sum()
def ecdf(arr):
arr = np.array(arr)
F = [len(arr[arr<=t]) / len(arr) for t in arr]
return np.array(F)
pH = np.array([8,8,8,7,7,7,7,7,7,7,7,6,3,2,2,2,1])
pH = np.sort(pH)
e = ecdf(pH)
ppoints = [ 1., 2.75, 4.5, 6.25, 8. ]
constraints1 = make_const(ppoints)
p1 = optimize.minimize(squares, [1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
method = 'SLSQP', args = (pH, e), constraints = constraints1)
p2 = optimize.minimize(squares, [-1.0, -1.0, -1.0, -1.0, -1.0, -1.0],
method = 'SLSQP', args = (pH, e), constraints = constraints1)
在这里
p1
无法优化,p2
成功终止。另外,如果我没有约束,那么如果ppoints = []
,则p1
成功地白蚁,而p2
失败。如果优化失败,则消息始终为:'Inequality constraints incompatible'
问题显然出在
initial guess
中的optimize.minimize
中。我认为该猜测的参数必须符合我的约束。但是在这里,最初的猜测[1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
遇到了我的困扰。谁能解释一下,问题出在哪里? 最佳答案
是的,您的起点满足约束条件。但是SLSQP可以处理线性化约束,并且正在寻找与所有线性化(described here)兼容的搜索方向。那些可能最终不兼容,或者兼容性很差,因为只有很小范围的方向符合条件,而搜索找不到它们。
起点[1,1,1,1,1,1]不好。考虑在x = 8时,前导系数1对多项式的贡献为8**5
,由于它在目标函数中平方,所以得到的值约为8**10
。这使低阶系数的贡献相形见,,低阶系数对于满足在接近0的点处的约束仍然很重要。因此,当起始点为全1时,该算法将面临严重的缩放问题。
以np.zeros((6, ))
为起点是一个更好的主意。搜索从那里成功。将初始点缩放为[7**(d-5) for d in range(6)]
也可以,但是几乎没有用(将7乘6或8替换会产生另一种错误,“用于线搜索的正方向导数”)。
因此,总结是:优化问题的伸缩性较差,使得搜索困难;并且错误消息不是很清楚有关实际出了什么问题。
除了更改初始点,您还可以尝试提供目标函数和约束的雅可比行列式(两者都很重要,因为该方法适用于拉格朗日法)。
关于python - Scipy优化使用SLSQP最小化初始猜测,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46278537/