R语言 为什么nls函数对于相同的模型和相似的数据集返回如此不同的值?

c86crjj0  于 2023-03-10  发布在  其他
关注(0)|答案(1)|浏览(151)

我有两组相同鱼类的年龄和长度数据,都在下面的link中提供。
我想要一个拟合的生长模型,使用R,它允许在生命的某个特定时刻生长的变化。
我试着使用nls函数,并提供了适合我的数据的起始值。该模型是对Von Bertalanffy增长模型的改编,该模型应该返回五个不同参数(Linf,k0,t0,k1和t1)的值。
对于这两个数据集,我使用的代码如下:

fit <-as.formula(TL~ Linf * (1 - exp(-K0 * (Age - t0))) * (Age < t1) +
                   Linf * (1 - exp(-K0 * (t1 - t0) - K1 * (Age - t1))) * (Age > t1))

model<-nls(fit, data=dataset, start=list(Linf=17, K0=0.3, t0=-2, K1=0.1, t1=3), nls.control(maxiter = 500, tol = 1e-03, minFactor = 1/1024, printEval = FALSE, warnOnly = FALSE))
summary(model)

对于第一个数据集,返回的值如下:

Formula: TL ~ Linf * (1 - exp(-K0 * (Age - t0))) * (Age < t1) + Linf * 
    (1 - exp(-K0 * (t1 - t0) - K1 * (Age - t1))) * (Age > t1)

Parameters:
       Estimate Std. Error t value Pr(>|t|)    
Linf  4.089e+02  1.565e+04   0.026   0.9792    
K0    5.477e-03  2.141e-01   0.026   0.9796    
t0   -2.934e+00  1.500e+00  -1.956   0.0511 .  
K1    7.596e-04  3.004e-02   0.025   0.9798    
t1    2.246e+00  2.143e-01  10.477   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.881 on 457 degrees of freedom

Number of iterations to convergence: 294 
Achieved convergence tolerance: 0.000979

而对于第二个数据集,返回的值为:

Formula: TL ~ Linf * (1 - exp(-K0 * (Age - t0))) * (Age < t1) + Linf * 
    (1 - exp(-K0 * (t1 - t0) - K1 * (Age - t1))) * (Age > t1)

Parameters:
     Estimate Std. Error t value Pr(>|t|)    
Linf 15.04002    0.60919  24.689  < 2e-16 ***
K0    0.16740    0.01895   8.833  < 2e-16 ***
t0   -3.67353    0.34427 -10.671  < 2e-16 ***
K1    0.11986    0.02007   5.971 2.63e-09 ***
t1    2.29970    0.31711   7.252 5.18e-13 ***
---

只有为第二个数据集返回的值才对所讨论的物种有意义。
为什么nls函数在使用相同的模型、相同的初始值和非常相似的数据集时,却返回如此不同的参数值?

jgovgodb

jgovgodb1#

我不认为拟合本身有什么问题--它们看起来都与给定数据有合理的拟合,问题似乎是在第一组数据中,在数据点相对较少的年龄段前后,梯度发生了明显的变化。
以下是第一组数据的曲线图:

library(ggplot2)

fit <-as.formula(y~ Linf * (1 - exp(-K0 * (x - t0))) * (x < t1) +
                   Linf * (1 - exp(-K0 * (t1 - t0) - K1 * (x - t1))) * (x > t1))

ggplot(dataset, aes(Age, TL)) +
  geom_point() +
  geom_smooth(method = nls, formula = fit, method.args = list(
    start = list(Linf=17, K0=0.3, t0=-2, K1=0.1, t1=3), 
    control = list(maxiter = 10000, minFactor = 1e-9, tol = 1e-3)),
    se = FALSE, linetype = 2
  )

但是,第二个数据集的数据和图的形状非常不同:

ggplot(dataset2, aes(Age, TL)) +
  geom_point() +
  geom_smooth(method = nls, formula = fit, method.args = list(
    start = list(Linf=17, K0=0.3, t0=-2, K1=0.1, t1=3), 
    control = list(maxiter = 10000, minFactor = 1e-9, tol = 1e-3)),
    se = FALSE, linetype = 2
  )

所以问题仅仅在于你假设两个数据集是“相似的”。它们一点也不相似,至少在拟合这个模型方面是这样。例如,第一个数据集只有52个个体(11%)4岁以下,但第二个数据集有1279个(42%)。两个样本的年龄分布明显存在很大差异。请注意,使用rbind组合两个 Dataframe 将得到一个大模型,该模型与单独使用dataset 2获得的值相似。

相关问题