当前位置: 首页 > 知识库问答 >
问题:

如何在R中使用蒙特卡罗ARIMA模拟函数

公西季
2023-03-14

下面是我想用R做的算法:

  1. ARIMA模型到ARIMA模拟10个时间序列数据集。sim()功能
  2. 将序列分为可能的子序列,包括2s3s4s5s6s7s8s,和9s
  3. 对于每个尺寸,对具有替换的块进行重采样,对于新系列,通过auto从每个块尺寸的子系列中获得最佳ARIMA模型。arima()函数
  4. 为每个块大小的每个子系列获取RMSE

下面的R函数可以完成此操作。

## Load packages and prepare multicore process
library(forecast)
library(future.apply)
plan(multisession)
library(parallel)
library(foreach)
library(doParallel)
n_cores <- detectCores()
cl <- makeCluster(n_cores)
registerDoParallel(cores = detectCores())
## simulate ARIMA(1,0, 0)
#n=10; phi <- 0.6; order <- c(1, 0, 0)
bootstrap1 <- function(n, phi){
  ts <- arima.sim(n, model = list(ar=phi, order = c(1, 0, 0)), sd = 1)
  ########################################################
  ## create a vector of block sizes
  t <- length(ts)    # the length of the time series
  lb <- seq(n-2)+1   # vector of block sizes to be 1 < l < n (i.e to be between 1 and n exclusively)
  ########################################################
  ## This section create matrix to store block means
  BOOTSTRAP <- matrix(nrow = 1, ncol = length(lb))
  colnames(BOOTSTRAP) <-lb
  ########################################################
  ## This section use foreach function to do detail in the brace
  BOOTSTRAP <- foreach(b = 1:length(lb), .combine = 'cbind') %do%{
    l <- lb[b]# block size at each instance 
    m <- ceiling(t / l)                                 # number of blocks
    blk <- split(ts, rep(1:m, each=l, length.out = t))  # divides the series into blocks
    ######################################################
    res<-sample(blk, replace=T, 10)        # resamples the blocks
    res.unlist <- unlist(res, use.names = FALSE)   # unlist the bootstrap series
    train <- head(res.unlist, round(length(res.unlist) - 10)) # Train set
    test <- tail(res.unlist, length(res.unlist) - length(train)) # Test set
    nfuture <- forecast::forecast(train, model = forecast::auto.arima(train), lambda=0, biasadj=TRUE, h = length(test))$mean        # makes the `forecast of test set
    RMSE <- Metrics::rmse(test, nfuture)      # RETURN RMSE
    BOOTSTRAP[b] <- RMSE
  }
  BOOTSTRAPS <- matrix(BOOTSTRAP, nrow = 1, ncol = length(lb))
  colnames(BOOTSTRAPS) <- lb
  BOOTSTRAPS
  return(list(BOOTSTRAPS))
}

调用函数

bootstrap1(10, 0.6)

我得到以下结果:

##              2        3         4        5        6        7         8         9
##  [1,] 0.8920703 0.703974 0.6990448 0.714255 1.308236 0.809914 0.5315476 0.8175382

我想按时间顺序重复上面的步骤1步骤4,然后我想到了R中的Monte Carlo技术。因此,我加载它的包并运行以下函数:

param_list=list("n"=10, "phi"=0.6)
library(MonteCarlo)
MC_result<-MonteCarlo(func = bootstrap1, nrep=3, param_list = param_list)

希望在矩阵表格中得到如下结果:

##           [,2]     [,3]      [,4]    [,5]       [,6]      [,7]      [,8]      [,9]
##  [1,] 0.8920703 0.703974  0.6990448 0.714255  1.308236  0.809914  0.5315476 0.8175382
##  [2,] 0.8909836 0.8457537 1.095148  0.8918468 0.8913282 0.7894167 0.8911484 0.8694729
##  [3,] 1.586785  1.224003  1.375026  1.292847  1.437359  1.418744  1.550254  1.30784

但我收到以下错误信息:

MonteCarlo错误(func=bootstrap1,nrep=3,param_list=param_list):func必须返回一个包含命名组件的列表。每个组件都必须是标量。

我如何才能找到获得上述预期结果的方法,并使结果重现?

共有1个答案

弓嘉纳
2023-03-14

之所以会出现此错误消息,是因为MonteCarlo希望bootstrap1()为模拟接受一个参数组合,并且每次复制只返回一个值(RMSE)。这里的情况并非如此,因为块长度(lb)是由bootstrap1中模拟的时间序列(n)的长度决定的,因此您将得到每个调用的n-2块长度的结果。

解决方案是将块长度作为参数传递,并适当重写bootstrap1()

library(MonteCarlo)
library(forecast)
library(Metrics)

