蒙特卡罗模拟两个布朗运动之间的相关性(连续随机游走)

时间:2016-10-09 13:26:37

标签: r loops simulation montecarlo

y <- cumsum(rnorm(100,0,1)) # random normal, with small (1.0) drift.
y.ts <- ts(y)
x <- cumsum(rnorm(100,0,1))
x
x.ts <- ts(x)
ts.plot(y.ts,ty= "l", x.ts) # plot the two random walks 


Regression.Q1 = lm(y~x) ; summary(lm2) 
summary(Regression.Q1)

t.test1 <- (summary(Regression.Q1)$coef[2,3]) # T-test computation 


y[t] = y[t-1] + epsilon[t]
epsilon[t] ~ N(0,1)
set.seed(1)
t=1000
epsilon=sample(c(-1,1), t, replace = 1) # Generate k random walks across time {0, 1, ... , T}


N=T=1e3
y=t(apply(matrix(sample(c(-1,1),N*T,rep=TRUE),ncol=T),1,cumsum))
y[1]<-0
for (i in 2:t) {
  y[i]<-y[i-1]+epsilon[i]
}

我需要:

重复该过程1,000次(蒙特卡罗模拟),即围绕前一个程序构建一个循环,每次保存t统计量。您将有一个1 000次t检验的序列:S =(t-test1,t-test2,...,t-test1000)。计算1000次t检验的绝对值&gt;的计数。 1.96,临界值为5%显着性水平。如果系列是我(0)你会发现大约5%。这不是这种情况(虚假回归)。

我需要添加什么来保存相应的系数?

1 个答案:

答案 0 :(得分:3)

您发布的与y[t] = y[t-1] + epsilon[t]相关的代码不是真正的工作代码,但我可以看到您正在尝试存储所有1000 * 2随机游走。实际上没有必要这样做。我们只关心t-score而不是那些随机游走的实现。

对于这种问题,我们的目标是多次复制一个过程,首先编写一个函数来执行一次这样的过程是很方便的。你已经拥有了良好的工作代码;我们只需要将它包装在一个函数中(删除那些不必要的部分,如plot):

sim <- function () {
  y <- cumsum(rnorm(100,0,1))
  x <- cumsum(rnorm(100,0,1))
  coef(summary(lm(y ~ x)))[2,3]
  }

此功能不输入;它只返回一个实验的t分数。

现在,我们将重复这1000次。我们可以编写for循环,但函数replicate更容易(如有必要,请阅读?replicate

S <- replicate(1000, sim())

注意这需要一些时间,比这个简单的任务要慢得多,因为lmsummary.lm都很慢。一个更快的方法将在稍后展示。

现在,S是具有1000个值的向量,这是您想要的“1000次t检验序列”。要获得“1,000次测试的绝对值&gt; 1.96”的时间,我们可以使用

sum(abs(S) > 1.96)
# [1] 756

结果756就是我得到的;你会得到一些不同的东西,因为模拟是随机的。但它总是如预期的那么大。

sim的更快版本

fast_sim <- function () {
  y <- cumsum(rnorm(100,0,1))
  x <- cumsum(rnorm(100,0,1))
  y <- y - mean(y)
  x <- x - mean(x)
  xty <- crossprod(x,y)[1]
  xtx <- crossprod(x)[1]
  b <- xty / xtx
  sigma <- sqrt(sum((y - x * b) ^ 2) / 98)
  b * sqrt(xtx) * sigma
  }

此函数计算不带lm的简单线性回归,不带summary.lm的t得分。

S <- replicate(1000, fast_sim())
sum(abs(S) > 1.96)
# [1] 778

另一种方法是使用cor.test

fast_sim2 <- function () {
  y <- cumsum(rnorm(100,0,1))
  x <- cumsum(rnorm(100,0,1))
  unname(cor.test(x, y)[[1]])
  }

S <- replicate(1000, fast_sim())
sum(abs(S) > 1.96)
# [1] 775

让我们有一个基准:

system.time(replicate(1000, sim()))
#   user  system elapsed 
#  1.860   0.004   1.867 

system.time(replicate(1000, fast_sim()))
#   user  system elapsed 
#  0.088   0.000   0.090 

system.time(replicate(1000, fast_sim2()))
#   user  system elapsed 
#  0.308   0.004   0.312 

cor.testlm + summary.lm快得多,但手动计算速度更快!