7

いくつかの実験データ (y、x、t_exp、m_exp) があり、制約付き多変量 BFGS メソッドを使用して、このデータの「最適な」モデル パラメーター (A、B、C、D、E) を見つけたいと考えています。パラメータ E は 0 より大きい必要があり、その他は制約されていません。

def func(x, A, B, C, D, E, *args):
    return A * (x ** E) * numpy.cos(t_exp) * (1 - numpy.exp((-2 * B * x) / numpy.cos(t_exp))) +  numpy.exp((-2 * B * x) / numpy.cos(t_exp)) * C + (D * m_exp)

initial_values = numpy.array([-10, 2, -20, 0.3, 0.25])
mybounds = [(None,None), (None,None), (None,None), (None,None), (0, None)]
x,f,d = scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(m_exp, t_exp), bounds=mybounds)

いくつかの質問:

  1. モデルの定式化funcに独立変数を含める必要がありますか、それともの一部としてx実験データから提供する必要がありますか?x_exp*args
  2. 上記のコードを実行すると、エラーが発生しますfunc() takes at least 6 arguments (3 given)。これは、x と 2 つの *args であると想定しています...どのように定義すればよいfuncですか?

編集: @zephyr の回答のおかげで、実際の関数ではなく、残差の二乗和を最小化することが目標であることがわかりました。次の作業コードにたどり着きました:

def func(params, *args):
    l_exp = args[0]
    s_exp = args[1]
    m_exp = args[2]
    t_exp = args[3]
    A, B, C, D, E = params
    s_model = A * (l_exp ** E) * numpy.cos(t_exp) * (1 - numpy.exp((-2 * B * l_exp) / numpy.cos(t_exp))) +  numpy.exp((-2 * B * l_exp) / numpy.cos(theta_exp)) * C + (D * m_exp)
    residual = s_exp - s_model
    return numpy.sum(residual ** 2)

initial_values = numpy.array([-10, 2, -20, 0.3, 0.25])
mybounds = [(None,None), (None,None), (None,None), (None,None), (0,None)]

x, f, d = scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(l_exp, s_exp, m_exp, t_exp), bounds=mybounds, approx_grad=True)

境界が正しく機能しているかどうかはわかりません。E に (0, None) を指定すると、実行フラグ 2、異常終了が発生します。(1e-6, None) に設定すると問題なく動作しますが、E として 1e-6 を選択します。境界を正しく指定していますか?

4

1 に答える 1

13

使用しているモデルが何を表しているのかを理解しようとは思わなかったので、次の簡単な例を線に当てはめます。

x_true = arange(0,10,0.1)
m_true = 2.5
b_true = 1.0
y_true = m_true * x_true + b_true

def func(params、* args):
    x = args [0]
    y = args [1]
    m、b = params
    y_model = m * x + b
    エラー=y-y_model
    合計を返す(エラー** 2)

initial_values = numpy.array([1.0、0.0])
mybounds = [(None、2)、(None、None)]

scipy.optimize.fmin_l_bfgs_b(func、x0 = initial_values、args =(x_true、y_true)、approx_grad = True)
scipy.optimize.fmin_l_bfgs_b(func、x0 = initial_values、args =(x_true、y_true)、bounds = mybounds、approx_grad = True)

最初の最適化には制限がなく、正しい答えが得られます。2番目の最適化は境界を尊重し、正しいパラメーターに到達できないようにします。

あなたが間違っている重要なことは、ほとんどすべての最適化関数についてです。「x」と「x0」は、最適化するパラメーターを参照します。他のすべては引数として渡されます。また、fit関数が正しいデータ型を返すことも重要です。ここでは単一の値が必要です。一部のルーチンはエラーベクトルを予期しています。また、勾配を分析的に計算して提供する場合を除いて、approx_grad=Trueフラグが必要です。

于 2011-12-29T19:55:05.713 に答える