【问题标题】:Speeding up time series simulation (for bootstrap)加速时间序列模拟(用于引导程序)
【发布时间】:2012-08-17 01:21:06
【问题描述】:

我需要在具有非标准依赖性的时间序列上运行引导程序。所以要做到这一点,我需要创建一个通过时间调整来模拟时间序列的函数。

testing<-function(){
  sampleData<-as.zoo(data.frame(index=1:1000,vol=(rnorm(1000))^2,x=NA))
  sampleData[,"x"]<-sampleData[,"vol"]+rnorm(1000) #treat this is completely exognenous and unknown in connection to vol
  sampleData<-cbind(sampleData,mean=rollmean(sampleData[,"vol"],k=3,align="right"))
  sampleData<-cbind(sampleData,vol1=lag(sampleData[,"vol"],k=-1),x1=lag(sampleData[,"x"],k=-1),mean1=lag(sampleData[,"mean"],k=-1))

  #get estimate
  mod<-lm(vol~vol1+x1+mean1,data=sampleData)

  res<-mod$residuals

  for(i in 5:1000){
    #recursively estimate
    sampleData[i,"vol"]<-as.numeric(predict(mod,newdata=data.frame(sampleData[i-1,])))+res[i-3]

    #now must update other paramaters
      #first our rolled average
      sampleData[i,"mean"]<-mean(sampleData[(i-3):i,"vol"])

      #reupdate our lagged variables
      sampleData[i,"vol1"]<-sampleData[i-1,"vol"]
      sampleData[i,"mean1"]<-sampleData[i-1,"mean"]

  }

  lm(vol~vol1+x1+mean1,data=sampleData)
}

当我运行这段代码并测量我得到的运行时间时

system.time(testing())
user  system elapsed 
2.711   0.201   2.915 

这对我来说是个小问题,因为将集成此代码以构建引导程序。这意味着这里花费的任何时间每一步都乘以大约 100。我更新了几千次。这意味着单次运行将需要数小时(到数天)才能运行。

有没有办法加快这段代码的速度?

亲切的问候,

马修

【问题讨论】:

  • 关于更多上下文,我使用的实际函数从外部获取残差,并将输出一些值(预测、参数)。残差通过带有非参数块引导的 tsboot 传入。然后,我需要随着时间的推移重复此操作,以查看参数(和分布如何变化)。
  • 使用 sapply 会加快速度吗?我如何让 sapply 从当前未处理的行中获取值?
  • sapply 无济于事。您需要分析您的代码以找到瓶颈(请参阅?Rprof)。从 zoo 切换到 xts 可以节省一点时间,因为需要花费一些时间进行子集设置。您还可以通过手动执行乘法来避免 predict.lm 的开销,从而提高性能。
  • 我认为主要的瓶颈是循环
  • @lselzer:不是;这是predict.lm

标签: r time-series statistics-bootstrap


【解决方案1】:

以下是避免predict.lm 开销的方法。另请注意,我使用矩阵而不是动物园对象,这会慢一点。您可以看到这使您的代码变慢了多少。这就是您为方便而付出的代价。

testing.jmu <- function() {
  if(!require(xts)) stop("xts package not installed")
  set.seed(21)  # for reproducibility
  sampleData <- .xts(data.frame(vol=(rnorm(1000))^2,x=NA), 1:1000)
  sampleData$x <- sampleData$vol+rnorm(1000)
  sampleData$mean <- rollmean(sampleData$vol, k=3, align="right")
  sampleData$vol1 <- lag(sampleData$vol,k=1)
  sampleData$x1 <- lag(sampleData$x,k=1)
  sampleData$mean1 <- lag(sampleData$mean,k=1)

  sampleMatrix <- na.omit(cbind(as.matrix(sampleData),constant=1))
  mod.fit <- lm.fit(sampleMatrix[,c("constant","vol1","x1","mean1")],
                    sampleMatrix[,"vol"])
  res.fit <- mod.fit$residuals

  for(i in 5:nrow(sampleMatrix)){
    sampleMatrix[i,"vol"] <-
      sum(sampleMatrix[i-1,c("constant","vol1","x1","mean1")] *
          mod.fit$coefficients)+res.fit[i-3]
    sampleMatrix[i,"mean"] <- mean(sampleMatrix[(i-3):i,"vol"])
    sampleMatrix[i,c("vol1","mean1")] <- sampleMatrix[i-1,c("vol","mean")]
  }

  lm.fit(sampleMatrix[,c("constant","vol1","x1","mean1")], sampleMatrix[,"vol"])
}
system.time(out <- testing.jmu())
#    user  system elapsed 
#    0.05    0.00    0.05 
coef(out)
#    constant        vol1          x1       mean1 
#  1.08787779 -0.06487441  0.03416802 -0.02757601

set.seed(21) 调用添加到您的函数中,您会看到我的函数返回的系数与您的相同。

【讨论】:

  • @lselzer:我要说多少次这不是问题?当它没有问题时,你为什么希望我删除它?随意提供不使用循环的答案...
猜你喜欢
  • 2023-03-28
  • 2013-04-05
  • 1970-01-01
  • 2014-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2020-06-22
相关资源
最近更新 更多