You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Scipy curve_fit拟合曲线时为何得到负参数值?

曲线拟合得到无意义负参数的问题分析

我用Scipy的optimize.curve_fit对散点数据做曲线拟合时,得到了无意义的负bX参数值,代码及运行结果如下:

import numpy as np
from scipy.optimize import curve_fit

# 定义线性二次模型(用于生成数据)
def linq(x, aparam, bparam):
    return np.exp(-(aparam*x + bparam*x**2))

# 待拟合的新模型
NX = 46
def abX(x, aXparam, bXparam):
    return np.exp(-(aXparam + bXparam)*x) * (1 + bXparam*x/NX)**NX

# 存储拟合结果的数组
avalues = []
davalues = []
bvalues = []
dbvalues = []
Chi2 = []

# 数据生成参数
Dmax = 10.
a1 = 0.740; b1 = .1100
# 模拟次数
Nensemble = 10

for iexp in range(1, Nensemble+1):
    # 生成带噪声的人工数据集
    nobs = int(Dmax + .5)
    x = np.arange(.5, nobs)
    N = linq(x, a1, b1)
    Nfluct = 0.3*N*np.random.normal(size=nobs)
    N = N + Nfluct
    sig = np.zeros(nobs) + 0.3*N
    
    # 执行曲线拟合
    start = (0, 1.)
    popt, pcov = curve_fit(abX, x, N, sigma=sig, p0=start, absolute_sigma=True)
  
    # 存储拟合结果
    avalues.append(popt[0])
    bvalues.append(popt[1])
    davalues.append(np.sqrt(pcov[0,0]))
    dbvalues.append(np.sqrt(pcov[1,1]))

# 输出统计结果
print("mean aX value =", np.mean(avalues), "+/-", np.std(avalues)/np.sqrt(Nensemble-1), ", gen =", a1) 
print("mean bX value =", np.mean(bvalues), "+/-", np.std(bvalues)/np.sqrt(Nensemble-1), ", gen =", b1)

运行结果:

mean aX value = 0.9829722097543518 +/- 0.019840535134131847 , gen = 0.74
mean bX value = -2.3048945875855527 +/- 0.024140253716692855 , gen = 0.11

问题原因

  1. 模型严重不匹配:生成数据用的是包含线性+二次项的指数衰减模型,但拟合时用的abX模型,当NX较大时近似于单指数衰减模型,完全无法匹配原数据的二次衰减趋势。拟合算法只能通过将bX设为负值,强行扭曲模型形态来贴近数据。
  2. 初始值设置不合理:拟合初始值(0,1.)和真实参数(0.74, 0.11)偏差过大,导致拟合过程容易陷入局部最优解,无法收敛到合理参数。
  3. 参数相关性过高:abX模型中,aXparam + bXparam作为整体出现在指数项,同时bXparam单独出现在幂次项,两个参数高度耦合,协方差矩阵不稳定,导致拟合结果失真。

解决办法

  1. 匹配数据与拟合模型:要么改用生成数据的linq模型进行拟合,要么调整数据生成逻辑使用abX模型,保证模型和数据的一致性:
    # 使用linq模型拟合,匹配数据生成逻辑
    popt, pcov = curve_fit(linq, x, N, sigma=sig, p0=(a1, b1), absolute_sigma=True)
    
  2. 优化初始值:将拟合初始值设为接近真实参数的值,比如p0=(a1, b1),帮助算法更快收敛到合理解。
  3. 添加参数约束:如果业务逻辑中bX必须为正,用bounds参数限制参数范围,强制bX非负:
    popt, pcov = curve_fit(abX, x, N, sigma=sig, p0=(a1, b1), bounds=((0, 0), (np.inf, np.inf)), absolute_sigma=True)
    
  4. 重新评估模型合理性:如果必须使用abX模型,需要验证该模型是否适配当前数据趋势,或重新推导模型形式以消除参数耦合问题。

内容的提问来源于stack exchange,提问作者yusra zabarmawi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:35:59