2016-11-27 10 views
0

、Yデータは、Xデータの加重和としてフィットすることができ、そして私の問題がにあります最適なフィットを与える係数を見つける。カーブフィッティングの最適化scipyのダウンロードのPythonのnumpyの

私はそれが最良か最適な方法ではないかもしれないが、私はそれを実現する一つの方法を理解している。

しかし、Xのデータをシフトしたり、Xの各列をN回ずつずらしたりスライディングしたりした後でのみ、最良のフィットが得られるように、Xのデータをシフトすることがあります。

これを行うためにnp.rollが使用できるかどうかを確認しようとしましたが、機能には係数とnp.rollの整数値が必要なのでスタックしました。フィット感を改善するためにN。

私の主な問題は、カーブフィットにこれら2つの異なる種類のパラメータをどのように渡すことができるのか理解できないと思います - 可能でしょうか?

おそらく、np.rollはこれを行う最善の方法ではありませんか?だから、別の方法のための任意の提案も感謝します。

以下の例では、2番目の列を-1だけシフトすると、XdataのYdataへの適合性が向上します。

xdata = np.array([[1.0, 1.0],[1.0, 1.0], [2.0, 3.0], [4.0, 2.0], [2.0, 1.0],[1.0, 1.0]]) 

ydata = np.array([3.0, 5.0, 6.0, 9.0, 5.0, 3.0]) 


def fitfunc(xdata, *params): 
    ctx = 0.0 

    # y is not yet defined by somehow I would like it to take the values passed in the second np.array defined in c below 
    # the for loop should just run twice in this example 

    for n in range(len(params)): 
     ctx = params[n]*np.roll(xdata[:,n], y, axis=0) + ctx 
    return ctx, y 

#initial guesses for fitting parameters 
c = (np.array([0.6, 0.3]), np.array([1, 1])) # the second np.array is what I would like to pass a y's 

# fit data using SciPy's Levenberg-Marquart method 
nlfit, nlpcov = scipy.optimize.curve_fit(fitfunc, xdata, ydata, p0=(c), sigma=None) 

print (nlfit) 

任意のヘルプ

+0

y = mx + bの形式の線形モデルを使用しようとしていますが、線を上下に移動する定数項bを含める必要がありますか?または、あなたのデータは時系列のセットで、x-variablesの遅れ(np.rollによって暗示されている可能性があります)がわからない場合はどうしますか? – David

+0

私のデータはスペクトルです。したがって、Xdata配列は、列に配置された2つのスペクトルのマトリックスである可能性があります。私の以前の質問から、Xdataは私のydataをX * a + X * b ... etc = Ydataと記述できると信じています。フィットを最適化しようとしたときにxデータの列を上下にシフトさせたいという理由は、実際のデータではそのようなシフトが一般的であることを意味する実験的な誤差があるため、Xdataの各列を係数、願わくば、最良の適合を見つけるためにXdata列を互いに対して試してみる方法があります。 – steve

+0

私は何を達成したいのかを明確にしたいと思いますか? np.rollは、このような列の相互移動を実現することができると思ったのです。関係するスペクトルには何千もの点があるので、より良いフィット感を得るために片方の端からもう一方へ、またはその逆にいくつかの点を回転させることは、これを達成する方法かもしれないと私は考えました。 – steve

答えて

0

curve_fitを事前にあなたがfitfuncにしたい、しかし、あなたが使用できるパラメータの単一のアレイを、期待していありがとう。この例では、p個の列があり、各列には勾配とシフトがあります。最後に、2 * p要素のパラメータ配列が必要です。初期パラメータ配列はこのように見える必要があります、

  • slope_params最初のp要素を取るparams[:cols]を使用してスロープパラメータの配列を、:fitfuncインサイド

    c = np.array([0.6, 0.3, 1, 1]) 
    

    、私はにパラメータ配列を分割します

  • shift_paramsは、最後のp個の要素をとるparams[cols:]を使用するシフトパラメータの配列です。

fitfuncのための完全なコード:私たちは[int(round(n)) for n in params[cols:]]を使用して、整数にシフトパラメータを変換する必要があり

def fitfunc(xdata, *params): 
    # Get number of columns in data 
    cols = xdata.shape[1] 

    # Get slope parameters 
    slope_params = params[:cols] 

    # Get shift parameters and convert to int 
    shift_params = [int(round(n)) for n in params[cols:]] 

    # Calculate fit 
    ctx = 0.0 
    for n in range(len(slope_params)): 
     ctx = slope_params[n] * np.roll(xdata[:,n], shift_params[n], axis=0) + ctx 

    # Show progress 
    print(params) 

    return ctx 

注意を。

curve_fitでこれを使用すると、すべてのシフトパラメータを変更し、警告を与えていない:

(0.59999999999999998, 0.29999999999999999, 1.0, 1.0) 
(0.59999999999999998, 0.29999999999999999, 1.0, 1.0) 
(0.59999999999999998, 0.29999999999999999, 1.0, 1.0) 
(0.60000000894069672, 0.29999999999999999, 1.0, 1.0) 
(0.59999999999999998, 0.30000000447034836, 1.0, 1.0) 
(0.59999999999999998, 0.29999999999999999, 1.0000000149011612, 1.0) 
(0.59999999999999998, 0.29999999999999999, 1.0, 1.0000000149011612) 
(-0.40816307558733345, 3.6326528012731845, 1.0, 1.0) 
(-0.40816306950522968, 3.6326528012731845, 1.0, 1.0) 
(-0.40816307558733345, 3.6326528554039292, 1.0, 1.0) 
(-0.40816307558733345, 3.6326528012731845, 1.0000000149011612, 1.0) 
(-0.40816307558733345, 3.6326528012731845, 1.0, 1.0000000149011612) 
(-0.40816327556523363, 3.632653071646589, 1.0, 1.0) 
OptimizeWarning: Covariance of the parameters could not be estimated 
    category=OptimizeWarning) 
[-0.40816328 3.63265307 1.   1.  ] 

あなたはより良い結果を得るために最適化設定を調整することができるかもしれませんが、私はこれを考えていませんあなたの問題に対する最も有望なアプローチです。

+0

このことをどのように説明してくれたことに感謝します。私の場合、元の問題を解決する方法ではないと思っていても、 – steve

関連する問題