首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在nlme中拟合数据的技巧?

在nlme中拟合数据的技巧?
EN

Stack Overflow用户
提问于 2014-04-08 03:13:58
回答 1查看 3.7K关注 0票数 3

当我在nlme中拟合数据时,我从来不会在第一次尝试中就成功,在nlme(fit.model)之后,我习惯于看到这样的情况:

代码语言:javascript
复制
Error in nlme.formula(model = mass ~ SSbgf(day, w.max, t.e, t.m), random = list( :
  step halving factor reduced below minimum in PNLS step

Error in MEestimate(nlmeSt, grpShrunk) : 
  Singularity in backsolve at level 0, block 1

所以我回到过去

1)更改x轴的单位(例如,从年更改为天,或将天更改为增长度日)。

2)在我的数据集中进行x=0、y=0测量

3)添加random=pdDiag()

4)弄乱随机的和固定的

5)切碎我的数据集,尝试在不同的时间适合不同的部分

6)实现一个非常简单的拟合,然后使用update使模型适当

最终,似乎有一些东西起作用了。还有没有其他人有什么要补充的?是什么帮助你让nlme使用你的数据?

我知道这个问题可能会结束,但如果有任何建议如何重新表述为可接受的,我将不胜感激。

下面是一个例子,我尝试了其中的一些方法,但到目前为止还没有成功:

数据:https://www.dropbox.com/s/4inldx7617fip01/proots.csv。这已经只是整个集合的一部分。

代码:

代码语言:javascript
复制
roots<-read.table("proots.csv", header = TRUE)

#roots$day[roots$year == 2007] <- 0 #when I use a dataset with time=0, mass=0
roots$day[roots$year == 2008] <- 153
roots$day[roots$year == 2009] <- 518
roots$day[roots$year == 2010] <- 883
roots$day[roots$year == 2011] <- 1248
roots$day[roots$year == 2012] <- 1613
roots$day[roots$year == 2013] <- 1978

#or bigger time steps
roots$time[roots$year == 2008] <- 1
roots$time[roots$year == 2009] <- 2
roots$time[roots$year == 2010] <- 3
roots$time[roots$year == 2011] <- 4
roots$time[roots$year == 2012] <- 5
roots$time[roots$year == 2013] <- 6

roots$EU<- with(roots, factor(plot):factor(depth)) #EU is "experimental unit"
rootsG<-groupedData(mass ~ day | EU, data=roots)

#I will post the SSbgf function below -- run it first
fit.beta <- nlsList(mass ~ SSbgf(day, w.max, t.e, t.m), data = rootsG) 

fit.nlme.bgf<-nlme(fit.beta)
fit.nlme.bgf<-nlme(fit.beta, random=list(w.max + t.e + t.m ~1))
fit.nlme.bgf<-nlme(fit.beta, random=list(w.max ~ 1))
fit.nlme.bgf<-nlme(fit.beta, random=pdDiag(w.max ~1))

fit.nlme.bgf<-nlme(fit.beta, random=pdDiag(w.max + t.e + t.m ~1))
fit.nlme.bgf<-nlme(fit.beta, random=list(t.m ~1)) 
fit.nlme.bgf<-nlme(fit.beta, random=list(t.e ~1))

fit.nlme.bgf<-nlme(fit.beta, random=pdSymm(w.max ~1))
fit.nlme.bgf<-nlme(fit.beta, random=pdDiag(w.max ~1))

下面是曲线的函数(SSbgf):

代码语言:javascript
复制
bgfInit <- function(mCall, LHS, data){

  xy <- sortedXyData(mCall[["time"]], LHS, data)
  if(nrow(xy) < 4){
    stop("Too few distinct input values to fit a bgf")
  }
  w.max <- max(xy[,"y"])
  t.e <- NLSstClosestX(xy, w.max)
  t.m <- NLSstClosestX(xy, w.max/2)
  value <- c(w.max, t.e, t.m)
  names(value) <- mCall[c("w.max","t.e","t.m")]
  value

}


bgf <- function(time, w.max, t.e, t.m){

  .expr1 <- t.e / (t.e - t.m)
  .expr2 <- (time/t.e)^.expr1
  .expr3 <- (1 + (t.e - time)/(t.e - t.m))
  .value <- w.max * .expr3 * .expr2

  ## Derivative with respect to t.e
  .exp1 <- ((time/t.e)^(t.e/(t.e - t.m))) * ((t.e-time)/(t.e-t.m) + 1)
  .exp2 <- (log(time/t.e)*((1/(t.e-t.m) - (t.e/(t.e-t.m)^2) - (1/(t.e - t.m)))))*w.max
  .exp3 <- (time/t.e)^(t.e/(t.e-t.m))
  .exp4 <- w.max * ((1/(t.e-t.m)) - ((t.e - time)/(t.e-t.m)^2))
  .exp5 <- .exp1 * .exp2 + .exp3 * .exp4 

  ## Derivative with respect to t.m
  .ex1 <- t.e * (time/t.e)^((t.e/(t.e - t.m))) * log(time/t.e) * ((t.e - time)/(t.e -     
 t.m) + 1) * w.max
  .ex2 <- (t.e - time) * w.max * (time/t.e)^(t.e/(t.e-t.m))
  .ex3 <- (t.e - t.m)^2
  .ex4 <- .ex1 / .ex3 + .ex2 / .ex3

  .actualArgs <- as.list(match.call()[c("w.max", "t.e", "t.m")])

##  Gradient
  if (all(unlist(lapply(.actualArgs, is.name)))) {
    .grad <- array(0, c(length(.value), 3L), list(NULL, c("w.max", 
                                                      "t.e", "t.m")))
    .grad[, "w.max"] <- .expr3 * .expr2
    .grad[, "t.e"] <- .exp5
    .grad[, "t.m"] <- .ex4 
    dimnames(.grad) <- list(NULL, .actualArgs)
    attr(.value, "gradient") <- .grad
  }
    .value
}

SSbgf <- selfStart(bgf, initial = bgfInit, c("w.max", "t.e", "t.m"))
EN

回答 1

Stack Overflow用户

发布于 2014-06-27 03:08:51

另一个技巧是增加pnls容差。

所需的代码为:

代码语言:javascript
复制
control = nlmeControl(pnlsTol = x, msVerbose = TRUE)

pnls公差的起始值是0.001,所以我喜欢从0.01或0.02开始。只需用你的数字替换x,你就应该设置好了。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22921047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档