R语言 nls(y~ alpha/(1 + exp(x-x 0)/beta)中的误差,:奇异梯度

lvjbypge  于 2024-01-03  发布在  其他
关注(0)|答案(1)|浏览(123)

我在R中使用nls时遇到以下错误。我想用sigmoid函数拟合我的数据。Y是从0.01到1,x是从0.1到-3。我使用的代码如下:

dummy_df <- data.frame(
  x = seq(0.1, -3, length.out = 50),
  y = seq(0.01, 1, length.out = 50)
)

  fit <- nls(y ~ alpha / (1 + exp(x - xO) / beta),data = dummy_df,
             start = list(alpha = 1.0009, beta = -10, xO = 0),
    control = nls.control(minFactor = 0.00001, maxiter = 10))

字符串
这导致以下误差:nls(y ~ alpha/(1 + exp(x-x 0)/beta)中的误差,

ar7v8xwq

ar7v8xwq1#

有几个问题:

**1)**参数不可识别,这就像要求ab求解a+b=1一样,必须修复其中一个。

我们可以把RHS写为

alpha / (1 + exp(x - xO) / beta)
= alpha / (1 + exp(x) * exp(-x0) / beta)

字符串
exp(-x 0)/beta实际上是一个参数,而不是两个。我们可以通过将betax0固定为任意值来解决这个问题。我们使用了nls 2“plinear-random”算法,该算法允许我们省略线性输入的起始值,这里是alpha,我们将beta设置为-1,以使参数可识别。基于算法,我们将RHS指定为矩阵,其列是非线性部分,而线性参数是乘以列的系数,nls 2的“plinear-random”算法在start描述的矩形内随机计算RHS,并给出最佳值。然后我们可以将其用作nls的起始值。

**2)**初始值不正确。使用如下所示的nls 2来解决这个问题。
**3)**模型没有很好地描述数据。一些图应该可以说服其中一个。

这里是代码;然而,如(3)中所提到的,尽管我们可以得到没有误差的结果,但我们不会得到将该模型拟合到该数据的好结果。

set.seed(123)

library(nls2)
set.seed(123)
beta <- -1

fit0 <- nls2(y ~ cbind(alpha = 1 / (1 + exp(x - x0) / beta)),
  data = dummy_df,
  start = data.frame(x0 = c(-20, 20)),
  algorithm = "plinear-random")

fit <- nls(y ~ cbind(alpha = 1 / (1 + exp((x - xO) / beta))),
  data = dummy_df, start = coef(fit0)[1], alg = "plinear")

公式不同

@Ben Bolker在评论中表示,也许你指的是公式。
如果是这种情况,则如果在所示的等效的更线性的参数化中重新表达,则将更容易拟合。

library(nls2)
set.seed(123)

fo2 <- y ~ cbind(alpha = 1/(1 + exp(xO.over.beta - one.over.beta * x)))

fit0 <- nls2(fo2, data = dummy_df,
  start = data.frame(one.over.beta = c(-5, 5), xO.over.beta = c(-5 -5)),
  algorithm = "plinear-random")

fit2 <- nls(fo2, data = dummy_df, 
  start = c(one.over.beta = coef(fit0)[[1]], xO.over.beta = coef(fit0)[[2]]),
  algorithm = "plinear")
fit2

alpha <- coef(fit2)[[3]]
beta <- 1/coef(fit2)[["one.over.beta"]]
xO <- beta * coef(fit2)[["xO.over.beta"]]


这样的话,我们就可以得到一个更合理的选择。

plot(y ~ x, dummy_df)
lines(fitted(fit2) ~ x, dummy_df, col = "red")


(图后续)x1c 0d1x
有了这个新模型@罗兰建议在评论中使用自启动模型SSlogis,它给出了相同的残差平方和,但系数略有不同。

nls(y ~ SSlogis(x, alpha, x0, beta), data = dummy_df)


还要注意的是,drc package有许多固定的增长曲线,它可以拟合而不需要初始值。例如,这使用了来自该软件包的5参数multi2模型。

library(drc)

fm <- drm(y ~ x, data = dummy_df, fct = multi2())

summary(fm)
sum(resid(fm)^2)  # residual sum of squares

更新

许多更新,包括修复一些错误和跟进问题下面的评论。

相关问题