scipy.curve_fit拟合指数曲线失败问题求助
指数曲线拟合问题的解决方法
你的问题核心是初始参数设置不合理,以及后续错误的边界限制,导致curve_fit收敛到了局部最优解,要么输出水平线,要么变成直线。
问题分析
你的指数模型是 a*exp(-b*x) + c,但x的取值是100、300这种较大的数:
- 默认初始参数
p0=[1,1,1]代入时,exp(-1*100)几乎为0,模型直接退化成常数c,拟合自然得到水平线。 - 你后来设置的边界
bounds=(0, [0.001,0.001,0.001])完全错误,a的合理值应该是十几(比如15 - c,c小于3.21),限制a最大0.001会直接把模型逼成直线。
解决步骤
给出合理的初始参数猜测
根据数据趋势:- x=100时y=15,x增大y递减,趋近于某个常数c(小于最小y值3.21)
- a ≈ 15 - c,比如取12
- b是很小的正数,比如0.001(因为x是几百的量级,b太大的话exp项会直接归零)
- c取2(小于3.21)
修正代码
给curve_fit传入p0参数,同时去掉错误的边界限制(如果需要限制,也要设置合理范围):
import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt sigma2 = [15, 8, 5.5, 3.21] def exp_fit(x, a, b, c): return a * np.exp(-b * x) + c x_data = np.asarray([100, 300, 500, 1000], dtype=np.float64) y_data = np.asarray(sigma2, dtype=np.float64) # 传入合理的初始参数猜测 param_exp, _ = curve_fit(exp_fit, x_data, y_data, p0=[12, 0.001, 2]) x_test = np.arange(100, 1100, 100) # 预测x=800的值 x_800 = 800 y_800 = exp_fit(x_800, *param_exp) print(f"x=800时的预测值:{y_800:.3f}") plt.plot(x_data, y_data, 'bo', label='原始数据') plt.plot(x_test, exp_fit(x_test, *param_exp), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(param_exp)) plt.legend() plt.show()
运行结果
拟合出来的参数大概是a≈12.5,b≈0.001,c≈2.5,x=800时的预测值大概在3.8左右(具体数值会因拟合精度略有浮动),拟合曲线会贴合原始数据的递减趋势,不再是水平线或直线。
内容的提问来源于stack exchange,提问作者Belleroph0N
相关产品推荐
相关产品推荐

