Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent a nls-fit from falling below zero

Tags:

r

nls

I'm trying to fit a function in R and therefor I use nls(). Is there a way to prevent the fitted function from falling below zero?

An easy work around would be to rise the parameter b0 in the target function after the fit, but this is actually not what I want because I expect a real fit with the constraint of beeing positive to lead to a better result.

y=c(m1,m2,m3,m4,m5,m6,m7,m8,m9,m10)
d=data.frame(seq(1, 10, 1),y=y)
fitFun <- function(x, add, b0, b1) {b0 + (x+add)^b1}
m=nls(y~fitFun(x,add,intercept,power),d,start=list(intercept=1,power=3.5,add=2),trace=T)
like image 558
B1ANCHi Avatar asked Dec 13 '25 10:12

B1ANCHi


2 Answers

Are you looking for this? Constraining the parameters to make the prediction non-negative can be tricky if the prediction is a hard-to-invert function of the parameters, but in this case we just have to require b0>=0 ... using @Roland's example,

fit2 <- nls(y~b0+(x+add)^b1,
            algorithm="port",
            lower=c(b0=0,b1=-Inf,add=-Inf),
            data=df,start=list(b0=1,b1=3.5,add=2))
lines(predict(fit2)~df$x,col="purple")

In the following the blue is the original unconstrained fit; red is @Roland's fit; and purple is the fit above.

enter image description here

like image 82
Ben Bolker Avatar answered Dec 16 '25 22:12

Ben Bolker


You need to change your model. For that you need to define what should happen if the function values would fall below zero. Here is an example, which sets these values to 0.

x <- 1:200/100
set.seed(42)
y <- -10+(x+1)^3.5+rnorm(length(x),sd=3)
df <- data.frame(x,y)

plot(y~x,data=df)

fitFun <- function(x, add, b0, b1) {
    res <- b0 + (x+add)^b1
    res[res<0] <- 0
    res
}
fit <- nls(y~fitFun(x,add,intercept,power),
           data=df,start=list(intercept=1,power=3.5,add=2))
summary(fit)
lines(predict(fit)~df$x,col="red")

fit result

like image 38
Roland Avatar answered Dec 16 '25 21:12

Roland



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!