R 通过使用最小化残差平方和的optim()获取参数,将模型拟合到观测数据

R 通过使用最小化残差平方和的optim()获取参数,将模型拟合到观测数据,r,optimization,ode,model-fitting,R,Optimization,Ode,Model Fitting,我试图将这个非常简单的4物种线性Lotka-Volterra竞争模型与观测数据相匹配,但由于某种原因,当我尝试optim()函数时,与deSolve有关的某些东西似乎失败了 # Data data <- data.frame(Cod = c(0.1966126, 0.1989563, 0.2567677, 0.3158896, 0.4225435, 0.7219856, 1.0570824, 0.7266830, 0.6286763,

我试图将这个非常简单的4物种线性Lotka-Volterra竞争模型与观测数据相匹配,但由于某种原因,当我尝试
optim()
函数时,与
deSolve
有关的某些东西似乎失败了

# Data
data <- data.frame(Cod = c(0.1966126, 0.1989563, 0.2567677, 0.3158896, 0.4225435, 0.7219856,
                           1.0570824, 0.7266830, 0.6286763, 0.6389475),
                   Herring = c(1.988372, 2.788014, 3.397138, 2.557245, 2.627013, 3.045617, 
                               3.161002, 3.531306, 3.432021, 3.617174),
                   Sprat = c(2.030273, 3.480469, 3.009277, 1.895996, 2.457520, 1.991211, 2.350098,
                             2.118164, 1.693359, 1.869141),
                   Flounder = c(0.4758220, 0.4425532, 0.4185687, 0.4967118, 0.7102515, 0.5733075,
                                0.7404255, 0.5996132, 0.6235977, 0.7187621))
# Model formulation
LLV <- function(time, state, parameters) {
  with(as.list(c(state, parameters)), {
    db1.dt = b1*(r1+a11*b1+a12*b2+a13*b3+a14*b4)
    db2.dt = b2*(r2+a22*b2+a21*b1+a23*b3+a24*b4)
    db3.dt = b3*(r3+a33*b3+a31*b1+a32*b2+a34*b4)
    db4.dt = b4*(r4+a44*b4+a41*b1+a42*b2+a43*b3)
    list(c(db1.dt, db2.dt, db3.dt, db4.dt))
  })
}
# Model input and simulation
# Model input
params <- c(r1 = -0.342085, r2 = 0.6855681, r3 = 2.757769, r4 = 0.9744113,
            a11 = -1.05973762, a12 = 0.09577309, a13 = -0.01915480, a14 = 1.36098939,
            a21 = 0.17533326, a22 = -0.32247342, a23 = 0.03111628, a24 = 0.30212711,
            a31 = 0.5303516, a32 = -0.4869761, a33 = -0.3194882, a34 = -1.5089027,
            a41 = 0.004418133, a42 = 0.163716414, a43 = -0.237873378, a44 = -1.519158802)
ini <- c(b1 = data[1,1], b2 = data[1,2], b3 = data[1,3], b4 = data[1,4])
tmax <- 10
t <- seq(1,tmax,0.1)
# Results and first parameter guess is more or less okay
results <- deSolve::ode(y = ini, times = t, func = LLV, parms = params)
matplot(data, pch = 1)
matplot(x = results[,1], y = results[,-1], type = "l", add = TRUE)

任何关于如何解决这个问题的想法都将不胜感激。

对于那些感兴趣的人,我已经设法找到了一个解决方案,其中包括更改ode集成方法。下面是正在工作的乐观主义者:

# Optimising parameter fit
LVmse = function(parms) {
  out = as.matrix(deSolve::ode(ini, 1:10, LLV, parms, method="rk")[,-1])
  RSS = sum((spp-out)^2, na.rm = TRUE) # Minimising residual sum of squares
  return(RSS)
}
optimres <- optim(par = params, fn = LVmse)
#优化参数拟合
LVmse=功能(parms){
out=as.matrix(deSolve::ode(ini,1:10,LLV,parms,method=“rk”)[,-1])
RSS=和((spp out)^2,na.rm=真)#最小化剩余平方和
返回(RSS)
}

optimres对于那些感兴趣的人,我已经设法找到了一个解决方案,其中包括更改ode集成方法。下面是正在工作的乐观主义者:

