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

nls()与nls2()拟合结果差异排查:我的配置哪里出错了?

问题:nls2暴力拟合无法复刻nls结果的原因及解决办法

我希望在nls()拟合有效的情况下,用nls2()的暴力拟合方法复刻其拟合结果,作为nls()失效时的备选方案。但目前nls2()的输出结果完全不符合预期,请问我的配置哪里出错了?是不是网格值设置的问题?


nls()拟合输出

Formula: y ~ C0 * exp(-lambda1 * x) + C1 * exp(-lambda2 * x)

Parameters:
                            Estimate Std. Error t value Pr(>|t|)   
C0.intercept_initial       -0.108025   0.012703  -8.504  0.00105 **
lambda1.log_slope_initial   0.438553   0.072185   6.075  0.00371 **
C1.intercept_terminal       0.107742   0.012531   8.598  0.00101 **
lambda2.log_slope_terminal  0.057911   0.008045   7.199  0.00197 **

nls2()拟合输出

Formula: y ~ C0 * exp(-lambda1 * x) + C1 * exp(-lambda2 * x)

Parameters:
          Estimate Std. Error t value Pr(>|t|)
C0       1.000e+01  2.043e+14       0        1
C1      -1.000e+01  5.285e+11       0        1
lambda1  0.000e+00  2.043e+14       0        1
lambda2  0.000e+00  5.285e+11       0        1

相关代码

# Data
dat <-  data.frame(x = c(0,2,4,8,12,24,48,72), y = c(0.000,0.05,0.0671,0.068,0.05,0.0250,0.0103,0.0043))

# Get initial parameters from SSbiexp
params <-  getInitial(y ~ SSbiexp(x, intercept_initial, log_slope_initial, intercept_terminal, log_slope_terminal), data = dat)
# Fit nls model
nls_mod_bi <-  nls(y ~ C0*exp(-lambda1*x) + C1*exp(-lambda2*x), start = list(C0 = params[1], lambda1 = exp(params[2]), C1 = params[3], lambda2 = exp(params[4])), data = dat)
summary(nls_mod_bi)
xNew <- seq(0, 240, length.out = 100) # new grid of times
yNew <- predict(nls_mod_bi, list(x = xNew)) # predict activity
dfNew <-  data.frame(x = xNew, y = yNew)
dfNew <-  dfNew |> slice(-1) # remove first row which contains -ve prediction for time 0
ggplot(dfNew, aes(x = x, y = y)) +
  geom_line() +
  geom_point(data = dat, aes(x = x, y = y), size = 3) +
  xlab("x") + ylab("y") +
  theme_bw(base_size = 20)

# Now fit nls2 model by brute-force
fo <- y ~ C0*exp(-lambda1*x) + C1*exp(-lambda2*x)
grd <- data.frame(C0      = c(-10, 10),
                  C1      = c(-10, 10),
                  lambda1 = c(0, 1),
                  lambda2 = c(0, 1))
nls_mod_bi2 <- nls2(fo,
                    data = dat,
                    start = grd,
                    algorithm = "brute-force")
summary(nls_mod_bi2)

问题原因与解决办法

你的问题核心确实是网格设置的问题,具体有两点:

  1. 网格采样点过少:你设置的grd仅提供了每个参数的上下限,nls2的brute-force算法只会生成4个顶点的组合(每个参数取上下限),而真实最优参数不在这些顶点中,自然无法找到正确解。
  2. 网格范围与真实参数空间不匹配:C0、C1的最优值在-0.2到0.2之间,但你设置的范围是-10到10,过宽的范围导致搜索顶点完全偏离真实参数区间。

修正方案1:基于nls结果缩小网格并增加采样点

利用已知的nls最优参数,将网格范围缩小到参数附近,并生成足够多的采样点:

# 提取nls的最优参数
nls_params <- coef(nls_mod_bi)
# 生成每个参数在最优值±50%范围内的10个采样点组合
grd <- expand.grid(
  C0 = seq(nls_params["C0"]*0.5, nls_params["C0"]*1.5, length.out = 10),
  C1 = seq(nls_params["C1"]*0.5, nls_params["C1"]*1.5, length.out = 10),
  lambda1 = seq(nls_params["lambda1"]*0.5, nls_params["lambda1"]*1.5, length.out = 10),
  lambda2 = seq(nls_params["lambda2"]*0.5, nls_params["lambda2"]*1.5, length.out = 10)
)
# 重新拟合nls2
nls_mod_bi2 <- nls2(fo, data = dat, start = grd, algorithm = "brute-force")
summary(nls_mod_bi2)

修正方案2:nls失效时的分阶段搜索

如果nls无法拟合(无参考参数),可以先设置合理的初始宽网格找到近似解,再缩小范围二次搜索:

# 第一阶段:初始宽网格(基于数据特征设置)
grd1 <- expand.grid(
  C0 = seq(-0.5, 0.5, length.out = 5),
  C1 = seq(-0.5, 0.5, length.out = 5),
  lambda1 = seq(0.1, 0.8, length.out = 5),
  lambda2 = seq(0.01, 0.1, length.out = 5)
)
nls_mod_bi2_stage1 <- nls2(fo, data = dat, start = grd1, algorithm = "brute-force")

# 第二阶段:基于第一阶段结果缩小网格
stage1_params <- coef(nls_mod_bi2_stage1)
grd2 <- expand.grid(
  C0 = seq(stage1_params["C0"]*0.8, stage1_params["C0"]*1.2, length.out = 10),
  C1 = seq(stage1_params["C1"]*0.8, stage1_params["C1"]*1.2, length.out = 10),
  lambda1 = seq(stage1_params["lambda1"]*0.8, stage1_params["lambda1"]*1.2, length.out = 10),
  lambda2 = seq(stage1_params["lambda2"]*0.8, stage1_params["lambda2"]*1.2, length.out = 10)
)
nls_mod_bi2_stage2 <- nls2(fo, data = dat, start = grd2, algorithm = "brute-force")
summary(nls_mod_bi2_stage2)

修正后,nls2的参数估计会与nls结果基本一致,拟合效果匹配预期。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 00:17:36