Python SciPy : 1 変数のスカラー関数の最小化
自分の頭の整理がてら、これから何回かに分けて SciPy の optimize パッケージについて整理していきます。 今回は最も簡単な 1 変数のスカラー関数の最小化関数についてまとめます。
関数について
1 変数のスカラー関数の最小化には minimize_scalar だけを使います。 他に fminbound, brent, golden といった関数が用意されていますが、minimize_scalar はオプション引数の method でこれら三つの手法を切り変えて使用できます。 指定できる method について表 1 にまとめます。
関数 | 説明 |
---|---|
minimize_scalar(method="brent") | Brent 法 |
minimize_scalar(method="bounded") | Brent 法(探索区間指定) |
minimize_scalar(method="golden") | 黄金分割法 |
minimize_scalar(method="custom") | 任意の最適化アルゴリズム |
実際に使うのは brent(デフォルト) か bounded です。brent は探索区間に指定がない場合、bounded は指定がある場合に使用します。 Brent 法は放物線補間という方法と黄金分割法を組み合わせた方法で、黄金分割法よりも収束が速いのが特徴です。 なお、brent ではオプションとして bracket で放物線補間の初期点を指定できます。これは探索区間の指定ではないので注意が必要です。
golden は単純に黄金分割法により最小値を求めます。 大抵は Brent 法で事足りますが、関数の導関数が不連続であるような場合には Brent 法がうまくいかないことがあるので、そういうときは 黄金分割法 を試してみるといいでしょう。
その他 custom では任意の最適化アルゴリズムを指定できるようになっています。
例
以下に関数の使用例を示します。 下手に bracket を指定すると意図していない極小点に収束することがあります。
# coding: utf-8 import numpy as np import matplotlib.pyplot as plt from scipy.special import j1 from scipy.optimize import minimize_scalar res1 = minimize_scalar(j1, method='brent') res1b = minimize_scalar(j1, bracket=(-10, 1), method='brent') res2 = minimize_scalar(j1, bounds=(4, 7), method='bounded') x = np.arange(-30, 10, 0.1) plt.figure() plt.plot(x, j1(x)) plt.plot(res1.x, res1.fun, "ob", label="brent") plt.plot(res1b.x, res1b.fun, "or", label="worth_id") plt.plot(res2.x, res2.fun, "oy", label="bounded") plt.legend(loc=0) # plt.show()
