使用nls函数执行自定义拟合时出错

时间:2014-02-12 05:35:21

标签: r

我正在尝试使用自定义方程拟合数据,并且我收到警告信息并且它没有被执行..这是我的r代码..

x <- c(3, 33, 146, 227, 342, 351, 353, 444, 556, 571, 709, 759, 836, 
860, 968, 1056, 1726, 1846, 1872, 1986, 2311, 2366, 2608, 2676, 
3098, 3278, 3288, 4434, 5034, 5049, 5085, 5089, 5089, 5097, 5324, 
5389, 5565, 5623, 6080, 6380, 6477, 6740, 7192, 7447, 7644, 7837, 
7843, 7922, 8738, 10089, 10237, 10258, 10491, 10625, 10982, 11175, 
11411, 11442, 11811, 12559, 12559, 12791, 13121, 13486, 14708, 
15251, 15261, 15277, 15806, 16185, 16229, 16358, 17168, 17458, 
17758, 18287, 18568, 18728, 19556, 20567, 21012, 21308, 23063, 
24127, 25910, 26770, 27753, 28460, 28493, 29361, 30085, 32408, 
35338, 36799, 37642, 37654, 37915, 39715, 40580, 42015, 42045, 
42188, 42296, 42296, 45406, 46653, 47596, 48296, 49171, 49416, 
50145, 52042, 52489, 52875, 53321, 53443, 54433, 55381, 56463, 
56485, 56560, 57042, 62551, 62651, 62661, 63732, 64103, 64893, 
71043, 74364, 75409, 76057, 81542, 82702, 84566, 88682)

y <- c(1:136)
df <- data.frame(x,y)

fit <- nls(y ~ a*(1-exp(-x/b))^c, data=df, start = list( a=100,b=1000,c=0.5),  
     algorithm="port",lower=list(a=100,b=100,c=0.5),upper=list(a=200,b=10000,c=2))

警告讯息:

1: In min(x) : no non-missing arguments to min; returning Inf
2: In max(x) : no non-missing arguments to max; returning -Inf

如何将此数据拟合到此自定义方程以及如何查找r平方值..

提前致谢..

1 个答案:

答案 0 :(得分:1)

首先,直接回答你的问题,R 2 对于非线性拟合来说不是一个有意义的概念。对于线性模型,R 2 是数据集中总变异性的一部分,由模型解释。此计算仅在SST = SSR + SSE时有效,对于所有线性模型都是如此,但对于非线性模型则不一定如此。有关更完整的说明和一些其他参考,请参阅this question

因此,虽然可以将线性模型的R 2 视为

rsq <- summary(lm(...))$r.squared

非线性模型的summary(...)方法不会返回R 2 值。

其次,你真的需要养成根据数据绘制拟合曲线的习惯。

plot(x,y)
lines(x,predict(fit))

没有办法将此解释为“良好”的契合度。如果我们在没有a,b和c约束的情况下重新运行模型,我们会得到更好的拟合:

fit.2 <- nls(y ~ a*(1-exp(-x/b))^c, data=df, start = list( a=100,b=1000,c=0.5),  
           algorithm="port")

par(mfrow=c(1,2))
plot(x,y, main="Constrained Model",cex=0.5)
lines(x,predict(fit), col="red")
plot(x,y, main="UNconstrained Model",cex=0.5)
lines(x,predict(fit.2), col="red")

显然这个模型“更好”,但这并不意味着它“好”。除其他外,我们需要查看残差。对于拟合良好的模型,残差不应取决于x。所以让我们看看:

plot(y,residuals(fit),main="Residuals: 1st Model")
plot(y,residuals(fit.2),main="Residuals: 2ndd Model")

第二个模型中的残差要小得多,并且不遵循趋势,尽管似乎有一些潜在的结构。这将是值得关注的 - 它暗示可能由于实际效应或可能由于数据收集方法而存在一些低振幅振荡。

此外,回归建模的基本原理(起始假设)是残差通常以恒定方差分布(例如,方差不依赖于x)。我们可以使用Q-Q图来检查这一点,该图描绘了(标准化)残差的分位数与N(0,1)的分位数。如果残差是正态分布的,那么这应该是一条直线。

se <- summary(fit)$sigma
qqnorm(residuals(fit)/se, main="Q-Q Plot, 1st Model")
qqline(residuals(fit)/se,probs=c(0.25,0.75))
se.2 <- summary(fit.2)$sigma
qqnorm(residuals(fit.2)/se.2, main="Q-Q Plot, 2nd Model")
qqline(residuals(fit.2)/se.2,probs=c(0.25,0.75))

如您所见,第二个模型的残差几乎是正态分布的。最重要的是IMO认为第二个模型是一个“好”的模型。

最后,您的数据在我看来就像是具有2个峰值的分布的cdf。对数据进行建模的一种非常简单的方法是:

  

y~a 1 ×(1 - exp(-x / b 1 ))+ a 2 ×(1 - exp( -x / b 2 ))

当我尝试这个模型时,它比模型的无约束版本好一点。