python实例 优化目标函数_python scipy optimize.minimize用法及代码示例

最小化一个或多个变量的标量函数。

参数:

fun:callable目标函数要最小化。

fun(x, *args) -> float

其中x是具有(n,)形状的一维数组,而args是完全指定函数所需的固定参数的元组。

x0:ndarray, shape (n,)初步猜测。大小为(n,)的实数元素的数组,其中‘n’是自变量的数量。

args:tuple, 可选参数额外的参数传递给目标函数及其派生函数(fun,jac和hess函数)。

method:str 或 callable, 可选参数求解器类型。应该是其中之一

‘Nelder-Mead’ (see here)

‘Newton-CG’ (see here)

‘L-BFGS-B’ (see here)

‘trust-constr’(see here)

‘trust-ncg’ (see here)

‘trust-exact’ (see here)

‘trust-krylov’ (see here)

custom - a callable object (added in version 0.14.0),

see below for description.

如果未给出,则选择为以下之一BFGS,L-BFGS-B,SLSQP,取决于问题是否具有约束或界限。

jac:{callable, ‘2-point’, ‘3-point’, ‘cs’, bool}, 可选参数梯度矢量的计算方法。仅适用于CG,BFGS,Newton-CG,L-BFGS-B,TNC,SLSQP,dogleg,trust-ncg,trust-krylov,trust-exact和trust-constr。如果它是可调用的,则应该是一个返回梯度向量的函数:

jac(x, *args) -> array_like, shape (n,)

其中x是具有形状(n,)的数组,而args是具有固定参数的元组。或者,关键字{“ 2点”,“ 3点”,‘cs’}选择用于梯度的数字估计的有限差分方案。选项“ 3点”和‘cs’仅对“ trust-constr”可用。如果jac是布尔值且为True,则假定fun与目标函数一起返回梯度。如果为False,则将使用“两点”有限差分估算来估算梯度。

hess:{callable, ‘2-point’, ‘3-point’, ‘cs’, HessianUpdateStrategy}, 可选参数计算黑森州矩阵的方法。仅适用于Newton-CG,狗腿,trust-ncg,trust-krylov,trust-exact和trust-constr。如果可调用,则应返回黑森州矩阵:

hess(x, *args) -> {LinearOperator, spmatrix, array}, (n, n)

其中x是(n,)ndarray,而args是具有固定参数的元组。只有“ trust-constr”方法才允许使用LinearOperator和稀疏矩阵返回。另外,关键字{“ 2点”,“ 3点”,‘cs’}选择用于数字估计的有限差分方案。或者,对象实现HessianUpdateStrategy界面可用于近似Hessian。实现此接口的可用quasi-Newton方法是:

每当通过finite-differences估算坡度时,就无法使用选项{'2-point','3-point',‘cs’}估算Hessian,而需要使用quasi-Newton策略之一估算。 Finite-difference选项{“ 2点”,“ 3点”,‘cs’}和HessianUpdateStrategy仅适用于“ trust-constr”方法。

hessp:callable, 可选参数目标函数的Hessian乘以任意向量p。仅适用于Newton-CG,trust-ncg,trust-krylov,trust-constr。只需给出一个或多个。如果提供了hess,则hessp将被忽略。 hessp必须计算一个任意向量的Hessian时间:

hessp(x, p, *args) ->  ndarray shape (n,)

其中x是(n,)ndarray,p是维度(n,)的任意向量,而args是具有固定参数的元组。

bounds:sequence 或 Bounds, 可选参数L-BFGS-B,TNC,SLSQP和trust-constr方法的变量界限。有两种方法可以指定范围:

Instance of Bounds class.

Sequence of (min, max) pairs for each element in x. None

is used to specify no bound.

constraints:{Constraint, dict} 或 List of {Constraint, dict}, 可选参数约束定义(仅适用于COBYLA,SLSQP和trust-constr)。 “ trust-constr”的约束定义为指定优化问题约束的单个对象或对象列表。可用的约束是:

