使用 optim 从具有不同常量的多个时间序列中估计参数
Using optim to estimate parameters from multiple time series with different constants
我正在尝试使用多个时间序列来估计模型参数,其中序列之间的常数值不同。为了便于解释,我将使用逻辑增长模型作为示例。
我已经能够从具有相同常量 K 的多个时间序列(N1 和 N2)中估计参数 (r)。
#Data; needs to be matrix instead of data frame
dat <- as.matrix(cbind(time=seq(0,166,by=16),
N1=c(0.020,0.030,0.060,0.100,0.160,0.26,0.360,0.50,0.70,0.800,0.90),
N2=c(0.015,0.033,0.062,0.106,0.162,0.26,0.306,0.51,0.76,0.821,0.91)))
#dynamical model to estimate r
dNdt.model=function(t,x,params){
N <- x
with(as.list(c(params)), {
dN <- r*N*(1-(N/K))
list(c(dN))
})
}
#sse objective function
sse.dNdt=function(dNparams, data, Kfix=1){
t <- data[,1]
N <- data[,-1]
N0 <- data[1,-1]
K <- Kfix
r0 <- dNparams
out <- as.data.frame(ode(y=N0, times=t, func=dNdt.model, parms=c(r=r0, K=K)))
sse <- sum((out[2]-N)^2) + sum((out[3]-N)^2) #SSE needs to be sum of all trajectories
}
#run optim
dNparams <- c(.3) #initial value of r
optim(dNparams, sse.dNdt, data=dat) #estimate r based on N1 and N2 trajectories
哪个returns预期输出:
$平价
[1] 0.0637207
$值
[1] 4.279062
$ 计数
函数梯度
32 不适用
$收敛
[1] 0
$消息
空
如何转换此代码以对每个时间序列采用不同的 K 值?将 Kfix 转换为包含 2 个值的向量 returns 出错:未找到对象 'K'。
这是一个解决方案,它使用 purrr::map2_dfc
到 运行 每个时间序列的模型和 K
值以及 returns 数据框,其中每一列对应一个时间系列。
# Load package
library(deSolve)
# Data for fitting
dat <- data.frame(time = seq(0, 166, by=16),
N1 = c(0.020, 0.030, 0.060, 0.100, 0.160,
0.26, 0.360, 0.50, 0.70, 0.800, 0.90),
N2 = c(0.015, 0.033, 0.062, 0.106, 0.162,
0.26, 0.306, 0.51, 0.76, 0.821, 0.91))
# Model
dNdt_model <- function(t, x, params){
# State variable
N <- x
with(as.list(c(params)), {
# Rate of change
dN <- r*N*(1-(N/K))
#Return list
list(c(dN))
})
}
下面的代码是唯一真正改变的部分(除了我强迫性的整理)。 purrr::map2_dfc
遍历每个初始条件和 K
值以及 运行 模型。结果被绑定到一个数据框中。最后,从模型结果中减去观测值并计算平方和。
#sse objective function
sse_dNdt <- function(dNparams, data, K){
# Output times
t <- data[,1]
# Time series
N <- data[,-1]
# Run for each time series (different initial condition, different K value)
out <- purrr::map2_dfc(.x = data[1,-1], .y = K,
~ ode(y = .x, times = t, func = dNdt_model, parms = c(r = dNparams, K = .y))[, 2])
#SSE needs to be sum of all trajectories
sum((out - N)^2)
}
但是,purrr::map2_dfc
是做什么的?正如其名称所示,它映射两个变量 (map2
),即初始条件和 K
值,以及 returns 一个数据框 (df
),即通过绑定列生成(c
,而不是行的 r
)。
# Initial value of r
dNparams <- c(.3)
下面,我用 K
个值的数组调用 optim
。
# Run with different K values for time series N1 and N1
optim(dNparams, sse_dNdt, data = dat, K = c(1, 2))
我正在尝试使用多个时间序列来估计模型参数,其中序列之间的常数值不同。为了便于解释,我将使用逻辑增长模型作为示例。
我已经能够从具有相同常量 K 的多个时间序列(N1 和 N2)中估计参数 (r)。
#Data; needs to be matrix instead of data frame
dat <- as.matrix(cbind(time=seq(0,166,by=16),
N1=c(0.020,0.030,0.060,0.100,0.160,0.26,0.360,0.50,0.70,0.800,0.90),
N2=c(0.015,0.033,0.062,0.106,0.162,0.26,0.306,0.51,0.76,0.821,0.91)))
#dynamical model to estimate r
dNdt.model=function(t,x,params){
N <- x
with(as.list(c(params)), {
dN <- r*N*(1-(N/K))
list(c(dN))
})
}
#sse objective function
sse.dNdt=function(dNparams, data, Kfix=1){
t <- data[,1]
N <- data[,-1]
N0 <- data[1,-1]
K <- Kfix
r0 <- dNparams
out <- as.data.frame(ode(y=N0, times=t, func=dNdt.model, parms=c(r=r0, K=K)))
sse <- sum((out[2]-N)^2) + sum((out[3]-N)^2) #SSE needs to be sum of all trajectories
}
#run optim
dNparams <- c(.3) #initial value of r
optim(dNparams, sse.dNdt, data=dat) #estimate r based on N1 and N2 trajectories
哪个returns预期输出:
$平价 [1] 0.0637207
$值 [1] 4.279062
$ 计数 函数梯度 32 不适用
$收敛 [1] 0
$消息 空
如何转换此代码以对每个时间序列采用不同的 K 值?将 Kfix 转换为包含 2 个值的向量 returns 出错:未找到对象 'K'。
这是一个解决方案,它使用 purrr::map2_dfc
到 运行 每个时间序列的模型和 K
值以及 returns 数据框,其中每一列对应一个时间系列。
# Load package
library(deSolve)
# Data for fitting
dat <- data.frame(time = seq(0, 166, by=16),
N1 = c(0.020, 0.030, 0.060, 0.100, 0.160,
0.26, 0.360, 0.50, 0.70, 0.800, 0.90),
N2 = c(0.015, 0.033, 0.062, 0.106, 0.162,
0.26, 0.306, 0.51, 0.76, 0.821, 0.91))
# Model
dNdt_model <- function(t, x, params){
# State variable
N <- x
with(as.list(c(params)), {
# Rate of change
dN <- r*N*(1-(N/K))
#Return list
list(c(dN))
})
}
下面的代码是唯一真正改变的部分(除了我强迫性的整理)。 purrr::map2_dfc
遍历每个初始条件和 K
值以及 运行 模型。结果被绑定到一个数据框中。最后,从模型结果中减去观测值并计算平方和。
#sse objective function
sse_dNdt <- function(dNparams, data, K){
# Output times
t <- data[,1]
# Time series
N <- data[,-1]
# Run for each time series (different initial condition, different K value)
out <- purrr::map2_dfc(.x = data[1,-1], .y = K,
~ ode(y = .x, times = t, func = dNdt_model, parms = c(r = dNparams, K = .y))[, 2])
#SSE needs to be sum of all trajectories
sum((out - N)^2)
}
但是,purrr::map2_dfc
是做什么的?正如其名称所示,它映射两个变量 (map2
),即初始条件和 K
值,以及 returns 一个数据框 (df
),即通过绑定列生成(c
,而不是行的 r
)。
# Initial value of r
dNparams <- c(.3)
下面,我用 K
个值的数组调用 optim
。
# Run with different K values for time series N1 and N1
optim(dNparams, sse_dNdt, data = dat, K = c(1, 2))