私はおそらく次のようにします:
from __future__ import division
from __future__ import print_function
from scipy.optimize import curve_fit
import numpy as np
def parabola(t, *p):
a, b, c, d = p
y = np.zeros(t.shape)
indices = np.abs(t) < b
y[indices] = (a*(1-(((t[indices]-c)/b)**2)) + d)
return y
p0 = [1, 2, 3, 4]
x = np.linspace(-10, 10, 20)
y = parabola(x, *p0)
coeff, cov = curve_fit(parabola, x, y, p0)
print(coeff)
アップデート
提供されたデータ (コメント内のリンクを参照) を使用すると、状況がやや明確になり始めます。
これは、その動作に関して注意が必要なデータです。実際の関数の重みは、ゼロ データが増えるとますます小さくなるため、多くの「ゼロ」データは関数のフィッティングには役立ちません。多くの場合、最善の方法は、関連するデータに集中することです (それができたら、すべてのデータを最適なパラメータで適合させることができます)。
基準が正しくありません。データのピーク周辺ではなく、ゼロ周辺に集中しています ( c
)。
関数とインデックスの基準の両方にパラメーターb
とがあると、事態が難しくなります。関数はますます線形に動作しなくなります。c
以下のコメントアウトされた行である固定基準を使用して、初期の最適なパラメーターを見つけました。
適切な開始パラメーターを提供します。[1, 2, 3, 4]
は非常に一般的であり、非線形最小二乗法の場合、適合が難しくなる可能性があります。
したがって、上記のすべてを考慮に入れて、私はこれを思いつきました:
from __future__ import division
from __future__ import print_function
from scipy.optimize import curve_fit
import numpy as np
from matplotlib import pyplot as plt
def parabola(t, *p):
a, b, c, d = p
y = np.zeros(t.shape)
# The indices criterion was first fixed to values that appeared reasonably;
# otherwise the fit would completely fail.
# Once decent parameters were found, I replaced 28 and 0.3 with the center `c`
# and the width `b`.
#indices = np.abs(t-28) < 0.3
indices = np.abs(t-c) < b
y[indices] = (a*(1-(((t[indices]-c)/b)**2)) + d)
return y
out = np.loadtxt('data.dat')
# Limit the data to only the interesting part of the data
# Once we have the fit correct, we can always attempt a fit to all data with
# good starting parameters
xdata = out[...,0][450:550]
ydata = out[...,1][450:550]
# These starting parameters are either from trial fitting, or from theory
p0 = [2, 0.2, 28, 6.6]
coeff, cov = curve_fit(parabola, xdata, ydata, p0)
plt.plot(xdata, ydata, '.')
xfit = np.linspace(min(xdata), max(xdata))
yfit = parabola(xfit, *coeff)
plt.plot(xfit, yfit, '-')
plt.show()

b
結果のパラメーターは依然として不適切な適合を示していることに注意してください。これらのデータとこの関数の組み合わせはちょっと難しいと思います。1 つのオプションは、さまざまな妥当な値b
(たとえば、0.2 から 0.3 の間) を反復し、最適な縮小カイ 2 乗を見つけることです。
ただし、データが放物線として表示されないことにも注意してください。最初、データ全体の写真を見たとき「ガウシアン」と思ったのですが、それも違います。有蓋車の機能のように見えます。放物線であるという優れた理論モデルがある場合、データがずれているか、モデルが正しくない可能性があります。説明的な関数だけを探している場合は、他のいくつかの関数も試してください。