Scipyのcurve_fit
(または利用可能であればもっと適切なもの)を使用してベクトル出力に関数をフィットさせたいと思います。たとえば、次の関数を考えてみましょう。Scipyでcurve_fitを使ってベクトル関数をフィッティングする
import numpy as np
def fmodel(x, a, b):
return np.vstack([a*np.sin(b*x), a*x**2 - b*x, a*np.exp(b/x)])
各コンポーネントは異なる関数ですが、それらは私が適合したいパラメータを共有しています。
x = np.linspace(1, 20, 50)
a = 0.1
b = 0.5
y = fmodel(x, a, b)
y_noisy = y + 0.2 * np.random.normal(size=y.shape)
from scipy.optimize import curve_fit
popt, pcov = curve_fit(f=fmodel, xdata=x, ydata=y_noisy, p0=[0.3, 0.1])
しかしcurve_fit
は、ベクトル出力を持つ関数では動作しませんし、エラーResult from function call is not a proper array of floats.
がスローされます。理想的には、私はこのような何かをするだろう。私が代わりにしたのは次のような出力を平らにすることです:
def fmodel_flat(x, a, b):
return fmodel(x[0:len(x)/3], a, b).flatten()
popt, pcov = curve_fit(f=fmodel_flat, xdata=np.tile(x, 3),
ydata=y_noisy.flatten(), p0=[0.3, 0.1])
そしてこれが動作します。ベクトル関数の代わりに、実際には異なる入力を持つ複数の関数をフィッティングしていますが、モデルパラメータを共有する場合は、入力と出力の両方を連結できます。
ベクトル関数をScipyまたはおそらくいくつかの追加モジュールに適合させるより適切な方法はありますか?私の主な考慮事項は効率です。実際にフィットする関数ははるかに複雑で、フィットには時間がかかることがあるので、このようなcurve_fit
の使用が混乱して実行時間が過ぎると、私は何をすべきかを知りたいと思います。
[lmfit](https://lmfit.github.io/lmfit-py/)に興味があるかもしれません。彼らはまた、多次元データのための 'flatten'メソッドを提案します。 – chthonicdaemon