COBYLA,SLSQP的约束定义为词典列表。每个带有字段的字典:

typestrConstraint type:‘eq’ for equality, ‘ineq’ for inequality.

funcallableThe function defining the constraint.

jaccallable, optionalThe Jacobian of fun (only for SLSQP).

argssequence, optionalExtra arguments to be passed to the function and Jacobian.

等式约束表示约束函数结果为零,而不等式表示约束函数结果为非负数。请注意,COBYLA仅支持不平等约束。

tol:float, 可选参数终止公差。要进行详细控制,请使用solver-specific选项。

options:dict, 可选参数求解器选项字典。所有方法都接受以下通用选项:

maxiterintMaximum number of iterations to perform. Depending on the

method each iteration may use several function evaluations.

dispboolSet to True to print convergence messages.

有关method-specific选项,请参见show_options。

callback:callable, 可选参数每次迭代后调用。对于“ trust-constr”,该调用带有签名:

callback(xk, OptimizeResult state) -> bool

其中xk是当前参数向量。和state是一个OptimizeResult对象,其字段与返回字段相同。如果回调返回True,则算法执行终止。对于所有其他方法,签名为:

callback(xk)

其中xk是当前参数向量。

返回值:

res:优化结果优化结果表示为OptimizeResult Object 。重要属性是:x解决方案数组,success布尔值标志,指示优化程序是否成功退出,以及message描述终止的原因。看到OptimizeResult用于其他属性的描述。

注意:

本节介绍可以通过‘method’参数选择的可用求解器。默认方法是BFGS。

无约束最小化

方法Nelder-Mead使用单纯形算法[1],[2]。该算法在许多应用中都很健壮。但是,如果可以信任导数的数值计算,则使用一阶和/或二阶导数信息的其他算法通常可能会更好,因为它们的性能更好。

方法鲍威尔是鲍威尔方法的修改[3],[4]这是共轭方向法。它沿着方向集的每个向量(选项和信息中的direc字段)执行顺序的一维最小化,并在主最小化循环的每次迭代时更新。函数不必是可微的,并且不采用任何导数。

方法CG使用Polak和Ribiere的非线性共轭梯度算法,这是Fletcher-Reeves方法的一种变种,在[5]第120-122页。仅使用一阶导数。

方法BFGS使用Broyden,Fletcher,Goldfarb和Shanno(BFGS)的quasi-Newton方法[5]pp。136.它仅使用一阶导数。事实证明,BFGS即使对于非平滑优化也具有良好的性能。此方法还返回Hessian逆的近似值,存储为OptimizeResult对象中的hess_inv。

方法Newton-CG使用Newton-CG算法[5]168页(也称为截断牛顿法)。它使用CG方法来计算搜索方向。另请参见TNC方法,用于使用类似算法最小化box-constrained。适用于large-scale问题。

方法狗腿使用dog-leg trust-region算法[5]无限制的最小化。该算法需要梯度和Hessian。此外,Hessian必须是正定的。

方法trust-ncg使用牛顿共轭梯度trust-region算法[5]无限制的最小化。该算法需要梯度和Hessian或计算给定向量的Hessian乘积的函数。适用于large-scale问题。

方法trust-krylov使用牛顿GLTR trust-region算法[14],[15]无限制的最小化。该算法需要梯度和Hessian或计算给定向量的Hessian乘积的函数。适用于large-scale问题。在不确定的问题上,与trust-ncg方法相比,它通常需要较少的迭代,建议将其用于中等和large-scale问题。

方法trust-exact是用于无约束最小化的trust-region方法,其中几乎完全解决了二次子问题[13]。此算法需要渐变和Hessian(不需要为正定)。在许多情况下,牛顿法收敛性较小,对于medium-size小问题最推荐。

Bound-Constrained最小化

方法L-BFGS-B使用L-BFGS-B算法[6],[7]用于约束约束的最小化。

