将数据拟合到玻尔兹曼 sigmoid 函数,并使用 R 中的非线性最小二乘拟合估计参数

Fitting data to a Boltzmann sigmoid function, and estimating parameters with a non-linear least squares fitting in R

提问人:A.R. 提问时间:8/5/2023 更新时间:8/5/2023 访问量:103

问:

我有一个包含 10 名受试者的数据集,他们的肌肉反应幅度是在施加到肌肉的 11 种不同刺激强度(状态)下测量的。数据的输出曲线看起来像一个 S 形函数,在 x 轴上具有不同的刺激强度,在 y 轴上产生肌肉振幅输出。

我想拟合玻尔兹曼 sigmoid 函数来拟合每个受试者的数据。从我所在领域的文献来看,我需要使用 R 的非线性最小二乘拟合来估计我感兴趣的参数(即斜率、S50 和来自以下函数的平台)(典型的一次使用是用于最小二乘收敛的 Marquardt-Levenberg 算法)。

据我所知,我认为玻尔兹曼函数应该如下所示:

y(x) = plateau / [1 + e^((S50-x)/slope)]

Plateau = maximum amplitude
S50 = stimulus intensity x required to evoke a response equal to half the maximum amplitude

一个主题的示例数据:

y = c(0.04, 0.053, 0.096, 0.219, 0.701, 1.333, 3.032, 3.556,4.33, 4.27, 4.167)
x = c(1,2,3,4,5,6,7,8,9,10,11)

给:

enter image description here

这篇文章有人概述了他们如何使用“nls”包来做到这一点: 使用 nls 函数会产生奇异梯度

所以我会有这样的东西:

fit <- nls(y ~ plateau / (1 + exp((S50 - x)/slope), start = list( ??? ))

但是,我还是有点迷茫。我怎么知道要输入哪些参数到等式中(我认为这会在 [???] 部分)?我需要指定 plateau、S50 和 slope 吗?我不知道这些不是重点吗?

有没有办法将我的数据输入到某个函数中,然后获得适合我的数据的最佳非线性方程的输出,并为我提供 S50、平台和斜率参数?我是否误解了这个过程?

显然,R 中有一个“gslnls”包,它使用 Marquardt-Levenberg 算法来拟合数据。我想我对如何应用它有点困惑,或者是否有更简单的方法可以做到这一点。

任何指导将不胜感激。

R 回归 NLS 非线性函数

评论


答:

1赞 Dave2e 8/5/2023 #1

[???] 中的内容是对三个参数的起始值的初步猜测。R 并且不知道您的函数如何表现,也不知道哪里存在可行的解决方案,因此它需要一些帮助来了解从哪里开始寻找。我建议将选项添加到功能中,以查看它在哪里寻找解决方案。有时,这需要一些反复试验才能正确!nls()trace=TRUE

奇异梯度误差通常意味着人们正在进入解空间的未定义区域,即一个值走向无穷大,一个负数的平方根,函数被可调参数的数量过度定义,等等。

从斜率 <1 开始似乎有效。

y = c(0.04, 0.053, 0.096, 0.219, 0.701, 1.333, 3.032, 3.556,4.33, 4.27, 4.167)
x = c(1,2,3,4,5,6,7,8,9,10,11)
fit <- nls(y ~ plateau / (1 + exp((S50 - x)/slope)), start = list( plateau=1, S50=1, slope=.5), trace = TRUE)

评论

0赞 A.R. 8/5/2023
谢谢!刚刚尝试使用 ## fit2 <- nls(y ~ SSlogis(x, plateau, S50, slope)) ## 并获得与仅使用带有起始值的 nls 函数相同的 plateau、slope 和 S50 输出。有理由使用一个而不是另一个吗?SSlogis 似乎消除了猜测,但不确定是否存在一个比另一个效果更好的情况(至少在遵循玻尔兹曼函数的情况下)。另外,您是否碰巧知道 nls 函数是否使用 Marquardt-Levenberg 算法进行最小二乘收敛?
1赞 Dave2e 8/5/2023
我认为 since 是通用的,可以适合任何模型,所以它只是人们使用的首选。我假设既然有这个特定的函数来求解逻辑方程,它可能是更好的选择。我不担心找到一个当地的mininium,所以起点并不那么重要。从文档中,使用高斯-牛顿算法,但可以选择使用其他算法。nls()SSlogis()nls()