curve_fit无法估计一阶系统参数协方差,拟合效果差求助
一阶模型拟合报错:无法估计参数协方差且拟合效果差
我尝试拟合形式为y = A(1-exp(-t/tau))+A0的一阶模型,但curve_fit报错:
Covariance of the parameters could not be estimated
且拟合效果极差,怀疑是默认参数不够稳健,附上代码与数据:
原始数据
Time (s) Ads 1 Ads 2 Ads 3 Des 1 Des 2 Des 3 Des 4 0 0 18.979 18.979 18.979 19.034 19.042 19.026 19.028 1 30 18.997 18.993 18.993 19.023 19.019 19.015 NaN 2 45 19.004 18.997 19.000 19.021 19.018 19.012 NaN 3 60 19.009 19.003 19.007 19.020 19.012 19.012 19.011 4 75 19.013 19.007 19.012 19.019 19.011 19.010 19.009 5 90 19.016 19.010 19.015 19.018 19.009 19.009 19.008 6 300 19.022 19.022 19.028 NaN 18.990 18.989 18.990 7 600 NaN NaN NaN NaN 18.984 NaN NaN
拟合代码
time = df['Time (s)'] def first_order(t,A,tau=100,A0=1): t0 = t[0] y = A*(1-np.exp(-(t-t0)/tau))+A0 return y parameters, covariance = curve_fit(first_order, time, df["Des 2"]) plt.plot(time,df["Des 2"]) plt.plot(np.linspace(time[0],time[-1:],100),first_order(np.linspace(time[0],time[-1:],100),*parameters),'--')
当前拟合结果

问题根源
- 模型与数据趋势完全不匹配:
Des 2数据是单调下降的,但当前模型是单调递增至饱和的曲线,完全不符合数据规律,这是拟合失败的核心原因。 - 初始参数严重偏离实际:默认参数
A0=1和数据的y值范围(18.98-19.04)差距极大,导致拟合算法无法找到收敛方向。 - NaN值干扰:数据中存在缺失值,虽不直接报错,但会降低拟合稳定性。
修正方案
1. 调整模型为衰减形式
针对脱附过程的下降趋势,改用符合物理意义的衰减模型:
def first_order_decay(t, A_sat, tau, A0): t0 = t[0] # A0为初始值,A_sat为饱和基线值,tau为衰减时间常数 y = A_sat + (A0 - A_sat) * np.exp(-(t - t0)/tau) return y
2. 清理数据并设置合理初始参数
import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt # 清理NaN数据 mask = ~np.isnan(df["Des 2"]) time_clean = time[mask] des2_clean = df["Des 2"][mask] # 根据数据范围给出初始猜测:A_sat≈18.98,tau≈100,A0≈19.04 p0 = [18.98, 100, 19.04] parameters, covariance = curve_fit(first_order_decay, time_clean, des2_clean, p0=p0) # 提取拟合参数 A_sat_fit, tau_fit, A0_fit = parameters print(f"拟合参数:饱和基线A_sat={A_sat_fit:.4f},时间常数tau={tau_fit:.1f},初始值A0={A0_fit:.4f}")
3. 重新可视化拟合结果
plt.plot(time_clean, des2_clean, 'o', label='原始数据') t_fit = np.linspace(time_clean.min(), time_clean.max(), 100) plt.plot(t_fit, first_order_decay(t_fit, *parameters), '--', label='拟合曲线') plt.xlabel('Time (s)') plt.ylabel('Des 2') plt.legend() plt.show()
额外建议
- 如果仍出现协方差估计问题,可增加迭代次数:
curve_fit(..., maxfev=10000) - 若拟合仍不稳定,改用
scipy.optimize.least_squares,它对非凸优化问题的鲁棒性更强。
内容的提问来源于stack exchange,提问作者ZucchiniLord
相关产品推荐
相关产品推荐