方法TNC使用截断的牛顿算法[5],[8]最小化带有变量的函数。该算法使用梯度信息。它也被称为牛顿Conjugate-Gradient。它与上述的Newton-CG方法不同,因为它包装了C实现,并允许为每个变量指定上限和下限。

约束最小化

方法COBYLA使用线性逼近约束优化(COBYLA)方法[9],[10],[11]。该算法基于目标函数和每个约束的线性近似。该方法包装了该算法的FORTRAN实现。约束函数‘fun’可以返回单个数字或数字数组或数字列表。

方法SLSQP使用顺序最小二乘编程来最小化具有界限,相等和不等式约束的任意组合的多个变量的函数。该方法包装了Dieter Kraft最初实现的SLSQP Optimization子例程。[12]。请注意,包装器通过将无限值转换为大的浮动值来处理范围内的无限值。

方法trust-constr是用于约束优化的trust-region算法。它根据问题定义在两种实现方式之间切换。它是SciPy中实现的最通用的约束最小化算法,最适合large-scale问题。对于等式约束问题,它是Byrd-Omojokun Trust-Region SQP方法的实现,如[17]和在[5],第549.当同样施加不平等约束时,它也适用于trust-region内部点方法,该方法在[16]。反过来,此内点算法通过引入松弛变量并为障碍参数逐渐减小的值解决一 Series equality-constrained障碍问题,从而解决了不等式约束。前面描述的等式约束SQP方法用于随着迭代次数越来越接近解决方案而以提高的准确度来解决子问题。

Finite-Difference选项

方法trust-constr可以使用三种finite-difference方案({'2-point','3-point',‘cs’})对梯度和Hessian进行近似。方案‘cs’可能是最准确的,但它需要具有正确处理复杂输入并在复杂平面中可微分的函数。方案“ 3点”比“方案2点”更准确,但是需要两倍的操作量。

自定义最小化器

传递自定义最小化方法可能很有用,例如,在使用这种方法的前端时,例如scipy.optimize.basinhopping或其他 Library 。您可以简单地将callable作为method参数。

可调用的称为method(fun, x0, args, **kwargs, **options)其中kwargs对应于传递给的任何其他参数minimize(例如回调,粗体等等),但选项dict除外,其内容也成对地作为方法参数传递。此外,如果jac已作为bool类型传递,则jac和fun会受到干扰,以便fun仅返回函数值,而jac会转换为返回Jacobian函数的函数。该方法应返回OptimizeResult Object 。

提供的可调用方法必须能够接受(并可能忽略)任意参数;接受的参数集minimize可能会在将来的版本中扩展,然后将这些参数传递给该方法。您可以在scipy.optimize教程中找到一个示例。

0.11.0版中的新函数。

参考文献:

Nelder,J A和R Mead。 1965年。一种用于函数最小化的单纯形方法。计算机杂志7:308-13。

Wright M. H.,1996年。直接搜索方法:在1995年的“数值分析”中被轻蔑,现在受到尊重:1995年的邓迪两年一次的数值分析会议论文集(编者D F Griffiths和G A Watson)。 Addison Wesley Longman,英国哈洛。 191-208。

Powell,M J D. 1964年。一种无需计算导数即可找到多个变量的最小值的有效方法。计算机杂志7:155-162。

按W,S A Teukolsky,W T Vetterling和B P Flannery。数字食谱(任何版本),剑桥大学出版社。

5(1,2,3,4,5,6,7,8)

Nocedal,J和S J Wright。 2006。数值优化。纽约施普林格。

伯德,R H和P Lu和J. Nocedal。 1995。有限约束算法的约束约束优化。 SIAM科学与统计计算杂志16(5):1190-1208。

Zhu,C和R H Byrd和J Nocedal。 1997。L-BFGS-B:算法778:L-BFGS-B,用于大规模约束优化的FORTRAN例程。数学软件上的ACM交易23(4):550-560。

纳什(Nash),SG。Newton-Type通过Lanczos方法最小化。 1984年。SIAM数值分析杂志21:770-778。

