2012-08-08 71 views
5

我有一個問題找到最有效的方法來計算多列xts對象的滾動線性迴歸。我已經在這裏搜索和閱讀了幾個以前的問題在stackoverflow。多列滾動迴歸

這個question and answer接近但在我看來是不夠的,因爲我想計算多個迴歸,因變量在所有迴歸中保持不變。我試圖再現與隨機數據的示例:爲了隨着時間的推移,每個因子多個變量(殘差係數等)存儲創建

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]作爲因變量(因子)對其他的因素之一每次運行30個觀察滾動迴歸。由於fastLm不計算標準化殘差,因此我必須將30個殘差存儲在臨時對象中以便將它們標準化。

如果xts對象中的列(因子)數量增加到大約100 - 1000列,則循環非常緩慢並且變得非常麻煩,這將需要一個永恆。我希望有一個更高效的代碼來創建大型數據集上的滾動迴歸。

+0

通過不運行迴歸兩次,我可以將它編輯成您的問題。 – 2012-08-08 21:25:02

+0

當然可以!這在歐洲很晚。謝謝約書亞。 該變化使性能提高了2-2.5倍。但是,您是否認爲該代碼對2500個每日觀察數據集和1000個因子具有足夠的性能? 或者您是否知道使用rollapply與上述方法相比有哪些性能提升? 我想如果數據集變得非常大,你必須應用遞歸最小二乘濾波器或相關的東西 - 對此的任何想法? – 2012-08-08 21:42:09

回答

8

如果你下降到線性迴歸的數學水平,它應該是非常快的。如果X是自變量,Y是因變量。該係數由

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

給我有點混淆有關的變量,你想成爲的依賴性和哪一個是獨立的,但希望解決以下類似的問題會幫助你。

在下面的例子中,我取1000個變量而不是原來的5,並且不引入任何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的任何錯誤應該給你的標準化殘差。請隨時修復此解決方案以糾正任何錯誤。

+0

+1爲直接的方法。 – ricardo 2012-08-27 20:01:26