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

R语言nls非线性拟合Matlab优化函数报singular gradient错误求助

R stat_smooth() nls拟合梯度奇异问题解决方案

报错核心原因

  • 初始值量级差过大:你设置的初始值k1=0.006999、k2=849.6相差6个数量级,计算k2-k1时会出现数值精度损失,且exp(-k2*x)在x≥1时直接下溢为0,导致参数求导的梯度矩阵奇异
  • 公式括号逻辑错误:你写的公式括号位置不符合双相指数增长模型的标准形式,模型逻辑和你Matlab中优化的目标函数不一致

修复方案

方案1:调整初始值+使用默认nls(无需额外安装包)

直接把k2的初始值下调到合理区间,修正公式括号即可运行,修改后代码如下:

library(tidyverse)
# 导入数据集
df <- tibble(
  x = c(1,3,5,10,20,30,40,50,60,90,120,180,240,360,1440),
  y = c(0.0342,0.0502,0.07,0.123,0.154,0.203,0.257,0.287,0.345,0.442,0.569,0.726,0.824,0.868,0.89),
  SEM = c(0.00532,0.00639,0.0118,0.0269,0.0125,0.019,0.0255,0.0266,0.0347,0.0398,0.057,0.0406,0.015,0.00821,0.0246)
)

df %>% 
  ggplot(aes(x, y)) +
  geom_point()+
  geom_errorbar(aes(ymin=y-SEM, ymax=y+SEM), width=25)+
  geom_ribbon(aes(ymin = y-2.575*SEM, ymax = y+2.575*SEM), alpha = 0.1)+
  geom_smooth(method="nls", 
              # 修正括号逻辑,匹配标准双相指数累积模型
              formula= y ~ 1 - (k2/(k2-k1)*exp(-k1*x) - k1/(k2-k1)*exp(-k2*x)),
              se=F,
              # 调整k2初始值到合理量级
              method.args = list(start=list(k1=0.006999, k2=0.08)))

方案2:使用更稳定的LM算法(推荐,抗初始值扰动能力更强)

如果初始值波动大,建议安装minpack.lm包,用Levenberg-Marquardt算法替代默认的高斯牛顿算法,彻底避免奇异梯度问题:

# 首次运行先安装依赖包:install.packages("minpack.lm")
library(minpack.lm)

df %>% 
  ggplot(aes(x, y)) +
  geom_point()+
  geom_errorbar(aes(ymin=y-SEM, ymax=y+SEM), width=25)+
  geom_ribbon(aes(ymin = y-2.575*SEM, ymax = y+2.575*SEM), alpha = 0.1)+
  geom_smooth(method="nlsLM", 
              formula= y ~ 1 - (k2/(k2-k1)*exp(-k1*x) - k1/(k2-k1)*exp(-k2*x)),
              se=F,
              method.args = list(start=list(k1=0.006999, k2=0.08)))

两种方案都可以正常拟合得到和Matlab优化结果一致的参数,拟合优度R²可达0.99以上。

内容的提问来源于stack exchange,提问作者David N.F.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:24:03