2017-12-19 6 views
1

私は物理プロセスを記述する関数Imaginaryを持っています。これをデータセットx_interpolate, y_interpolateに適合させたいと思います。この関数はLorentzianピーク関数の形式であり、私はピーク検出アルゴリズムを使って見つけたf_peak(ピーク位置)を除き、ユーザーが与えた初期値をいくつか持っています。オフセットを除くすべてのフィットパラメータは正であると予想され、したがって私はbounds_Iをそれに応じて設定しました。私はフィッティングプロセス中に固定パラメータf_peakを維持したいいくつかの状況でcurve_fitの適合パラメータを固定する

def Imaginary(freq, alpha, res, Ms, off): 
    numerator = (2*alpha*freq*res**2) 
    denominator = (4*(alpha*res*freq)**2) + (res**2 - freq**2)**2 
    Im = Ms*(numerator/denominator) + off 
    return Im 

pI = np.array([alpha_init, f_peak, Ms_init, 0]) 

bounds_I = ([0,0,0,0, -np.inf], [np.inf,np.inf,np.inf, np.inf]) 

poptI, pcovI = curve_fit(Imaginary, x_interpolate, y_interpolate, pI, bounds=bounds_I) 

。これは多くの理由のためにこれを行うよりPython的な方法がある場合ので、私は思っていたこれを行うのではない最適な方法である

bounds_I = ([0,f_peak+0.001,0,0, -np.inf], [np.inf,f_peak-0.001,np.inf, np.inf]) 

:私はへbounds_Iを変更することにより、簡単な解決策を試してみましたか?あなたの助けをありがとう

答えて

2

パラメータが固定されている場合、実際にパラメータではないので、パラメータのリストから削除する必要があります。そのパラメータを固定値で置き換えたモデルを定義し、それに合うようにします。以下の例では、簡潔にするために簡略化して自己完結型であること:及びcの最適値である戻り[-0.02350478, 0.35048631]を適合するための第2の呼

x = np.arange(10) 
y = np.sqrt(x)  
def parabola(x, a, b, c): 
    return a*x**2 + b*x + c 

fit1 = curve_fit(parabola, x, y) # [-0.02989396, 0.56204598, 0.25337086] 
b_fixed = 0.5 
fit2 = curve_fit(lambda x, a, c: parabola(x, a, b_fixed, c), x, y) 

。 bの値は0.5に固定した。

もちろん、パラメータは初期ベクトルpIと境界からも削除する必要があります。

0

lmfit(https://lmfit.github.io/lmfit-py/)が役立つ場合があります。このライブラリは、scipy最適化ルーチンに高レベルのインタフェースを追加し、最適化とカーブフィッティングのためのよりPythonのアプローチを目指しています。たとえば、Parameterオブジェクトを使用して、目的関数またはモデル関数を変更することなく、境界および固定パラメータを設定できます。カーブフィッティングの場合、使用できる高水準モデル関数を定義します。

ますたとえば、あなたは、(あなたの関数の署名に応じParameterオブジェクトに名前を付けますlmfit)パラメータを作成して初期値を提供し、あなたが

from lmfit import Model 
lmodel = Model(Imaginary) 

でそれを書いてきたように、あなたのImaginary関数を使用するとできます。デフォルトでは

params = lmodel.make_params(alpha=alpha_init, res=f_peak, Ms=Ms_init, off=0) 

すべてのパラメータが結合していないで、フィット感に変化しますが、あなたは(モデル関数を書き換えることなく)これらの属性を変更することができます。

params['alpha'].min = 0 
params['res'].min = 0 
params['Ms'].min = 0 

あなたはのようにフィットして変化しないように、パラメータの1つ(またはそれ以上)を設定することができます

params['res'].vary = False 

明確にするために:これはモデルの機能を変化させる必要がない場合には、それははるかに簡単に作りますどのような境界が課されるか、などのような、さまざまな要因に左右されます。

あなたは、モデルと、これらのパラメータでフィットを実行します:

result = lmodel.fit(y_interpolate, params, freq=x_interpolate) 

あなたは

print(result.fit_report()) 

とフィット統計のレポート、パラメータのための最高のフィット値と不確実性を得ることができます最適なパラメータはresult.paramsで保持されます。

lmfitには、LorentzianとConstantオフセットを含む多くの一般的な形式のモデルも組み込まれています。だから、あなたは、l_centerl_sigma、およびcl_amplitudeという名前のパラメータを持つことになります

from lmfit.models import LorentzianModel, ConstantModel 

mymodel = LorentzianModel(prefix='l_') + ConstantModel() 

params = mymodel.make_params() 

としてこのモデルを構築することができ(cは定数)とモデルは、(独立変数のためにあなたのfreqを名前xを使用します。 )。この手法は、ピークまたはバックグラウンドの機能的な形態を変更する場合や、複数のピークをスペクトルにフィッティングする場合に非常に便利になります。

関連する問題