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

huangapple go评论63阅读模式
英文:

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

问题

I have a dataset of 10 subjects, whose muscle response amplitude was measured across 11 different stimulus intensities (states) applied to their muscles. The output curve of the data looks like a sigmoidal function, with different stimulus intensities on the x-axis and resultant muscle amplitude outputs on the y-axis.

I would like to fit a Boltzmann sigmoid function to fit each subject's data. From the literature in my field, I would need to estimate my parameters of interest (i.e., slope, S50, and plateau from the function below) using a non-linear least squares fitting using R (typical once used is a Marquardt-Levenberg algorithm for least squares convergence).

From what I could find, I believe the Boltzmann function should look like:

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

Example data for one subject:

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)

This post has someone outline how they do this with the "nls" package: link

So I would have something like:

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

However, I'm still a little lost. How do I know what parameters to feed into the equation (which I think would go in the [???] section)? Do I need to specify plateau, S50, and slope? Isn't the whole point that I don't know these going in?

Is there a way to feed my data into some function to then get an output of the best non-linear equation that fits my data and gives me those S50, plateau, and slope parameters? Am I misunderstanding the process?

There is apparently a "gslnls" package available in R that uses the Marquardt-Levenberg algorithm to fit the data. I guess I am a little confused as to how to apply it, or if there is a simpler way to do this.

Any guidance would be greatly appreciated.

英文:

I have a dataset of 10 subjects, whose muscle response amplitude was measured across 11 different stimulus intensities (states) applied to their muscles. The output curve of the data looks like a sigmoidal function, with different stimulus intensities on the x-axis and resultant muscle amplitude outputs on the y-axis.

I would like to fit a Boltzmann sigmoid function to fit each subject's data. From the literature in my field, I would need to estimate my parameters of interest (i.e., slope, S50, and plateau from the function below) using a non-linear least squares fitting using R (typical once used is a Marquardt-Levenberg algorithm for least squares convergence).

From what I could find, I believe the Boltzmann function should look like:

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

Example data for one subject:

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)

Giving:

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

This post has someone outline how they do this with the "nls" package: https://stackoverflow.com/questions/60800267/working-with-nls-function-produces-a-singular-gradient/60800647#60800647

So I would have something like:

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

However, I'm still a little lost. How do I know what parameters to feed into the equation (which I think would go in the [???] section)? Do I need to specify plateau, S50, and slope? Isn't the whole point that I don't know these going in?

Is there a way to feed my data into some function to then get an output of the best non-linear equation that fits my data and gives me those S50, plateau, and slope parameters? Am I misunderstanding the process?

There is apparently a "gslnls" package available in R that uses the Marquardt-Levenberg algorithm to fit the data. I guess I am a little confused as to how to apply it, or if there is a simpler way to do this.

Any guidance would be greatly appreciated.

答案1

得分: 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 = 0.5), trace = TRUE)
英文:

What goes inside the [???] are the initial guesses for the starting values for your three parameters. R and nls() does not know how your function behaves nor where are feasible solutions exist thus thus it needs some help on where to start looking. I recommend adding the trace=TRUE option to function to see where is it looking for the solution. Sometimes this takes some trial and error to get right!

Singular gradient error usually means one is entering an undefined region of the solution space, i.e. a value is going to infinity, square root of a negative number, the function is over defined with the number of adjustable parameters, etc.

Starting with the slope <1 seems to work.

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 &lt;- nls(y ~ plateau / (1 + exp((S50 - x)/slope)), start = list( plateau=1, S50=1, slope=.5), trace = TRUE)

huangapple
  • 本文由 发表于 2023年8月5日 02:59:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838552.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定