基于SLSQP的Scipy优化最小化初始猜测

2024-04-25 05:04:46 发布

您现在位置:Python中文网/ 问答频道 /正文

出于某种目的,在我的代码中,我想猜测五次多项式,它最适合我的数据,并且在某些点上是不减分的。在

示例代码为:

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白蚁成功,而{}失败。如果优化失败,消息始终是:

^{pr2}$

问题显然在initial guess中的optimize.minimize。我认为这个猜测的参数必须符合我的限制。但在这里,最初的猜测[1.0, 1.0, 1.0, 1.0, 1.0, 1.0]遇到了我的缺点。谁能解释一下,问题在哪里?在


Tags: returndefnpargsarrayphoptimizearr
1条回答
网友
1楼 · 发布于 2024-04-25 05:04:46

是的,你的初始点满足约束条件。但是SLSQP使用线性化的约束,并且正在寻找一个与所有线性化(described here)兼容的搜索方向。它们可能最终要么不兼容,要么兼容性差,因为只有很小范围的方向符合条件,而搜索无法找到它们。在

起点[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的正方向导数”)。在

所以总结是:优化问题的伸缩性很差,使得搜索变得困难;错误信息对于实际出错的地方并不是很明确。在

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

相关问题 更多 >