Scipy优化使用SLSQP最小化初始猜测

时间:2017-09-18 11:49:12

标签: python optimization scipy

出于某种目的,在我的部分代码中,我想猜测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的{​​{1}}中。我认为那个猜测的参数必须符合我的约束。但在这里,初步猜测optimize.minimize符合我的同意。任何人都可以解释一下,问题在哪里?

1 个答案:

答案 0 :(得分:3)

是的,您的初始点满足约束条件。但是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)]也可以,但只是勉强(用6或8代替7会产生另一种错误,“linesearch的正方向导数”)。

所以摘要是:优化问题缩放不良,使搜索变得困难;并且错误信息不是很清楚实际出错的地方。

除了改变初始点之外,你可以尝试提供目标函数和约束的雅可比行列式(两者都很重要,因为该方法适用于拉格朗日算法)。