📜  SciPy-优化

📅  最后修改于: 2020-11-05 04:34:45             🧑  作者: Mango


scipy.optimize包提供了几种常用的优化算法。该模块包含以下方面-

  • 使用多种算法(例如BFGS,Nelder-Mead单形,牛顿共轭梯度,COBYLA或SLSQP)对多元标量函数(minimize())进行无约束和无约束最小化

  • 全局(强力)优化例程(例如,anneal(),basinhopping())

  • 最小二乘最小化(leastsq())和曲线拟合(curve_fit())算法

  • 标量单变量函数最小化器(minimize_scalar())和根查找器(newton())

  • 使用多种算法的多元方程组系统求解器(root())(例如,混合Powell,Levenberg-Marquardt或诸如Newton-Krylov之类的大规模方法)

多元标量函数的无约束和无约束最小化

minimum ()函数scipy.optimize中的多元标量函数的无约束和无约束最小化算法提供了通用接口。为了演示最小化函数,请考虑使NN变量的Rosenbrock函数最小化的问题-

$$ f(x)= \ sum_ {i = 1} ^ {N-1} \:100(x_i-x_ {i-1} ^ {2})$$

该函数的最小值为0,这是在xi = 1时实现的。

Nelder–Mead单纯形算法

在下面的示例中,最小化()例程与Nelder-Mead单形算法(方法=’Nelder-Mead’)一起使用(通过method参数选择)。让我们考虑以下示例。

import numpy as np
from scipy.optimize import minimize

def rosen(x):

x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
res = minimize(rosen, x0, method='nelder-mead')

print(res.x)

上面的程序将生成以下输出。

[7.93700741e+54  -5.41692163e+53  6.28769150e+53  1.38050484e+55  -4.14751333e+54]

单纯形算法可能是最小化行为良好的函数的最简单方法。它仅需要函数评估,对于简单的最小化问题是一个不错的选择。但是,由于它不使用任何梯度评估,因此可能需要更长的时间才能找到最小值。

只需函数调用即可找到最小值的另一种优化算法是Powell方法,可通过在minimum()函数设置method =’powell’来使用。

最小二乘

用变量的边界求解非线性最小二乘问题。给定残差f(x)(n个实变量的m维实函数)和损失函数rho(s)(标量函数),minimum_squares找到成本函数F(x)的局部最小值。让我们考虑以下示例。

在此示例中,我们找到了Rosenbrock函数的最小值,这些变量对自变量没有界限。

#Rosenbrock Function
def fun_rosenbrock(x):
   return np.array([10 * (x[1] - x[0]**2), (1 - x[0])])
   
from scipy.optimize import least_squares
input = np.array([2, 2])
res = least_squares(fun_rosenbrock, input)

print res

注意,我们仅提供残差的向量。该算法将成本函数构造为残差的平方和,从而得到Rosenbrock函数。精确的最小值为x = [1.0,1.0]。

上面的程序将生成以下输出。

active_mask: array([ 0., 0.])
      cost: 9.8669242910846867e-30
      fun: array([ 4.44089210e-15, 1.11022302e-16])
      grad: array([ -8.89288649e-14, 4.44089210e-14])
      jac: array([[-20.00000015,10.],[ -1.,0.]])
   message: '`gtol` termination condition is satisfied.'
      nfev: 3
      njev: 3
   optimality: 8.8928864934219529e-14
      status: 1
      success: True
         x: array([ 1., 1.])

寻根

让我们了解根源查找对SciPy的帮助。

标量函数

如果一个人有一个单变量方程,则可以尝试四种不同的求根算法。这些算法中的每一个都需要一个期望有根的间隔的端点(因为该函数改变符号)。通常, brentq是最佳选择,但其他方法在某些情况下或出于学术目的也可能有用。

定点求解

与找到一个函数的零点密切相关的问题是找到一个函数的不动点的问题。函数的固定点是函数求函数返回点的点:g(x)= x。显然, gg的不动点是f(x)= g(x)-x的根。等效地, ff的根是g(x)= f(x)+ x的不动点。例程fixed_point提供了一种简单的迭代方法,该方法使用Aitkens序列加速来估算gg的固定点(如果已给出起点)。

方程组

可以使用root()函数来找到一组非线性方程的。可以使用几种方法,其中hybr (默认)和lm分别使用MINPACK的PowellLevenberg-Marquardt混合方法

以下示例考虑了单变量先验方程。

x 2 + 2cos(x)= 0

其根可以如下找到-

import numpy as np
from scipy.optimize import root
def func(x):
   return x*2 + 2 * np.cos(x)
sol = root(func, 0.3)
print sol

上面的程序将生成以下输出。

fjac: array([[-1.]])
fun: array([ 2.22044605e-16])
message: 'The solution converged.'
   nfev: 10
   qtf: array([ -2.77644574e-12])
      r: array([-3.34722409])
   status: 1
   success: True
      x: array([-0.73908513])