出于某种目的,在我的代码的一部分中,我想猜测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/

10-12 14:31