SciPy 优化
scipy.optimize包 提供了几种常用的优化算法。This module contains the following aspects −
- 使用各种算法(如BFGS、Nelder-Mead simplex、Newton Conjugate Gradient、COBYLA或SLSQP)对多变量标量函数进行无约束和约束的最小化(minimize())。
-
全局(粗暴)优化程序(例如,退火(),跳盆())。
-
最小二乘法(leastsq())和曲线拟合(curve_fit())算法
-
标量单变量函数最小化(minimize_scalar())和根查找器(newton())。
-
多变量方程组求解器(root()),使用各种算法(如混合鲍威尔、莱文伯格-马夸特或大规模方法,如牛顿-克雷洛夫)。
多变量标量函数的无约束和约束性最小化
minimize()函数 为 scipy.optimation 中的多元标量函数的无约束和有约束最小化算法提供了一个通用接口 。 为了演示最小化函数,考虑最小化NN变量的Rosenbrock函数的问题–
f(x) = sum_{i = 1}^{N-1}:100(x_i – x_{i-1}^{2})
这个函数的最小值是0,当xi=1时就能达到。
Nelder-Mead简单算法
在下面的例子中,minimize()例程与 Nelder-Mead单线算法(method = ‘Nelder-Mead’) 一起使用(通过方法参数选择)。让我们考虑下面的例子。
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]
单纯算法可能是最小化一个相当好的函数的最简单的方法。它只需要函数评估,对于简单的最小化问题是一个不错的选择。然而,由于它不使用任何梯度评价,它可能需要更长的时间来找到最小值。
另一种只需要调用函数就能找到最小值的优化算法是 鲍威尔方法 ,它可以通过在最小化()函数中设置 method = ‘powell’ 来实现。
最小二乘法
解决一个非线性最小二乘法问题,并对变量进行限制。给出残差f(x)(n个实数变量的m维实数函数)和损失函数rho(s)(一个标量函数),最小二乘法找到成本函数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分别使用 Powell的混合方法 和MINPACK的 Levenberg-Marquardt方法 。
下面的例子考虑了单变量的超越方程。
**x 2 + 2cos(x) = 0 **
A root of which can be found as follows −
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])