r中nls的奇异梯度误差;我怎么知道它的代码或数据?

时间:2015-08-19 11:56:56

标签: r nls

我试图对这些数据进行非线性回归:

Flux<-c(192.09536, 199.47616, 137.63245, 133.60358, -89.28360, -23.17639, -27.14659, 107.25287,  52.72565, NA, 167.43277, 113.59047)
Par<-c(4.166667e-01, 4.347826e-02, 4.583333e-01, 1.845833e+02, 1.122688e+03, 1.059048e+03, 6.384000e+02, 3.326087e+02, 7.094762e+02, 4.180000e+02, 3.953333e+02, 3.998636e+02)
Obs<-c(1,2,3,4,5,6,7,8,9,10,11,12)
curve1<-data.frame(Flux, Par, Obs)
curve1<-do.call("cbind", curve1)

这是我尝试的第一个模型,它曾用于其他一些类似的数据集:

model1 <- nls(Flux~b*Par/(c+Par)-a, data = curve1, start=list(a=180,
                                                          b=-200, c=800))

但是对于这个数据,model1给出了:

Error in nls(Flux ~ b * Par/(c + Par) - a, data = curve1, start =
    list(a = 180, : singular gradient

我认为这可能是因为我的起始参数是错误的所以我试图把它变成一个自启动模型(我也试过很多不同的起始参数):

model2<-with(curve1, nls(Flux~SSasymp(Par, a, b, c)))

这会产生同样的错误。 但是我认为在这种情况下我使用了SSasymp错误,因为它适合于我能够适应model1的数据的错误曲线。 我想这是因为我把关于a,b和c(?)的R搞糊涂了。我在阅读使用SSasymp时已经读到了: b是水平渐近线(a) - x为0时的响应&#39; 而c是速率常数。

在模型1中的原始方程中,b是水平渐近线,c是速率常数,a是x为0时的响应。

如果我尝试编写一个自启动模型来反映这一点:

model3<-with(curve1, nls(Flux~SSasymp(Par, b, (b-a), c)))

我收到此错误:     另外:警告信息:     在nls(Flux~SSasymp(Par,b,(b-a),c)):       没有为某些参数指定起始值。     将'a'初始化为&#39; 1。&#39;。     考虑指定&#39; start&#39;或使用selfStart模型

我正在寻求建议 1)由于我的代码错误/错误的启动参数或因为模型不适合数据,model1无法正常工作?

如果是后一种情况,是否有办法迫使R尽最大努力使非线性模型适合它?在生态学上,这应该是一个饱和的曲线。

2)我/我如何使自己的方程符合自启动模型?我是否从根本上误解了如何使用SSasymp?

非常感谢任何帮助。抱歉,如果我没有解释或格式化这个,这是我的第一篇文章,我不是一个经验丰富的R用户或统计学家!

1 个答案:

答案 0 :(得分:1)

这样的东西?

enter image description here

model1<-nls(Flux~b*Par/(c+Par)-a, data = curve1, start=list(a=180, b=-200, c=-2000))
plot(Flux~Par,curve1)
curve(predict(model1,newdata=data.frame(Par=x)),add=TRUE)
summary(model1)
# Formula: Flux ~ b * Par/(c + Par) - a
#
# Parameters:
#   Estimate Std. Error t value Pr(>|t|)    
# a  -179.17      22.86  -7.837 5.06e-05 ***
# b  1009.36    2556.44   0.395    0.703    
# c -5651.20   11542.41  -0.490    0.638    
# ---
# Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 42.43 on 8 degrees of freedom
# ...

您的数据有些病态。表格的功能

  

y = b * x /(c + x)

b < 0c > 0时,

会向上凹;它们在b > 0c < 0时向下凹,提供|c| > max(x)(否则会有一个垂直渐近线,如其中一条评论所示)。因为您的数据“几乎”是线性的,并且存在大量的分散,所以最佳拟合(例如,最小化残差平方和的参数集a,b和c)是向下凹的({{1} })。因此,如果您从估计值c < 0开始,就会收敛。

现在,我从你的问题中收集c < -max(x)有一些物理意义,要求它是&gt;这里的问题是您的模型被过度指定(参数太多)。在饱和曲线中,速率常数由曲率确定。但在你的情况下,没有曲率(或者,如果有的话,它是负的),所以你无法确定速率常数。数学上,c

  

b * x /(c + x)〜(b / c)* x

在您的情况下,斜率约为-0.25,因此x << c。但是b/c ~ -0.25b的数值无限多,可以产生这个比率。因此,虽然您对比率c了解很多,但您对b/cb个人一无所知。这就是为什么这些参数中的标准误差在上面的拟合中如此之大(并且p值非常高)。

最重要的是,在这种特定情况下,您没有足够的数据来分别确定a,b和c,具有任何准确性。

[两个小问题]

  1. 您的数据中c s的存在与此无关 - NA默认删除包含nls(...)的行。
  2. 您不需要该行:NA