将自起始值添加到 R 中的 nls 回归
Adding self starting values to an nls regression in R
我有现成的代码用于将 S 型曲线拟合到 R 中的数据。如何使用 selfstart(或其他方法)自动找到回归的起始值?
sigmoid = function(params, x) {
params[1] / (1 + exp(-params[2] * (x - params[3])))
}
dataset = data.frame("x" = 1:53, "y" =c(0,0,0,0,0,0,0,0,0,0,0,0,0,0.1,0.18,0.18,0.18,0.33,0.33,0.33,0.33,0.41,0.41,0.41,0.41,0.41,0.41,0.5,0.5,0.5,0.5,0.68,0.58,0.58,0.68,0.83,0.83,0.83,0.74,0.74,0.74,0.83,0.83,0.9,0.9,0.9,1,1,1,1,1,1,1) )
x = dataset$x
y = dataset$y
# fitting code
fitmodel <- nls(y~a/(1 + exp(-b * (x-c))), start=list(a=1,b=.5,c=25))
# visualization code
# get the coefficients using the coef function
params=coef(fitmodel)
y2 <- sigmoid(params,x)
plot(y2,type="l")
points(y)
这是非线性曲线拟合中常见(且有趣)的问题。
背景
如果我们仔细观察函数 sigmoid
,我们可以找到合理的起始值
我们首先注意到
因此对于较大的 x
值,函数接近 a
。换句话说,作为 a
的起始值,我们可以选择 y
的值作为 x
的 最大 值。
在 R 语言中,这转换为 y[which.max(x)]
。
现在我们有了 a
的起始值,我们需要确定 b
和 c
的起始值。为此,我们可以利用几何级数
并通过仅保留前两项来扩展 f(x) = y
我们现在设置a = 1
(我们的初始值a
),重新排列方程并在两边取对数
我们现在可以拟合 log(1 - y) ~ x
形式的线性模型以获得斜率和偏移量的估计值,这反过来又提供了 b
和 c
的起始值。
R 实现
让我们定义一个函数,它将值 x
和 y
和 returns 作为参数起始值的 list
start_val_sigmoid <- function(x, y) {
fit <- lm(log(y[which.max(x)] - y + 1e-6) ~ x)
list(
a = y[which.max(x)],
b = unname(-coef(fit)[2]),
c = unname(-coef(fit)[1] / coef(fit)[2]))
}
根据您提供的 x
和 y
的数据,我们得到以下起始值
start_val_sigmoid(x, y)
#$a
#[1] 1
#
#$b
#[1] 0.2027444
#
#$c
#[1] 15.01613
因为start_val_sigmoid
returns一个list
我们可以直接使用它的输出作为nls
中的start
参数
nls(y ~ a / ( 1 + exp(-b * (x - c))), start = start_val_sigmoid(x, y))
#Nonlinear regression model
# model: y ~ a/(1 + exp(-b * (x - c)))
# data: parent.frame()
# a b c
# 1.0395 0.1254 29.1725
# residual sum-of-squares: 0.2119
#
#Number of iterations to convergence: 9
#Achieved convergence tolerance: 9.373e-06
示例数据
dataset = data.frame("x" = 1:53, "y" =c(0,0,0,0,0,0,0,0,0,0,0,0,0,0.1,0.18,0.18,0.18,0.33,0.33,0.33,0.33,0.41,0.41,0.41,0.41,0.41,0.41,0.5,0.5,0.5,0.5,0.68,0.58,0.58,0.68,0.83,0.83,0.83,0.74,0.74,0.74,0.83,0.83,0.9,0.9,0.9,1,1,1,1,1,1,1) )
x = dataset$x
y = dataset$y
我有现成的代码用于将 S 型曲线拟合到 R 中的数据。如何使用 selfstart(或其他方法)自动找到回归的起始值?
sigmoid = function(params, x) {
params[1] / (1 + exp(-params[2] * (x - params[3])))
}
dataset = data.frame("x" = 1:53, "y" =c(0,0,0,0,0,0,0,0,0,0,0,0,0,0.1,0.18,0.18,0.18,0.33,0.33,0.33,0.33,0.41,0.41,0.41,0.41,0.41,0.41,0.5,0.5,0.5,0.5,0.68,0.58,0.58,0.68,0.83,0.83,0.83,0.74,0.74,0.74,0.83,0.83,0.9,0.9,0.9,1,1,1,1,1,1,1) )
x = dataset$x
y = dataset$y
# fitting code
fitmodel <- nls(y~a/(1 + exp(-b * (x-c))), start=list(a=1,b=.5,c=25))
# visualization code
# get the coefficients using the coef function
params=coef(fitmodel)
y2 <- sigmoid(params,x)
plot(y2,type="l")
points(y)
这是非线性曲线拟合中常见(且有趣)的问题。
背景
如果我们仔细观察函数 sigmoid
我们首先注意到
因此对于较大的 x
值,函数接近 a
。换句话说,作为 a
的起始值,我们可以选择 y
的值作为 x
的 最大 值。
在 R 语言中,这转换为 y[which.max(x)]
。
现在我们有了 a
的起始值,我们需要确定 b
和 c
的起始值。为此,我们可以利用几何级数
并通过仅保留前两项来扩展 f(x) = y
我们现在设置a = 1
(我们的初始值a
),重新排列方程并在两边取对数
我们现在可以拟合 log(1 - y) ~ x
形式的线性模型以获得斜率和偏移量的估计值,这反过来又提供了 b
和 c
的起始值。
R 实现
让我们定义一个函数,它将值 x
和 y
和 returns 作为参数起始值的 list
start_val_sigmoid <- function(x, y) {
fit <- lm(log(y[which.max(x)] - y + 1e-6) ~ x)
list(
a = y[which.max(x)],
b = unname(-coef(fit)[2]),
c = unname(-coef(fit)[1] / coef(fit)[2]))
}
根据您提供的 x
和 y
的数据,我们得到以下起始值
start_val_sigmoid(x, y)
#$a
#[1] 1
#
#$b
#[1] 0.2027444
#
#$c
#[1] 15.01613
因为start_val_sigmoid
returns一个list
我们可以直接使用它的输出作为nls
start
参数
nls(y ~ a / ( 1 + exp(-b * (x - c))), start = start_val_sigmoid(x, y))
#Nonlinear regression model
# model: y ~ a/(1 + exp(-b * (x - c)))
# data: parent.frame()
# a b c
# 1.0395 0.1254 29.1725
# residual sum-of-squares: 0.2119
#
#Number of iterations to convergence: 9
#Achieved convergence tolerance: 9.373e-06
示例数据
dataset = data.frame("x" = 1:53, "y" =c(0,0,0,0,0,0,0,0,0,0,0,0,0,0.1,0.18,0.18,0.18,0.33,0.33,0.33,0.33,0.41,0.41,0.41,0.41,0.41,0.41,0.5,0.5,0.5,0.5,0.68,0.58,0.58,0.68,0.83,0.83,0.83,0.74,0.74,0.74,0.83,0.83,0.9,0.9,0.9,1,1,1,1,1,1,1) )
x = dataset$x
y = dataset$y