未能拟合非线性拟合方法(nlsLM,nlxb和wrapnls)

时间:2016-05-10 08:49:02

标签: r dplyr nls non-linear-regression

我有一个nls fitting任务,我想用R做。 我第一次尝试这样做here和@Roland指出

"重点是复杂的模型难以适应。更重要的是,数据支持模型的次数越少,直至变得不可能。如果你有非常好的起始值,你可能适合这个。"

我同意@Roland但如果excel可以做到这一点,那么为什么R无法做到呢?

基本上这种拟合可以用Excel的GRG非线性求解器完成,但是这个过程非常耗时,有时拟合并不好。 (因为现实中有很多数据)。

这是我的示例data.frame。我想让每个set组适合下面提供的模型,

set.seed(12345)
    set =rep(rep(c("1","2","3","4"),each=21),times=1)
    time=rep(c(10,seq(100,900,100),seq(1000,10000,1000),20000),times=1)
    value <- replicate(1,c(replicate(4,sort(10^runif(21,-6,-3),decreasing=FALSE))))
    data_rep <- data.frame(time, value,set)

     > head(data_rep)
            #    time        value set
            #1     10 1.007882e-06   1
            #2    100 1.269423e-06   1
            #3    200 2.864973e-06   1
            #4    300 3.155843e-06   1
            #5    400 3.442633e-06   1
            #6    500 9.446831e-06   1
            *      *       *         *

尝试1

我已在此处trouble-when-adding-3rd-fitting-parameter-in-nls

发布了一个问题

基本上问题在于我想对分组数据进行拟合并根据拟合系数进行预测。

我使用了来自nlsLM的{​​{1}}我收到了错误

  

nlsModel中的错误(公式,mf,start,wts,upper):     初始参数估计时的奇异梯度矩阵

根据@Roland,乍一看可能是模型错误或我的起始值不好。另一方面,我只能用两个拟合参数来拟合这个模型。当我想将library(minpack.lm)参数添加到拟合函数时,就会出现问题。

尝试2

在帖子trouble-when-adding-3rd-fitting-parameter-in-nls中关注@G。格洛腾迪克的建议,我在third包中尝试了nlxb,并将参数nlmrt中的一个修改为d并按照以下方式进行拟合;

d=32

拟合系数合理wolaa!但是这一次我意识到(@G.Grothendieck后来也指出)在formula = value~Ps*(1-exp(-2*f*time*exp(-d)))*1/(sqrt(2*pi*sigma))*exp(-(d-d_ave)^2/(2*sigma))*d_step d_step <- 1 f <- 1e9 d <- 32 library(plyr) library(nlmrt) get.coefs <- function(data_rep) { fit <- nlxb(formula , data = data_rep, start=c(d_ave=44,sigma=12,Ps=0.5), lower=c(d_ave=25,sigma=2,Ps=0.5), upper=c(d_ave=60,sigma=15,Ps=1), trace=TRUE) } fit <- dlply(data_rep, c("set"), .fun = get.coefs) # Fit data grouped by "set" # > fit # $`1` # nlmrt class object: x # residual sumsquares = 1.474e-07 on 21 observations # after 12 Jacobian and 13 function evaluations # name coeff SE tstat pval #gradient JSingval # d_ave 42.0126 NA NA NA #-7.082e-15 0.001733 # sigma 12.8377 NA NA NA #2.408e-15 1.289e-19 # Ps 0.973223 NA NA NA #9.33e-15 3.37e-20 # # $`2` # nlmrt class object: x # residual sumsquares = 6.2664e-08 on 21 observations # after 12 Jacobian and 13 function evaluations # name coeff SE tstat pval #gradient JSingval # d_ave 42.246 NA NA NA #-7.269e-15 0.001428 # sigma 12.7429 NA NA NA #2.568e-15 3.098e-19 # Ps 0.981517 NA NA NA #9.211e-15 2.746e-20 # # $`3` # nlmrt class object: x # residual sumsquares = 1.773e-07 on 21 observations # after 12 Jacobian and 13 function evaluations # name coeff SE tstat pval #gradient JSingval # d_ave 41.968 NA NA NA #-6.438e-15 0.001798 # sigma 12.8561 NA NA NA #2.173e-15 2.414e-19 # Ps 0.972988 NA NA NA #8.534e-15 5.922e-20 # $`4` # nlmrt class object: x # residual sumsquares = 2.5219e-07 on 21 observations # after 12 Jacobian and 13 function evaluations # name coeff SE tstat pval #gradient JSingval # d_ave 41.8532 NA NA NA #-4.454e-15 0.001976 # sigma 12.9045 NA NA NA #1.474e-15 3.443e-19 # Ps 0.974319 NA NA NA #5.987e-15 3.124e-20 # attr(,"split_type") # [1] "data.frame" # attr(,"split_labels") # set # 1 1 # 2 2 # 3 3 # 4 4 之后预测新值是不可能的(为什么=?我不知道!)

nlxb

::您可以在here

中找到predvals <- ldply(fit, .fun=predictvals, xvar="time", yvar="value",xrange=range(range)) # predict values 函数
  

UseMethod出错(&#34;预测&#34;):     没有适用的方法来预测&#39;应用于类&#34; nlmrt&#34;

的对象

没有!对于predictvals类对象,我需要coefpredict methods

尝试3

跟随@G。格洛腾迪克的另一个建议 接下来,我尝试了"nlmrt"的{​​{1}}。

因为在这篇文章中他说, can-we-make-prediction-with-nlxb-from-nlmrt-package

&#34;因为nlmrt包确实提供wrapnls,它将运行nlmrt然后wrapnls以便生成nlmrt对象,然后该对象就可以与所有nls类方法一起使用。

来自同样"nls"的套餐仍有问题,如下所示

我在第一次post之后放弃使用"nls",因为加载nlmrtplyr会让我的问题变得更复杂。所以我会坚持使用plyr并使用dplyr函数。

dplyr
  

nlsModel中的错误(公式,mf,start,wts,upper):     初始参数估计时的奇异梯度矩阵

我回到了我开始犯这个错误的地方。 我想我尝试了所有我能做的事情,寻找相关的例子(虽然只有3个),阅读书籍并遵循建议。

1 个答案:

答案 0 :(得分:2)

nls2之后使用nls2包中的nlxb(假设为data_rep, 来自问题的formulad_stepfd。为了使示例最小化,我们已经消除了dplyr,只显示了set == 2的计算。

library(nlmrt)
library(nls2)

data_rep2 <- subset(data_rep, set == 2)

fit.nlxb <- nlxb(formula , data = data_rep2,
                start = c(d_ave = 44, sigma = 12, Ps = 0.5),
                lower = c(d_ave = 25, sigma = 2, Ps = 0.5),
                upper = c(d_ave = 60, sigma = 15, Ps = 1))

fit.nls <- nls2(formula, data = data_rep2, start = fit.nlxb$coefficients,
  algorithm = "brute-force")

identical(fit.nlxb$coefficients, coef(fit.nls))
## [1] TRUE

fit.nls是一个"nls"类对象,其系数与fit.nlxb相同,我们可以使用fitted()predict()以及所有其他"nls"方法就可以了。