我使用此代码通过将指数与scipy.optimize.curve_fit
拟合来平滑数据:
def smooth_data_v1(x_arr,y_arr):
def func(x, a, b, c):
return a*np.exp(-b*x)+c
#Scale data
y = y_orig / 10000.0
x = 500.0 * x_orig
popt, pcov = curve_fit(func, x, y, p0=(1, 0.01, 1))
y_smooth = func(x, *popt) # Calcaulate smoothed values for same points
#Undo scaling
y_final = y_smooth * 10000.0
return y_final
Howewer我想要估计的指数曲线经过第一点。
坏情况:
好案例:
我尝试使用第一个点x0,y0删除最后一个参数:
def smooth_data_v2(x_orig,y_orig):
x0 = x_orig[0]
y0 = y_orig[0]
def func(x, a, b):
return a*np.exp(-b*x)+y0-a*np.exp(-b*x0)
#Scale data
y = y_orig / 10000.0
x = 500.0 * x_orig
popt, pcov = curve_fit(func, x, y, p0=(1, 0.01))
y_smooth = func(x, *popt) # Calcaulate smoothed values for same points
#Undo scaling
y_final = y_smooth * 10000.0
return y_final
Howewer出了点问题,我得到了:
a
参数真的很大popt [ 4.45028144e+05 2.74698863e+01]
有任何想法吗?
更新:
数据示例
x_orig [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.]
y_orig [ 445057. 447635. 450213. 425089. 391746. 350725. 285433. 269027.
243835. 230587. 216757. 202927. 189097. 175267. 161437.]
最佳答案
Scipy curve_fit
允许传递参数sigma
,该参数被设计为加权拟合的标准偏差。但是此数组可以填充任意数据:
from scipy.optimize import curve_fit
def smooth_data_v1(x_arr,y_arr):
def func(x, a, b, c):
return a*np.exp(-b*x)+c
#create the weighting array
y_weight = np.empty(len(y_arr))
#high pseudo-sd values, meaning less weighting in the fit
y_weight.fill(10)
#low values for point 0 and the last points, meaning more weighting during the fit procedure
y_weight[0] = y_weight[-5:-1] = 0.1
popt, pcov = curve_fit(func, x_arr, y_arr, p0=(y_arr[0], 1, 1), sigma = y_weight, absolute_sigma = True)
print("a, b, c:", *popt)
y_smooth = func(x_arr, *popt)
return y_smooth
x_orig = np.asarray([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
y_orig = np.asarray([ 445057, 447635, 450213, 425089, 391746, 350725, 285433, 269027,
243835, 230587, 216757, 202927, 189097, 175267, 161437])
print(smooth_data_v1(x_orig, y_orig))
如您所见,现在的第一个点和最后一个点都接近原始值,但是对于其余的数据点来说,这种“钳位”有时要付出一定的代价。
您可能还注意到,我删除了重新缩放部分。恕我直言,在进行曲线拟合之前,不应该这样做。通常最好使用原始数据。另外,您的数据不能真正用指数函数很好地表示,因此
b
值很小。关于python - 如何强制scipy.optimize.curve_fit解决第一点?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49151096/