0

私はscipy.optimize.curve_fitで曲線をフィットしようとしています。これは、シグマ配列の値ゼロである。私はアルゴリズムがこれを処理することができないことを理解しています。この場合、私はゼロで割ります。Python:sigma = 0を使ってscipy.optimize.curve_fitでデータをフィッティングする

シグマ:なしまたはM-長シーケンス、オプションの ない場合なし、ydataの配列の不確実性scipyのダウンロードドキュメントから。これらは、最小自乗問題、すなわちnp.sum(((f(xdata、* popt) - ydata)/ sigmaを最小にする)の重みとして使用される** 2)Noneの場合、不確かさは1と仮定される。

ここ

は私のコードは次のようになります。

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit 

x = [0.125, 0.375, 0.625, 0.875, 1.125, 1.375, 1.625, 1.875, 2.125, 2.375, 2.625, 2.875, 3.125, 3.375, 3.625, 3.875, 4.125, 4.375] 
y_para = [0, 0, 0.0414, 0.2164, 0.2616, 0.4254, 0.5698, 0.5921, 0.6286, 0.6452, 0.5879, 0.6032, 0.6667, 0.6325, 0.7629, 0.7164, 0.7091, 0.7887] 
err = [0, 0, 0.0391, 0.0331, 0.0943, 0.0631, 0.1219, 0.1063, 0.0912, 0.0516, 0.0365, 0.0327, 0.0227, 0.103, 0.1344, 0.0697, 0.0114, 0.0465] 

def logistic_growth(x, A1, A2, x_0, p): 
    return A2 + (A1-A2)/(1+(x/x_0)**p) 

x_plot = np.linspace(0, 4.5, 100) 

bounds_para = ([0.,0,-np.inf,-np.inf],[0.0000000001, 1,np.inf,np.inf]) 

paras, paras_cov = curve_fit(logistic_growth, x, y_para, bounds = bounds_para, sigma = err, absolute_sigma=True) 
para_curve = logistic_growth(x_plot, *paras) 

plt.figure() 
plt.errorbar(x,y_para, err, color = 'b', fmt = 'o', label = "Data") 
plt.plot(x_plot, para_curve, color = 'b', label = "Fit")  
plt.show() 

curve_fitにおけるシグマオプションが正常に動作せずにこれを実行すると、それが提起含む:ERR-配列でゼロからもたらされる、

ValueError: Residuals are not finite in the initial point. 

を。 誰もこれを回避する方法を知っていますか?

答えて

1

なぜ変数をドロップしないのですか?分散がゼロの場合、分析に意味のある方法で貢献することはできません。

+0

これはかなりうまくいきます。たぶんこれは、これを正しく解決する唯一の方法でもあります。しかし、実際には、これらのデータポイントも考慮したいと思います。欠けているエラーバーは、このデータポイントの値が複数の複製に対して変化しなかったためです。これは、ゼロ以外の値に対しても発生する可能性がありますが、それほどありません。この場合でもエラーの値を非常に低く設定することは、曲線を完全に台無しにするので、このトリックは行いません。私はあなたの提案と共に、良い結果を与えるので、統計的に正しいと思われ、問題を解決します。だから、ありがとう! –

1

これはscipyのダウンロードドキュメントがcurve_fitシグマパラメータについてこう言われる、「これらは最小二乗問題で重みとして使用されている...」その後、私の意見では、彼らはへの逆でなければなりませんエラー。ここに私が提案するものがあります。

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit 

x = [0.125, 0.375, 0.625, 0.875, 1.125, 1.375, 1.625, 1.875, 2.125, 2.375, 2.625, 2.875, 3.125, 3.375, 3.625, 3.875, 4.125, 4.375] 
y_para = [0, 0, 0.0414, 0.2164, 0.2616, 0.4254, 0.5698, 0.5921, 0.6286, 0.6452, 0.5879, 0.6032, 0.6667, 0.6325, 0.7629, 0.7164, 0.7091, 0.7887] 
err = [0, 0, 0.0391, 0.0331, 0.0943, 0.0631, 0.1219, 0.1063, 0.0912, 0.0516, 0.0365, 0.0327, 0.0227, 0.103, 0.1344, 0.0697, 0.0114, 0.0465] 

weights = [1/max(_,0.001) for _ in err] 
print (weights) 

def logistic_growth(x, A1, A2, x_0, p): 
    return A2 + (A1-A2)/(1+(x/x_0)**p) 

x_plot = np.linspace(0, 4.5, 100) 

bounds_para = ([0.,0,-np.inf,-np.inf],[0.0000000001, 1,np.inf,np.inf]) 

paras, paras_cov = curve_fit(logistic_growth, x, y_para, bounds = bounds_para, 
    absolute_sigma=True, 
    sigma = weights) 
para_curve = logistic_growth(x_plot, *paras) 

plt.figure() 
plt.errorbar(x,y_para, err, color = 'b', fmt = 'o', label = "Data") 
plt.plot(x_plot, para_curve, color = 'b', label = "Fit")  
plt.show() 

この結果、以下のプロットが得られます。これらの初期データポイントは、フィッティングされたラインのすぐ近くに配置されます。

resulting plot

+0

私は誤差が最小二乗問題を最小限に抑えるために逆に使われると思います。 scipy docから:「最小二乗問題の重み付け、すなわちnp.sum((f(xdata、* popt)-ydata)/ sigma)** 2)」を最小化する。これは誤差/シグマ値が大きくなるとそれぞれのデータポイントの重みが小さくなります。私は実際に前にあなたの魅力的なアプローチを試して、この特殊なケースのために良い結果をもたらすことを知っているが、私はそのような問題の正しいアプローチではないと思う。 –

+0

いくつかのデータポイントの* err *のゼロ値は、それらのポイントが正確に決定されたか、またはそれらが不正確に決定されたことを意味すると私の質問があると思いますか?連続して* err *の値が大きいほど精度が低いかどうかを示しますか? –

関連する問題