7

複数の列を持つ xts オブジェクトに対してローリング線形回帰を計算する最も効率的な方法を見つけるのに問題があります。ここで、stackoverflow に関するいくつかの以前の質問を検索して読みました。

この質問と回答は近いですが、すべての回帰で従属変数を変更せずに多重回帰を計算したいので、私の意見では十分ではありません。ランダムデータを使用して例を再現しようとしました:

require(xts)
require(RcppArmadillo)  # Load libraries

data <- matrix(sample(1:10000, 1500), 1500, 5, byrow = TRUE)  # Random data
data[1000:1500, 2] <- NA  # insert NAs to make it more similar to true data
data <- xts(data, order.by = as.Date(1:1500, origin = "2000-01-01"))

NR <- nrow(data)  # number of observations
NC <- ncol(data)  # number of factors
obs <- 30  # required number of observations for rolling regression analysis
info.names <- c("res", "coef")

info <- array(NA, dim = c(NR, length(info.names), NC))
colnames(info) <- info.names

配列は、複数の変数 (残差、係数など) を経時的に因子ごとに格納するために作成されます。

loop.begin.time <- Sys.time()

for (j in 2:NC) {
  cat(paste("Processing residuals for factor:", j), "\n")
  for (i in obs:NR) {
    regression.temp <- fastLm(data[i:(i-(obs-1)), j] ~ data[i:(i-(obs-1)), 1])
    residuals.temp <- regression.temp$residuals
    info[i, "res", j] <- round(residuals.temp[1] / sd(residuals.temp), 4)
    info[i, "coef", j] <- regression.temp$coefficients[2]
  } 
}

loop.end.time <- Sys.time()
print(loop.end.time - loop.begin.time)  # prints the loop runtime

data[, 1]ループが示すように、アイデアは、従属変数 (因子) を他の因子の 1 つに対して毎回使用して、30 観測のローリング回帰を実行することです。fastLmは標準化された残差を計算しないため、それらを標準化するために一時オブジェクトに 30 の残差を保存する必要があります。

xts オブジェクトの列 (因子) の数が約 100 ~ 1,000 列に増えると、ループが非常に遅くなり、面倒になります。大規模なデータセットに対してローリング回帰を作成するためのより効率的なコードがあることを願っています。

4

2 に答える 2

10

線形回帰の数学のレベルまで下がると、かなり速くなるはずです。X が独立変数で、Y が従属変数の場合。係数は次の式で与えられます。

Beta = inv(t(X) %*% X) %*% (t(X) %*% Y)

どの変数が従属変数でどれが独立変数かについて少し混乱していますが、以下の同様の問題を解決することも役に立ちます。

以下の例では、元の 5 つの変数の代わりに 1000 の変数を使用し、NA を導入していません。

require(xts)

data <- matrix(sample(1:10000, 1500000, replace=T), 1500, 1000, byrow = TRUE)  # Random data
data <- xts(data, order.by = as.Date(1:1500, origin = "2000-01-01"))

NR <- nrow(data)  # number of observations
NC <- ncol(data)  # number of factors
obs <- 30  # required number of observations for rolling regression analysis

これで、Joshua の TTR パッケージを使用して係数を計算できます。

library(TTR)

loop.begin.time <- Sys.time()

in.dep.var <- data[,1]
xx <- TTR::runSum(in.dep.var*in.dep.var, obs)
coeffs <- do.call(cbind, lapply(data, function(z) {
    xy <- TTR::runSum(z * in.dep.var, obs)
    xy/xx
}))

loop.end.time <- Sys.time()

print(loop.end.time - loop.begin.time)  # prints the loop runtime

時差3.934461秒

res.array = array(NA, dim=c(NC, NR, obs))
for(z in seq(obs)) {
  res.array[,,z] = coredata(data - lag.xts(coeffs, z-1) * as.numeric(in.dep.var))
}
res.sd <- apply(res.array, c(1,2), function(z) z / sd(z))

索引付けにエラーがres.sdなければ、標準化された残差が得られるはずです。バグを修正するために、このソリューションを自由に修正してください。

于 2012-08-09T14:12:29.547 に答える