【问题标题】:Prevent a nls-fit from falling below zero防止 nls-fit 低于零
【发布时间】:2014-06-20 05:38:24
【问题描述】:

我正在尝试在 R 中拟合一个函数,因此我使用 nls()。 有没有办法防止拟合函数低于零?

一个简单的解决方法是在拟合后提高目标函数中的参数b0,但这实际上不是我想要的,因为我希望真正符合 beeing positive 的约束会导致更好的结果.

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)

【问题讨论】:

    标签: r nls


    【解决方案1】:

    您需要更改模型。为此,您需要定义如果函数值低于零会发生什么。这是一个示例,它将这些值设置为 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")
    

    【讨论】:

    • 感谢您的回答,我会考虑如何更改模型,但实际上我认为模型是固定的,宁愿告诉优化器函数值应保持在零以上,例如作为优化过程中的附加条件
    • @B1ANCHi 我想你很困惑。如果你对模型的结果施加约束,你就有效地改变了你的模型。您可以通过实际更改模型或采取便宜的方式来做到这一点,我已经在这里演示过。优化器只在你想约束模型参数时才关心。
    【解决方案2】:

    你在找这个吗?如果预测是参数的难以反转的函数,则约束参数以使预测为非负可能会很棘手,但在这种情况下,我们只需要使用 @Roland 的示例要求 b0&gt;=0 ...,

    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")
    

    下面的蓝色是原始的无约束拟合;红色适合@Roland;紫色是上面的合适。

    【讨论】:

    • @B1ANCHi 但是,如果数据明显违反了它的约束,就像本例中的情况一样,您应该重新考虑您的模型。
    【解决方案3】:

    非常感谢您的回答。也许我没有就我的问题提供足够的信息,但我还没有被允许发布图片和描述一切会导致一个短篇故事。

    @Roland 完全正确,优化器的任务不是关心目标函数的行为,但正如我提到的,我假设模型是修复的。

    @Ben Bolker 将函数的加法部分限制为正值的建议导致结果不令人满意。

    我没有提到的是 m1 到 m10 是我记录的数据收集的平均值。我通过在拟合过程中使用记录系列的方差作为权重解决了我的问题。

    y=c(m1,m2,m3,m4,m5,m6,m7,m8,m9,m10)
    d=data.frame(seq(1, 10, 1),y=y)
    vars = c(var(lt1$V1),var(lt2$V1),var(lt3$V1),var(lt4$V1),var(lt5$V1),var(lt6$V1),var(lt7$V1),var(lt8$V1),var(lt9$V1),var(lt10$V1))
    weights = rep(max(vars),10)/vars
    fitFun <- function(x, add, b0, b1) {b0 + (x+add)^b1}
    m=nls(y~fitFun(x,add,intercept,power),d,weights=weights,start=list(intercept=1,power=3.5,add=2),trace=T)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多