使用lmfit拟合三角PDF时出现异常结果的求助
三角形分布拟合异常问题排查
待拟合数据点
我有一组包含x、y坐标的点:
x = np.array([0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360, 390]) y = np.array([0, 1.2, 2.8, 1.7, 1.4, 1.2, 1.1, 0.91, 0.74, 0.61, 0.5, 0.28, 0.17, 0])
这些点大致呈三角形分布,因此我使用lmfit库进行拟合。注:我知道scipy.stats.triang可实现类似功能,但它要求x和c需在[0,1]区间内,且项目已大量使用lmfit,故选择此方案。
拟合代码
import numpy as np import matplotlib.pylab as plt import lmfit # 定义三角形分布函数 def triangular_pdf(x, amplitude, start, shape, end): model = np.zeros_like(x) # 初始化模型数组为0 mask1 = (x < start) | (x > end) mask2 = (x >= start) & (x < shape) mask3 = (x == shape) mask4 = (x >= shape) & (x < end) model[mask1] = 0 model[mask2] = 2*amplitude*(x[mask2]-start) / ((end-start)*(shape-start)) model[mask3] = 2*amplitude / (end - start) model[mask4] = 2*amplitude*(end-x[mask4]) / ((end-start)*(end-shape)) model = np.where((x>=start)&(x<=end), model, 0) return model model_triangular = lmfit.Model(triangular_pdf) params_init_triangular = model_triangular.make_params(amplitude={'value':y.max(), 'vary':True}, start={'value':x[0], 'vary':False}, end={'value':x[-1], 'vary':False}, shape={'value':(x[-1]+x[0])/2, 'max':x[-1], 'min':x[0]}) result = model_triangular.fit(y, params_init_triangular, x=x) #, nan_policy='propagate') params_opt = result.params print(result.fit_report()) x_samp = np.linspace(x.min(), x.max(), 300) y_samp_model = model_triangular.eval(params_opt, x=x_samp) plt.plot(x, y, 'o', label='points') plt.plot(x_samp, y_samp_model, '-', label='triang') plt.legend() plt.show()
异常拟合结果
运行上述代码后,得到如下拟合报告:
[[Model]] Model(triangular_pdf) [[Fit Statistics]] # fitting method = leastsq # function evals = 3 # data points = 14 # variables = 2 chi-square = 18.8851000 reduced chi-square = 1.57375833 Akaike info crit = 8.19042290 Bayesian info crit = 9.46853756 R-squared = -1.50895005 ## Warning: uncertainties could not be estimated: amplitude: at initial value shape: at initial value [[Variables]] amplitude: 2.80000000 (init = 2.8) start: 0 (fixed) shape: 195.000000 (init = 195) end: 390 (fixed)

可以看到拟合结果明显错误,且amplitude和shape参数完全未偏离初始值,未进行任何优化。
方法有效性验证
为确认triangular_pdf函数和lmfit模型本身的有效性,我做了如下测试:
x_test = np.linspace(0,400,50) y_test = triangular_pdf(x_test, 1000, 0, 100*np.random.rand(), 400) + np.random.rand(1,len(x_test))[0] result_test = model_triangular.fit(y_test, params_init_triangular, x=x_test)#, nan_policy='propagate') params_opt_test = result_test.params print(result_test.fit_report()) x_samp = np.linspace(x_test.min(), x_test.max(), 300) y_samp_model = model_triangular.eval(params_opt_test, x=x_samp) plt.plot(x_test, y_test, 'o', label='points') plt.plot(x_samp, y_samp_model, '-', label='triang') plt.legend() plt.show()
测试得到的拟合报告如下:
[[Model]] Model(triangular_pdf) [[Fit Statistics]] # fitting method = leastsq # function evals = 34 # data points = 50 # variables = 2 chi-square = 9.11427030 reduced chi-square = 0.18988063 Akaike info crit = -81.1090828 Bayesian info crit = -77.2850368 R-squared = 0.92041334 [[Variables]] amplitude: 1125.37941 +/- 21.3058857 (1.89%) (init = 2.8) start: 0 (fixed) shape: 92.1393307 +/- 3.07739313 (3.34%) (init = 195) end: 390 (fixed)

测试中参数正常迭代优化,拟合结果符合预期,说明方法本身是可行的。目前无法定位原始数据拟合失败的原因,恳请帮忙排查。
内容的提问来源于stack exchange,提问作者Abdulrahman Sheikho
相关产品推荐
相关产品推荐

