Python:scipy curve_fit高X值曲线拟合失效问题求助
指数函数拟合高X值数据失效的原因与解决方法
问题根源
当X值处于500-860这类大区间时,np.exp(-c*x)会快速趋近于0,引发两个核心问题:
- 函数对参数
c的敏感度极低,优化器无法通过微小参数调整获得有效残差变化,难以收敛到正确值 - 默认初始参数
[1,1,1]完全不符合高X数据的趋势,优化器极易陷入局部最优或无法收敛
同时,高X值带来的数值量级差异,也会导致拟合过程中的数值不稳定。
解决方案
1. 提供匹配数据趋势的初始参数猜测
根据你的高X数据特征:
- X越大,Y越趋近于最小值0.21,因此
a的初始值可设为0.2 - X最小时Y达到23.97,
b的初始值可设为23.97 - 0.2 = 23.77 c为正数,且因X量级大,c的取值需很小(比如0.001)
2. 对X数据进行缩放
将X值除以合适系数(如100),降低指数部分的数值量级,避免exp(-c*x)快速下溢为0,提升拟合稳定性。
改进后的代码
from scipy.optimize import curve_fit import matplotlib.pyplot as plt import numpy as np low_x_values = [3.139, 2.53, 0.821, 0.27] high_x_values = [859.8791936328762, 805.5080517453312, 639.2578427310567, 496.3622821767497] list_x = high_x_values list_y = [0.21, 0.49, 1.56, 23.97] def func_exp(x, a, b, c): return a + (b * np.exp(-c * x)) # 对X数据缩放,降低指数项量级 scaled_x = np.array(list_x) / 100 # 设置贴合数据趋势的初始参数 p0 = [0.2, 24, 0.1] list_line_info, pcov = curve_fit(func_exp, scaled_x, list_y, p0=p0, maxfev=100000) # 绘图时还原X的原始量级 plot_x = np.linspace(min(list_x), max(list_x), 1000) scaled_plot_x = plot_x / 100 plot_y = list_line_info[0] + list_line_info[1] * np.exp(-list_line_info[2] * scaled_plot_x) plt.plot(plot_x, plot_y, linestyle='-', color='orangered', label='拟合曲线') plt.plot(list_x, list_y, linestyle='--', color='dodgerblue', label='原始数据') plt.scatter(list_x, list_y, color='black', zorder=2) plt.grid() plt.legend() plt.show()
3. 可选:重新参数化模型
也可以直接修改模型,把c替换为k/100,省去手动缩放数据的步骤:
def func_exp_scaled(x, a, b, k): return a + (b * np.exp(-k * x / 100)) p0 = [0.2, 24, 0.1] list_line_info, pcov = curve_fit(func_exp_scaled, np.array(list_x), list_y, p0=p0, maxfev=100000)
效果验证
改进后,拟合曲线会贴合高X数据的趋势:X增大时Y趋近于0.2,X减小时Y快速上升至23.97,彻底解决原拟合失效的问题。
内容的提问来源于stack exchange,提问作者Fish1996
相关产品推荐
相关产品推荐

