- 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])