# parameter grids
n <- 10 # length of time series
lb <- seq(n-2) + 1 # vector of block sizes
phi <- 0.6 # autoregressive parameter
reps <- 3 # monte carlo replications

# simulation function  
bootstrap1 <- function(n, lb, phi) {
    
    #### simulate ####
    ts <- arima.sim(n, model = list(ar = phi, order = c(1, 0, 0)), sd = 1)
    
    #### devide ####
    m <- ceiling(n / lb) # number of blocks
    blk <- split(ts, rep(1:m, each = lb, length.out = n)) # divide into blocks
    #### resample ####
    res <- sample(blk, replace = TRUE, 10)        # resamples the blocks
    res.unlist <- unlist(res, use.names = FALSE)   # unlist the bootstrap series
    #### train, forecast ####
    train <- head(res.unlist, round(length(res.unlist) - 10)) # train set
    test <- tail(res.unlist, length(res.unlist) - length(train)) # test set
    nfuture <- forecast(train, # forecast
                        model = auto.arima(train), 
                        lambda = 0, biasadj = TRUE, h = length(test))$mean    
    ### metric ####
    RMSE <- rmse(test, nfuture) # return RMSE
    return(
      list("RMSE" = RMSE)
    )
}

param_list = list("n" = n, "lb" = lb, "phi" = phi)

要运行模拟,请将参数以及bootstrap1()传递给MonteCarlo()。要并行进行模拟,您需要通过ncpus设置内核数。MonteCarlo软件包使用Snow Fall,因此它应该在Windows上运行。

注意,我还设置了raw=T(否则结果将是所有复制的平均值)。预先设定种子将使结果重现。

set.seed(123)
MC_result <- MonteCarlo(func = bootstrap1, 
                        nrep = reps,
                        ncpus = parallel::detectCores() - 1,
                        param_list = param_list,
                        export_also = list(
                         "packages" = c("forecast", "Metrics")
                        ),
                        raw = T)

结果是一个数组。我认为最好将其转换为数据。帧通过MakeFrame()

Frame <- MakeFrame(MC_result)

不过,很容易得到一个reps x lb矩阵:

matrix(Frame$RMSE, ncol = length(lb), dimnames = list(1:reps, lb))
 类似资料:
  • 我试图模拟来自rho=0.7的AR(1)模型的数据(Y)。然后我将使用这些数据在截距上运行Y的回归(通过这样做,参数估计成为Y的平均值),然后使用鲁棒的标准错误。我想对这个假设运行一个蒙特卡罗模拟,使用2000次重复不同的滞后值。目的是显示当滞后变化时Newey West估计器的有限样本性能 我的问题是:上面的代码是进行这种模拟的正确方法吗?如果是,我如何得到一个代码来重复这个过程在HAC测试中的

  • 我正在写一个蒙特卡罗模拟来检查有多少次y不是紧挨着另一个y。我变出了一个40 x和10 y的向量,放置在向量中的随机位置。我的目标是计算向量中没有任何相邻y的概率。以下是我尝试过的: 结果是一个非常小的数字,这对我来说似乎没有意义。

  • 从名字我们可以看出,MCMC由两个MC组成,即蒙特卡罗方法(Monte Carlo Simulation,简称MC)和马尔科夫链(Markov Chain ,也简称MC)。要弄懂MCMC的原理我们首先得搞清楚蒙特卡罗方法和马尔科夫链的原理。我们将用三篇来完整学习MCMC。在本篇,我们关注于蒙特卡罗方法。 2. 蒙特卡罗方法引入 蒙特卡罗原来是一个赌场的名称,用它作为名字大概是因为蒙特卡罗方法是一种

  • 问题内容: 我已经为“ 2d有效ising模型”编写了蒙特卡洛模拟,并且试图改善运行时间。 我的代码做什么:我为每个粒子(rgrid和mgrid)创建一个用于粒子数量(r)的矩阵和一个用于磁化强度的矩阵。粒子的自旋可以是-1/1,因此磁化强度范围为[-r,r],步长为2。 然后选择一个随机点和一个随机粒子(+1或-1)。由于概率取决于每个位置的正/负粒子数量,因此我创建了2个数组并将其压缩,这样我

  • 我有以下型号 在此处输入图像描述 我需要使用蒙特卡洛实验并获得统计数据。一个例子应该是。 在此处输入图像描述 但在运行时,图形上不会显示任何内容。如何将此统计数据链接到模型?

  • 利用伪随机数生成器(PRNG)对排队型系统进行蒙特卡罗模拟。我使用System.random,因为它速度快,但发现它在后续的绘制之间有某种怪异的相关性,干扰了结果(不够随机)。 现在我使用的是Mersenne Twister(http://takel.jp/mt/mersennetwister.cs),它(到目前为止)已经证明对我的目的来说是足够随机的。它慢了50%,但那是我愿意付出的代价,以得到