- SciPy 教程
- SciPy - 首页
- SciPy - 简介
- SciPy - 环境设置
- SciPy - 基本功能
- SciPy - 集群
- SciPy - 常量
- SciPy - FFTpack
- SciPy - 积分
- SciPy - 插值
- SciPy - 输入和输出
- SciPy - 线性代数
- SciPy - Ndimage
- SciPy - 优化
- SciPy - 统计
- SciPy - CSGraph
- SciPy - 空间
- SciPy - ODR
- SciPy - Special 包
- SciPy 有用资源
- SciPy - 参考
- SciPy - 快速指南
- SciPy - 有用资源
- SciPy - 讨论
SciPy - 优化
scipy.optimize 包提供了一些常用的优化算法。此模块包含以下方面:
使用各种算法(例如 BFGS、Nelder-Mead 单纯形、牛顿共轭梯度、COBYLA 或 SLSQP)进行多元标量函数的无约束和约束最小化 (minimize())
全局(蛮力)优化例程(例如,anneal()、basinhopping())
最小二乘最小化 (leastsq()) 和曲线拟合 (curve_fit()) 算法
标量单变量函数最小化器 (minimize_scalar()) 和根查找器 (newton())
使用各种算法(例如混合 Powell、Levenberg-Marquardt 或大规模方法,如 Newton-Krylov)的多元方程组求解器 (root())
多元标量函数的无约束和约束最小化
minimize() 函数为 scipy.optimize 中多元标量函数的无约束和约束最小化算法提供了一个通用接口。为了演示最小化函数,考虑最小化 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') 一起使用(通过 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 方法,可以通过在 minimize() 函数中设置 method = 'powell' 来使用。
最小二乘法
求解具有变量边界的非线性最小二乘问题。给定残差 f(x)(n 个实变量的 m 维实函数)和损失函数 rho(s)(标量函数),least_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 的 Powell 的混合方法和 Levenberg-Marquardt 方法。
以下示例考虑了单变量超越方程。
x2 + 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])