# Optimising parameter fit
LVmse = function(parms) {
  out = as.matrix(deSolve::ode(ini, 1:10, LLV, parms, method="rk")[,-1])
  RSS = sum((spp-out)^2, na.rm = TRUE) # Minimising residual sum of squares
  return(RSS)
}
optimres <- optim(par = params, fn = LVmse)
#优化参数拟合
LVmse=功能(parms){
out=as.matrix(deSolve::ode(ini,1:10,LLV,parms,method=“rk”)[,-1])
RSS=和((spp out)^2,na.rm=真)#最小化剩余平方和
返回(RSS)
}

optimres您得到了一个更好的匹配,但是您应该非常小心这个问题。我有点疯狂,用(开发中的)来解决这个问题。我对模型进行了拟合,得到了更好的拟合,还尝试了100个随机变化的起点来拟合我的最佳拟合。你的剩余平方和是1.19
fitode
在第一次尝试时达到了0.29,100次拟合的最佳结果是RSS=0.16然而:这些配合非常不稳定。该图显示了数据的拟合度,并预测了未来5个时间步(1)拟合度(虚线);(2) fitode初始配合(虚线);(3) 其他100个fitode配合(距离最佳配合0.05 RSS以内的为实心配合,比该配合差的为轻描淡写的配合)

你可以看到样本外的预测大多是疯狂的。事实上,你的拟合比某些更好的拟合更稳定-在整个社区崩溃之前到达时间步骤13-但底线是,在这种情况下,对数据的良好拟合并不能保证一个合理的答案。看起来100次拟合中只有一次达到了预测时间序列的末尾而没有崩溃(这似乎是基于观察到的时间序列的合理合理的“常识”预测)

为了可靠地拟合这些数据,您要么需要一个参数少得多的模型,要么需要以先验形式提供外部信息,要么需要正则化——某种方式进行惩罚拟合,这意味着“摇摆”的确定性轨迹,或者不合理的交互参数/增长率

##遥控器::安装github(“parksw3/fitode”)
图书馆(fitode)
##fitode的带有标记的数据

数据2您得到了更好的拟合,但是您应该非常小心这个问题。我有点疯狂,用(开发中的)来解决这个问题。我对模型进行了拟合,得到了更好的拟合,还尝试了100个随机变化的起点来拟合我的最佳拟合。你的剩余平方和是1.19
fitode
在第一次尝试时达到了0.29,100次拟合的最佳结果是RSS=0.16然而:这些配合非常不稳定。该图显示了数据的拟合度,并预测了未来5个时间步(1)拟合度(虚线);(2) fitode初始配合(虚线);(3) 其他100个fitode配合(距离最佳配合0.05 RSS以内的为实心配合,比该配合差的为轻描淡写的配合)

你可以看到样本外的预测大多是疯狂的。事实上,你的拟合比某些更好的拟合更稳定-在整个社区崩溃之前到达时间步骤13-但底线是,在这种情况下,对数据的良好拟合并不能保证一个合理的答案。看起来100次拟合中只有一次达到了预测时间序列的末尾而没有崩溃(这似乎是基于观察到的时间序列的合理合理的“常识”预测)

为了可靠地拟合这些数据,您要么需要一个参数少得多的模型,要么需要以先验形式提供外部信息,要么需要正则化——某种方式进行惩罚拟合,这意味着“摇摆”的确定性轨迹,或者不合理的交互参数/增长率

##遥控器::安装github(“parksw3/fitode”)
图书馆(fitode)
##fitode的带有标记的数据

数据2这是一个难题。我同意你可能认为非线性优化应该很容易,因为你有一个很好的开始条件,但你正在尝试将一个20参数的非线性模型拟合到40个数据点。我会看一看,看看我是否能提出任何解决方案,但总的来说,这将是非常困难的。类似MARSS(多元自回归状态空间)模型的东西可能会起作用?嗨,本,非常感谢你的回复。是的,也许我不允许optim()有效地搜索40个数据点。我可以尝试扩展时间序列,但这通常是渔业科学家经常要优化更复杂模型(如EwE)的拟合度。我可以模拟一些数据,如果你认为这将解决问题,以适应中间年份,增加一些先验不确定性的抽样。我知道模型的代码可以写成db.dt=(r+Ab)b,但我想添加一些更高阶的特定交互作用。HOI的编码形式为db1.dt=b1(r1+a11b1+a12b2^2…),然后我将重新应用优化程序,以获得某种“现实”(就LV模型而言)模型,我可以用它来应用一个算法,找到纳什均衡收获率。我在这个算法中使用了更复杂的模型,但修改后的LV似乎非常适合作为描述整个过程的教程。但是我