このページは、NAGライブラリのJupyterノートブックExampleの日本語翻訳版です。オリジナルのノートブックはインタラクティブに操作することができます。
NAG最適化モデリングスイートを使用したキャリブレーション問題からの外れ値の除去
このノートブックの正しいレンダリング
このノートブックでは、方程式と参照のためにlatex_envs
Jupyter拡張機能を使用しています。ローカルにインストールしたJupyterでLaTeXが正しくレンダリングされない場合は、この拡張機能をインストールしていない可能性があります。詳細は
https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/latex_envs/README.html
をご覧ください。
キャリブレーション問題
モデル\(f\)の5つのパラメータを与えられたデータ点に適合させる単純なキャリブレーション問題を考えます。モデルは以下の形式です: \[ \min_{x\in\mathbb{R}^5} \sum_{i=1}^{30}\left( f(t_i, x) - y_i \right)^2 \] ここで、\(x=[a,b,c,d,\omega]\)は適合させるパラメータで、\(f(t, x) = at^2 + bt+ c + d\sin(\omega t)\)がモデルです。
データ
初期データ点\(\{(t_i, y_i)\}\)は以下を使用してシミュレートされました \[(a=0.3,b=1.0,c=0.01,d=0.2,\omega =5.0)\] ここで、\(t_i\)は\(\left[-1.0,1.0\right]\)に均一に分布し、\(y_i=f(t_i,x)+\epsilon_i\)で\(\epsilon_i\)はランダムノイズです。
これらの点のうち2つ(\(y_{10}\)と\(y_{20}\))は、外れ値の存在をエミュレートするために修正されました。
import pickle
import numpy as np
import matplotlib.pyplot as plt
import math
# シミュレーションデータを読み込み、2つの外れ値を含む
= pickle.load(open('nlnlsq_data.pck', 'rb'))
data = len(data['y'])
nres
# データ点と、それらを生成するために使用された真の関数をプロットする
= lambda t : 0.3*t**2 + t + 0.01 + 0.2*math.sin(5.0*t)
f_true 't'], data['y'], '*')
plt.plot(data[= np.linspace(-1.0,1.0, num=200)
t = [f_true(x) for x in t]
y
plt.plot(t, y) plt.show()
キャリブレーション問題のセットアップ
まず、ソルバーが任意のパラメータセット \(x\) でのフィットの品質を決定するために使用するコールバックを定義することから始めます。
def lsqfun(x, nres, inform, data):
"""
Objective function callback passed to the least squares solver.
"""
= np.zeros(nres)
rx = data['t']
t = data['y']
y for i in range(nres):
= (
rx[i] 0]*t[i]**2 + x[1]*t[i] + x[2] + x[3]*np.sin(x[4]*t[i]) - y[i]
x[
)return rx, inform
def lsqgrd(x, nres, rdx, inform, data):
"""
Computes the Jacobian of the least square residuals.
"""
= len(x)
n = data['t']
t for i in range(nres):
*n+0] = t[i]**2
rdx[i*n+1] = t[i]
rdx[i*n+2] = 1.0
rdx[i*n+3] = np.sin(x[4]*t[i])
rdx[i*n+4] = x[3]*t[i]*np.cos(x[4]*t[i])
rdx[ireturn inform
NAG ’ハンドル’を問題の次元といくつかのオプションパラメータで初期化します。
from naginterfaces.library import opt
from naginterfaces.base import utils
= 5
nvar # 変数の数で最適化モデルのハンドルを初期化する
= opt.handle_init(nvar)
handle
# 密な非線形最小二乗目的関数を定義する
opt.handle_set_nlnls(handle, nres)
# ソルバーの出力を制御するためのオプションパラメータを設定する
for option in [
'Print Options = NO',
'Print Level = 1',
'Print Solution = X',
'Bxnl Iteration Limit = 100',
]:
opt.handle_opt_set(handle, option)
# 省略された反復出力のために明示的なI/Oマネージャーを使用する:
= utils.FileObjManager(locus_in_output=False) iom
外れ値の問題を解決する
# ソルバーを呼び出す
= np.ones(nvar, dtype=float)
x = opt.handle_solve_bxnl(handle, lsqfun, lsqgrd, x, nres, data=data,
res =iom) io_manager
E04GG, Nonlinear least squares method for bound-constrained problems
Status: converged, an optimal solution was found
Value of the objective 1.05037E+00
Norm of gradient 8.78014E-06
Norm of scaled gradient 6.05781E-06
Norm of step 1.47886E-01
Primal variables:
idx Lower bound Value Upper bound
1 -inf 3.61301E-01 inf
2 -inf 9.10227E-01 inf
3 -inf 3.42138E-03 inf
4 -inf -6.08965E+00 inf
5 -inf 6.24881E-04 inf
フィッティングされたパラメータでモデルをプロットし、外れ値の影響を確認できます:
# データ点とフィッティングされた関数をプロットする
= res.x
x = lambda t : x[0]*t**2 + x[1]*t + x[2] + x[3]*math.sin(x[4]*t)
f_out 't'], data['y'], '*')
plt.plot(data[= [f_out(z) for z in t]
y
plt.plot(t, y)"outlier_fit.png")
plt.savefig( plt.show()
外れ値を除去して再度解く
# 2つの外れ値残差を無効にする
='NLS', idx=[10, 20])
opt.handle_disable(handle, comp
# 問題をもう一度解いてください
= np.ones(nvar, dtype=float)
x = opt.handle_solve_bxnl(handle, lsqfun, lsqgrd, x, nres, data=data,
res =iom) io_manager
E04GG, Nonlinear least squares method for bound-constrained problems
Status: converged, an optimal solution was found
Value of the objective 5.96811E-02
Norm of gradient 1.19914E-06
Norm of scaled gradient 3.47087E-06
Norm of step 3.49256E-06
Primal variables:
idx Lower bound Value Upper bound
1 -inf 3.53888E-01 inf
2 -inf 1.06575E+00 inf
3 -inf 1.91383E-03 inf
4 -inf 2.17299E-01 inf
5 -inf 5.17660E+00 inf
フィッティングされた関数はデータにずっと近くなりました!
# データ点とフィッティングされた関数をプロットする
= res.x
x = lambda t : x[0]*t**2 + x[1]*t + x[2] + x[3]*math.sin(x[4]*t)
f_fit 't'], data['y'], '*')
plt.plot(data[= [f_fit(z) for z in t]
y
plt.plot(t, y) plt.show()
opt.handle_free(handle)
このノートブックで紹介されているソルバーは、最適化モデリングスイート(NAGライブラリに付属)を通じてアクセスできます。最適化モデリングスイートについてさらに詳しく知るか、フォームに記入してください。できるだけ早くご連絡いたします。