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

LMFIT如何实现仅输出正值的最优拟合?

强制拟合结果始终为正值的实现方法

我希望强制最优拟合结果始终为正值,当前使用lmfit的代码如下:

from lmfit.models import ExpressionModel
from lmfit.models import StepModel

step_mod = StepModel(form='linear', prefix='step_')

gmod = ExpressionModel("1-exp_amp*exp(-x/exp_decay)")

mod =  gmod*step_mod
pars = gmod.make_params(exp_amp=1, exp_decay=30)
pars += step_mod.guess(y, x=x, amplitude=1,center=23,sigma=0)

out = mod.fit(y, pars, x=x)

print(out.fit_report())

plt.plot(x, y,'o')
# plt.plot(x, out.init_fit, '--', label='initial fit')
plt.plot(x, out.best_fit, '-', label='best fit')
plt.legend()
plt.show()

当前拟合结果:

[[Model]]
(Model(_eval) * Model(step, prefix='step_', form='linear'))
[[Fit Statistics]]
# fitting method   = leastsq
# function evals   = 37
# data points      = 370
# variables        = 5
chi-square         = 2.53597470
reduced chi-square = 0.00694788
Akaike info crit   = -1833.68223
Bayesian info crit = -1814.11472
##  Warning: uncertainties could not be estimated:
step_center:     at initial value
step_sigma:      at boundary
[[Variables]]
exp_amp:         1.80889259 (init = 1)
exp_decay:       40.0313587 (init = 30)
step_amplitude:  1.02997887 (init = 1)
step_center:     23.0000000 (init = 23)
step_sigma:      0.00000000 (init = 0)

当前拟合存在两个问题:一是拟合不够理想(比如step_center和step_sigma始终停留在初始值);二是手动调整阶跃函数的center后,拟合结果出现负值。请问如何实现仅输出正值的拟合结果?


解决方案

要实现拟合结果始终为正,同时解决参数拟合停滞的问题,可以从以下几个方面入手:

1. 给参数设置物理约束

lmfit支持通过min和max给参数设置取值范围,确保关键参数为正,同时避免边界值导致拟合停滞:

# 给指数模型参数设置下限,避免出现负值或除以0
pars['exp_amp'].min = 0
pars['exp_decay'].min = 1e-6

# 给阶跃模型参数设置合理范围,sigma避免设为0
pars['step_amplitude'].min = 0
pars['step_sigma'].min = 1e-6
pars['step_center'].min = x.min()
pars['step_center'].max = x.max()

2. 修改表达式模型确保输出为正

原表达式1-exp_amp*exp(-x/exp_decay)可能在某些x取值下出现负值,可通过max函数强制结果非负:

gmod = ExpressionModel("max(0, 1-exp_amp*exp(-x/exp_decay))")

3. 调整初始参数与拟合方法

  • 不要将step_sigma初始值设为0,给一个小的正值(比如sigma=1),让拟合器有调整空间;
  • 若leastsq方法陷入局部最优,可尝试使用鲁棒性更强的拟合方法,比如nelder或differential_evolution:
out = mod.fit(y, pars, x=x, method='nelder')

4. 合并模型逻辑(可选)

如果阶跃函数的作用是控制指数项的生效区间,可将逻辑整合到表达式模型中,减少参数数量,提升拟合稳定性:

# 整合阶跃与指数模型,直接用条件判断控制激活区间
gmod = ExpressionModel("max(0, (1-exp_amp*exp(-x/exp_decay)) * (x >= step_center))")
pars = gmod.make_params(exp_amp=1, exp_decay=30, step_center=23)
pars['step_center'].min = x.min()
pars['step_center'].max = x.max()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 02:20:33