nls系数的约束

时间:2017-02-20 07:18:09

标签: r nls

我试图使用nls()函数拟合数据,其中数据的性质给出了一个系数和两个系数之和的界限。让我举一个简短的例子来看问题在哪里。我希望参数b1介于0和1之间,我希望参数b1和b2的总和也在0和1之间。

set.seed(123)

# example where everything is OK
x <- 1:200
g <- rbinom(200, 1, 0.5)
y <- 3 + (0.7 + 0.2 * g) * x 
yeps <- y + rnorm(length(y), sd = 0.1)  

# both parameter b1 and sum of parameters b1 and b2 are between 0 and 1
nls(yeps ~ a + (b1 + b2 * g) * x, start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213))

# using more extreme values
x <- 1:200
g <- rbinom(200, 1, 0.5)
y <- 3 + (0.9 - 0.99 * g) * x 
yeps <- y + rnorm(length(y), sd = 15) 

# b1 is OK, but b1 + b2 < 0
nls(yeps ~ a + (b1 + b2 * g) * x, 
    start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213))

# trying constraints, not good, sum is still out of range
nls(yeps ~ a + (b1 + b2 * g) * x, 
    start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213),
    lower = list(a = -Inf, b1 = 0, b2 = -1),
    upper = list(a = Inf, b1 = 1, b2 = 1),
    algorithm = "port")

我正在寻找的是类似的东西(不起作用):

nls(yeps ~ a + (b1 + b2 * g) * x, 
    start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213),
    lower = list(a = -Inf, b1 = 0, b2 = -b1),
    upper = list(a = Inf, b1 = 1, b2 = 1 - b1),
    algorithm = "port")

是否可以在nls()函数中使用其他参数设置约束?谢谢你的任何建议!

1 个答案:

答案 0 :(得分:2)

设B2 = b1 + b2所以b2 = B2-b1并且用B2-b1代替b2我们在a,b1和B2方面遇到问题,其中后两者在0和1之间,所以:

fm <- nls(yeps ~ a + (b1 + (B2-b1) * g) * x, lower = c(-Inf, 0, 0), upper = c(Inf, 1, 1),
    start = list(a = 0.1, b1 = 0.5, B2 = 0.1), alg = "port")

给出以下(因此b2 = B2 - b1 = 0 - 0.9788 = -0.9788)

> fm
Nonlinear regression model
  model: yeps ~ a + (b1 + (B2 - b1) * g) * x
   data: parent.frame()
      a      b1      B2 
-5.3699  0.9788  0.0000 
 residual sum-of-squares: 42143

Algorithm "port", convergence message: both X-convergence and relative convergence (5)

并密谋:

plot(yeps ~ x)
points(fitted(fm) ~ x, pch = 20, col = "red")

screenshot