2

私はフォームの放物線形状でデータを当てはめようとしています: Y(x) = a(1 – (x/b)^2) for |x| < b ....... Y(x) = 0 それ以外の場合 放物線を水平方向および垂直方向に移動できるように、自由度を 2 つ追加しました。

from scipy.optimize import curve_fit

def parabolic(self, t, *p): 
    a, b, c, d = p        
    if abs(t) > b:
        return 0
    else:
        return a*(1-(((t-c)/b)**2)) + d

私は scipy.optimize から curve_fit を使用しようとしており、放物線関数を作成しました。これを使用して適合させようとしています:

coeff, cov = curve_fit(parabolic, data[:,0], data[:,1], p0) #Return co-effs for fit and      covariance, p0 = user given seed fitting parameters

The script returns an error though related to using logic in my parabolic fit definition. When I remove the logic statement and just fit to the entire data (which is a background noise level with a parabolic shape in the centre), the results are awful as the fit tries to include the background noise level.

All suggestions welcomed.

Thanks

4

1 に答える 1

2

私はおそらく次のようにします:

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 乗を見つけることです。

ただし、データが放物線として表示されないことにも注意してください。最初、データ全体の写真を見たとき「ガウシアン」と思ったのですが、それも違います。有蓋車の機能のように見えます。放物線であるという優れた理論モデルがある場合、データがずれているか、モデルが正しくない可能性があります。説明的な関数だけを探している場合は、他のいくつかの関数も試してください。

于 2013-04-25T09:42:15.157 に答える