首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用R拟合Sigmoidal曲线

使用R拟合Sigmoidal曲线
EN

Stack Overflow用户
提问于 2015-10-09 16:11:47
回答 3查看 28.8K关注 0票数 12

我读过一篇文章(S型曲线拟合R )。它被标记为复制,但我看不到任何与帖子相关的内容。而对于这些帖子给出的答案是不够的。

我读了一篇webpage

与其他人类似,他使用以下格式来拟合这行代码:

代码语言:javascript
运行
复制
fitmodel <- nls(y~a/(1 + exp(-b * (x-c))), start=list(a=1,b=.5,c=25))

问题是,在大多数情况下,a,b,c都是给定的,我不知道应该将a,b,c中的哪一组用于我的数据集。有人能给我一些关于如何获得参数的建议吗?

这是我的一组数字:

代码语言:javascript
运行
复制
x <- c(3.9637878,3.486667,3.0095444,2.5324231,2.0553019,1.5781806,1.1010594,0.6242821)
y <- c(6491.314,6190.092,2664.021,2686.414,724.707,791.243,1809.586,541.243)
EN

回答 3

Stack Overflow用户

发布于 2015-10-09 17:25:23

幸运的是,R为逻辑模型提供了一个自启动模型。它使用了轻微的重新参数化,但实际上与您的模型相同:Asym/(1+exp((xmid-input)/scal))

自启动模型可以为您估计良好的起始值,因此您不必指定它们。

代码语言:javascript
运行
复制
plot(y ~ x)
fit <- nls(y ~ SSlogis(x, Asym, xmid, scal), data = data.frame(x, y))

summary(fit)
#Formula: y ~ SSlogis(x, Asym, xmid, scal)
#
#Parameters:
#      Estimate Std. Error t value Pr(>|t|)
#Asym 1.473e+04  2.309e+04   0.638    0.551
#xmid 4.094e+00  2.739e+00   1.495    0.195
#scal 9.487e-01  5.851e-01   1.622    0.166
#
#Residual standard error: 941.9 on 5 degrees of freedom
#
#Number of iterations to convergence: 0 
#Achieved convergence tolerance: 4.928e-06

lines(seq(0.5, 4, length.out = 100), 
      predict(fit, newdata = data.frame(x = seq(0.5, 4, length.out = 100))))

当然,您的数据并不真正支持该模型。估计的中点正好在数据范围的正确界限上,因此参数估计(特别是渐近线)是非常不确定的。

票数 8
EN

Stack Overflow用户

发布于 2017-06-01 20:39:04

我用来拟合你的数据的代码:

代码语言:javascript
运行
复制
 df <- data.frame(x=c(3.9637878,3.486667,3.0095444,2.5324231,2.0553019,1.5781806,1.1010594,0.6242821),                     
                  y=c(6491.314,6190.092,2664.021,2686.414,724.707,791.243,1809.586,541.243))

library(drc)
fm <- drm(y ~ x, data = df, fct = G.3())

plot(fm)
summary(fm)

拟合后的外观:

票数 3
EN

Stack Overflow用户

发布于 2015-10-09 17:34:01

我看到了两个问题。

  1. 是nls的默认算法,它对起始参数非常敏感。在您的示例数据中,我发现使用algorithm='port'很有用。或者,切换到“健壮”的实现也可能有所帮助。
  2. 它有助于理解参数在模型中的作用。

对你的模型的简单解释是: sigmoid在y中从0到a。它在x=c处到达“一半”点。b的作用是斜率,如果为负,模型将从a到0。

具体地说,对于您发布的测试数据,我估计起始值如下:

  • 我注意到的第一件事-你的数据并不是精确地‘接近’零,所以添加一个大约1000的偏移量d可能是有用的。
  • a是5000或更大,
  • c是大于2的某个地方-也许3
  • b你需要猜测-从x2到3.5你的信号从1000跳到6000会产生5000的差值-除以a-斜率1/1.5 = 0.66或更大...让我们四舍五入到一个。

所以最终使用这个公式

代码语言:javascript
运行
复制
fitmodel <- nls(y ~a/(1 + exp(-b * (x-c)) ) + d, start=list(a=5000,b=1,c=3, d=1000))

提供一个合适的(也可以在没有d的情况下工作)。尝试了一下,我发现设置algorithm='port'使得命令对起始值的敏感度更低。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33033176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档