Powell,M JD。一种直接搜索优化方法,通过线性插值对目标函数和约束函数进行建模。 1994年。《优化和数值分析的进展》,编辑。 S. Gomez和J-P Hennart,Kluwer Academic(Dordrecht),51-67。

Powell M JD。用于优化计算的直接搜索算法。 1998.Acta Numerica 7:287-336。

Powell M JD。没有导数的优化算法的观点。 2007.剑桥大学技术报告DAMTP 2007 /NA03

Kraft,D。用于顺序二次编程的软件包。 1988年。代表DFVLR-FB 88-28,DLR德国航空航天中心-德国科隆飞行力学研究所。

Conn,A. R.,Gould,N.I.和Toint,P. L.信任区域方法。 2000。暹罗。第169-200页。

F. Lenders,C。Kirches,A。Potschka:“ trlib:GLTR方法的vector-free实现,用于迭代解决信任区问题”,https://arxiv.org/abs/1611.04718

N. Gould,S。Lucidi,M。Roma,P。Toint:“使用Lanczos方法解决Trust-Region子问题”,SIAM J. Optim。,9(2),504-525,(1999)。

伯德(Richard H.),理查德·H·巴尔(Mary E. 1999。用于large-scale非线性编程的内点算法。 SIAM优化杂志9.4:877-900。

Lalee,Marucha,Jorge Nocedal和Todd Plantega。 1998年。关于large-scale等式约束优化的算法的实现。 SIAM Journal on Optimization 8.3:682-706。

例子:

让我们考虑最小化Rosenbrock函数的问题。此函数(及其相应的派生)在以下位置实现rosen(分别rosen_der,rosen_hess) 在里面scipy.optimize。

>>> from scipy.optimize import minimize, rosen, rosen_der

Nelder-Mead方法的一个简单应用是:

>>> x0 = [1.3, 0.7, 0.8, 1.9, 1.2]

>>> res = minimize(rosen, x0, method='Nelder-Mead', tol=1e-6)

>>> res.x

array([ 1., 1., 1., 1., 1.])

现在使用BFGS算法,使用一阶导数和一些选项:

>>> res = minimize(rosen, x0, method='BFGS', jac=rosen_der,

... options={'gtol': 1e-6, 'disp': True})

Optimization terminated successfully.

Current function value:0.000000

Iterations:26

Function evaluations:31

Gradient evaluations:31

>>> res.x

array([ 1., 1., 1., 1., 1.])

>>> print(res.message)

Optimization terminated successfully.

>>> res.hess_inv

array([[ 0.00749589, 0.01255155, 0.02396251, 0.04750988, 0.09495377], # may vary

[ 0.01255155, 0.02510441, 0.04794055, 0.09502834, 0.18996269],

[ 0.02396251, 0.04794055, 0.09631614, 0.19092151, 0.38165151],

[ 0.04750988, 0.09502834, 0.19092151, 0.38341252, 0.7664427 ],

[ 0.09495377, 0.18996269, 0.38165151, 0.7664427, 1.53713523]])

接下来,考虑一个具有多个约束的最小化问题(即示例16.4)。[5])。目标函数是:

>>> fun = lambda x: (x[0] - 1)**2 + (x[1] - 2.5)**2

定义了三个约束:

>>> cons = ({'type': 'ineq', 'fun': lambda x: x[0] - 2 * x[1] + 2},

... {'type': 'ineq', 'fun': lambda x: -x[0] - 2 * x[1] + 6},

... {'type': 'ineq', 'fun': lambda x: -x[0] + 2 * x[1] + 2})

并且变量必须为正,因此有以下界限:

>>> bnds = ((0, None), (0, None))

使用SLSQP方法可以解决优化问题,如下所示:

>>> res = minimize(fun, (2, 0), method='SLSQP', bounds=bnds,

... constraints=cons)

它应该收敛于理论解(1.4,1.7)。

你可能感兴趣的:(python实例,优化目标函数)