pythonには、多くのパラメーターを持つ関数があります。この関数をデータセットに適合させたいのですが、パラメーターを1つだけ使用して、残りのパラメーターは自分で提供します例は次のとおりです。
def func(x,a,b):
return a*x*x + b
for b in xrange(10):
popt,pcov = curve_fit(func,x1,x2)
これで私はフィッティングがa
に対してのみ行われ、パラメータb
がループ変数の値を取ることを望みます。これはどのように行うことができますか?
次のように、func
をラムダでラップできます。
def func(x,a,b):
return a*x*x + b
for b in xrange(10):
popt,pcov = curve_fit(lambda x, a: func(x, a, b), x1, x2)
ラムダは無名関数であり、Pythonで使用できるのは単純な1行の関数のみです。基本的に、名前を割り当てる必要がない場合に、コードの量を減らすために通常使用されますより詳細な説明は公式ドキュメントに記載されています: http://docs.python.org/tutorial/controlflow.html#lambda-forms
この場合、ラムダを使用してfunc
の引数の1つを修正します。新しく作成された関数はx
とa
の2つの引数のみを受け入れますが、b
はローカルのb
変数から取得した値に固定されます。次に、この新しい関数が引数としてcurve_fit
に渡されます。
ダイジェストを直感的に理解できない可能性があるラムダ関数を使用する代わりに、カスタム境界内でパラメーターを強制的に検索するscikit curve_fit parameter bounds
を指定することをお勧めします。
あなたがしなければならないのは、変数aを-infと+ infの間で移動させ、変数bbetween( b-イプシロン)および(b+イプシロン)
あなたの例では:
epsilon = 0.00001
def func(x,a,b):
return a*x*x + b
for b in xrange(10):
popt,pcov = curve_fit(func,x1,x2, bounds=((-np.inf,b-epsilon), (np.inf,b+epsilon))
Scipyのcurve_fitは、func、xdata、ydataの3つの位置引数を取ります。したがって、(関数ラッパーを使用する)代替のアプローチは、元のxdata(x1)と固定パラメーターbの2番目の列の両方を含む行列を作成することにより、「b」をxdata(つまり、独立変数)として扱うことです。
X1とx2が配列であると仮定します。
def func(xdata,a):
x, b = xdata[:,0], xdata[:,1] # Extract your x and b
return a*x*x + b
for b in xrange(10):
xdata = np.zeros((len(x1),2)) # initialize a matrix
xdata[:,0] = x1 # your original x-data
xdata[:,1] = b # your fixed parameter
popt,pcov = curve_fit(func,xdata,x2) # x2 is your y-data
元の関数を編集する意思がある、または編集できる場合は、より簡単なオプションがあります。
関数を次のように再定義します。
def func(x,a):
return a*x*x + b
次に、パラメーターbのループに単純に配置できます。
for b in xrange(10):
popt,pcov = curve_fit(func, x1, x2)
注意:関数は、これが機能するために呼び出されるのと同じスクリプトで定義する必要があります。