最適化アルゴリズムExample集: 導関数を用いない非線形最小二乗問題の解法
nAG数値計算ライブラリ > 最適化アルゴリズムExample集 > 導関数を用いない非線形最小二乗問題の解法

非線形最小二乗問題(導関数なし)

このExampleでは、n変数(mは少なくともn)のm個の非線形関数の二乗和の無制約最小値を求めています。導関数は必要ありません。内点法を用いたLP問題の解法を示すためのExampleです。

目的関数:

タスク
minimize \(\sum_{i=1}^{m} \left(x_0 + \frac{t_{i,0}}{x_1 t_{i,1} + x_2 t_{i,2}} - y_i\right)^2\)

ここで、\(t\)\(m \times 3\)の行列、\(y\)は長さ\(m\)のベクトルです。目的は、観測データ\(y\)と、パラメータ\(x_0, x_1, x_2\)を用いたモデル予測値の二乗誤差の総和を最小化することです。

決定変数:

変数 範囲
\(x_0\) 実数
\(x_1\) 実数
\(x_2\) 実数

制約条件:

このExampleでは制約条件はありません。無制約最適化問題として定式化されています。

具体的な数値例として、以下のデータが使用されています。

\(y = [0.14, 0.18, 0.22, 0.25, 0.29, 0.32, 0.35, 0.39, 0.37, 0.58, 0.73, 0.96, 1.34, 2.10, 4.39]\)

\(t = \begin{bmatrix} 1.0 & 15.0 & 1.0\\ 2.0 & 14.0 & 2.0\\ 3.0 & 13.0 & 3.0\\ 4.0 & 12.0 & 4.0\\ 5.0 & 11.0 & 5.0\\ 6.0 & 10.0 & 6.0\\ 7.0 & 9.0 & 7.0\\ 8.0 & 8.0 & 8.0\\ 9.0 & 7.0 & 7.0\\ 10.0 & 6.0 & 6.0\\ 11.0 & 5.0 & 5.0\\ 12.0 & 4.0 & 4.0\\ 13.0 & 3.0 & 3.0\\ 14.0 & 2.0 & 2.0\\ 15.0 & 1.0 & 1.0 \end{bmatrix}\)

初期推定値は \(x = [0.5, 1.0, 1.5]\) です。

最適解は \(x = [0.082, 1.133, 2.344]\) で、二乗誤差の総和は0.0082となります。

Exampleの実行コマンド:

python -m naginterfaces.library.examples.opt.lsq_uncon_mod_func_comp_ex

ソースコード表示コマンド:

python -c "import inspect; from naginterfaces.library.examples.opt import lsq_uncon_mod_func_comp_ex; print(''.join(inspect.getsourcelines(lsq_uncon_mod_func_comp_ex)[0]))"

出力結果例:

naginterfaces.library.opt.lsq_uncon_mod_func_comp Python Example Results.
Find an unconstrained minimum of a sum of squares.
Best fit model parameters are:
        x_0 =      0.082
        x_1 =      1.133
        x_2 =      2.344
Residuals for observed data:
   -0.0059   -0.0003    0.0003    0.0065   -0.0008
   -0.0013   -0.0045   -0.0200    0.0822   -0.0182
   -0.0148   -0.0147   -0.0112   -0.0042    0.0068
Sum of squares of residuals: 0.0082

マニュアル:

lsq_uncon_mod_func_compのマニュアル

ソース:

#!/usr/bin/env python3
"``naginterfaces.library.opt.lsq_uncon_mod_func_comp`` Python Example."

# nAG Copyright 2021.

# pylint: disable=invalid-name,too-many-arguments

import numpy as np

from naginterfaces.library import opt

def main():
    """
    Example for :func:`naginterfaces.library.opt.lsq_uncon_mod_func_comp`.

    Find an unconstrained minimum of a sum of squares of m nonlinear
    functions in n variables (m at least n). No derivatives are required.

    >>> main()
    naginterfaces.library.opt.lsq_uncon_mod_func_comp Python Example Results.
    Find an unconstrained minimum of a sum of squares.
    <BLANKLINE>
    Best fit model parameters are:
            x_0 =      0.082
            x_1 =      1.133
            x_2 =      2.344
    <BLANKLINE>
    Residuals for observed data:
       -0.0059   -0.0003    0.0003    0.0065   -0.0008
       -0.0013   -0.0045   -0.0200    0.0822   -0.0182
       -0.0148   -0.0147   -0.0112   -0.0042    0.0068
    <BLANKLINE>
    Sum of squares of residuals: 0.0082
    """

    print(
        'naginterfaces.library.opt.lsq_uncon_mod_func_comp '
        'Python Example Results.'
    )
    print('Find an unconstrained minimum of a sum of squares.')

    def cb_lsqfun(iflag, m, xc):
        """Evaluate the residuals."""
        fvec = (xc[0] + t[:,0]/(xc[1]*t[:,1]+xc[2]*t[:,2]) - y[:])
        return iflag, fvec

    y = [
        0.14, 0.18, 0.22, 0.25, 0.29, 0.32, 0.35, 0.39, 0.37,
        0.58, 0.73, 0.96, 1.34, 2.10, 4.39,
    ]

    m = len(y)

    t = np.array([
        [1.0, 15.0, 1.0],
        [2.0, 14.0, 2.0],
        [3.0, 13.0, 3.0],
        [4.0, 12.0, 4.0],
        [5.0, 11.0, 5.0],
        [6.0, 10.0, 6.0],
        [7.0, 9.0, 7.0],
        [8.0, 8.0, 8.0],
        [9.0, 7.0, 7.0],
        [10.0, 6.0, 6.0],
        [11.0, 5.0, 5.0],
        [12.0, 4.0, 4.0],
        [13.0, 3.0, 3.0],
        [14.0, 2.0, 2.0],
        [15.0, 1.0, 1.0],
    ])

    # Initial guess
    x = [.5, 1., 1.5]

    soln = opt.lsq_uncon_mod_func_comp(
        m, cb_lsqfun, x,
    )

    print('\nBest fit model parameters are:')
    for i in range(len(x)):
        print('        x_{:d} = {:10.3f}'.format(i, soln.x[i]))

    print('\nResiduals for observed data:')
    print('\n'.join([''.join(['  {:8.4f}']*5)]*3).format(*soln.fvec))

    print('\nSum of squares of residuals: {:6.4f}'.format(soln.fsumsq))

if __name__ == '__main__':
    import doctest
    import sys
    sys.exit(
        doctest.testmod(
            None, verbose=True, report=False,
            optionflags=doctest.REPORT_NDIFF,
        ).failed
    )

関連情報
Privacy Policy  /  Trademarks