R语言中拟合衰减曲线时如何设置趋近于0的渐近线?
R语言中拟合衰减曲线时如何设置趋近于0的渐近线?
我太懂你这种感受了——本来想拟合一条乖乖趋近0的衰减曲线,结果用自带的SSmicem、SSsymp这些自启动模型跑出来,尾部居然比观测值还高,完全偏离预期,属实有点头疼!
其实解决思路很明确:要么直接用天生渐近线为0的模型,要么给现有模型加约束强制渐近线固定为0。下面给你几个实用的方案:
方案1:自定义强制渐近线为0的指数衰减模型(最直接)
指数衰减模型y = a * exp(-b*x)天生就会随着x增大趋近于0,完全符合你的需求,而且拟合起来也简单。假设你的数据框是df,包含distance(距离)和value(响应值)两列,具体步骤如下:
# 先可视化数据,确认趋势 plot(value ~ distance, data = df, pch = 16, col = "steelblue") # 用nls拟合模型,给合理的初始值 # a的初始值设为数据的最大值(因为x=0时y≈a),b给个小正数就行 fit_exp <- nls(value ~ a * exp(-b * distance), data = df, start = list(a = max(df$value), b = 0.1)) # 查看拟合结果细节 summary(fit_exp) # 把拟合曲线画到图上看看 x_seq <- seq(min(df$distance), max(df$distance), length.out = 100) lines(x_seq, predict(fit_exp, newdata = list(distance = x_seq)), col = "red", lwd = 2)
这个模型的逻辑很直观:当distance不断增大时,exp(-b*distance)会无限趋近于0,所以value自然就趋向0,完美解决你尾部飘高的问题。
方案2:给自启动模型加约束,强制渐近线为0
如果你习惯用R自带的自启动模型,比如SSasymp(原本是拟合到某个渐近值的模型),可以直接固定渐近参数为0,改造后也能满足需求。这里推荐用minpack.lm包的nlsLM函数,它比基础的nls更不容易收敛失败:
# 先安装加载包(如果没装过的话) # install.packages("minpack.lm") library(minpack.lm) # 改造SSasymp模型,固定渐近线Asym=0 fit_constrained <- nlsLM(value ~ 0 + (R0 - 0)*exp(-lrc*distance), data = df, start = list(R0 = max(df$value), lrc = 0.1)) # 查看结果并绘图 summary(fit_constrained) lines(x_seq, predict(fit_constrained, newdata = list(distance = x_seq)), col = "green", lwd = 2, lty = 2)
小提示
- 初始值很关键:
nls类的函数对初始值比较敏感,a(或R0)选数据的最大值、b(或lrc)选0.1~0.5之间的小正数,基本都能顺利收敛。 - 如果你的数据衰减趋势不是简单的指数型,也可以扩展模型,比如双指数衰减
y ~ a*exp(-b*x) + c*exp(-d*x)——只要所有指数项都随x增大趋向0,整个模型的渐近线就还是0。 - 要是数据噪声大,尾部有异常值,可以试试
robustbase包的nlrob做稳健拟合,减少异常值的干扰。
备注:内容来源于stack exchange,提问作者ChrisJ
相关产品推荐
相关产品推荐

