Python SciPy : 非線形最小二乗問題の最適化アルゴリズム

今回は非線形最小二乗問題(データ近似問題)の SciPy の関数についてまとめます。

関数について

SciPy で非線形最小二乗問題を解く関数は表 1 のものがあります。

表1: 非線形最小二乗問題の最適化アルゴリズム
関数 説明
leastsq Levenberg-Marquardt 法で最小二乗問題の解を求める
nnls 有効制約法で非負の最小二乗問題の解を求める
curve_fit leastsq のインターフェースを曲線近似用に変更したもの

leastsq は MINPACK の LMDIF と LMDER のラッパーで、Levenerg-Marquardt 法で最小二乗問題の解を求めます。 Levenerg-Marquardt 法は Gauss-Newton 法よりも計算回数は増えますが、非線形性が強い問題でも安定して収束する方法です。 そのため非線形最小二乗問題を解く手法として標準的に使われています。

nnls はパラメータが非負の制約条件のもとで最小二乗問題の解を求める方法です。

curve_fit は leastsq のインターフェースを変えたもので、内部では leastsq を呼び出しています。

以前 に Gauss-Newton 法で取り上げた例をやってみます。

leastsq で書いた場合

# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq


def objectiveFunction(beta):
    r = y - theoreticalValue(beta)
    return r


def theoreticalValue(beta):
    f = beta[0]*x / (beta[1]+x)
    return f

x = np.array([0.038, 0.194, 0.425, 0.626, 1.253, 2.500, 3.740])
y = np.array([0.050, 0.127, 0.094, 0.2122, 0.2729, 0.2665, 0.3317])

initialValue = np.array([0.9, 0.2])
betaID = leastsq(objectiveFunction, initialValue)

plt.figure()
plt.plot(x, y, 'r.')
plt.plot(x, theoreticalValue(betaID[0]), 'b')
plt.show()
15062501.png

curve_fit で書いた場合

# coding: utf-8
from scipy.optimize import curve_fit


def theoreticalValue(x, a, b):
    f = a*x / (b+x)
    return f

x = np.array([0.038, 0.194, 0.425, 0.626, 1.253, 2.500, 3.740])
y = np.array([0.050, 0.127, 0.094, 0.2122, 0.2729, 0.2665, 0.3317])

initialValue = np.array([0.9, 0.2])
betaID, pconv = curve_fit(theoreticalValue, x, y)

plt.figure()
plt.plot(x, y, 'r.')
plt.plot(x, theoreticalValue(x, betaID[0], betaID[1]), 'b')
# plt.show()
15062502.png

コメント

Comments powered by Disqus
書籍更新情報
2017-02-18
Pythonによる科学技術計算 基礎編
1.4版への更新が可能になりました。
サポートページはこちら
電子書籍
Pythonによる科学技術計算 基礎編
電子書籍
線形代数(1): Pythonによる科学技術計算 実践編