時間序列

R:在(真正的)大面板上執行多元回歸的快速有效的方法(Fama MacBeth 的第一遍)

  • June 10, 2015

我正在嘗試對一組 5000 隻股票進行滾動多元回歸(14 個解釋變數):

  • 對於 5000 隻股票中的每一隻,我執行 284 次回歸(通過滾動我的樣本期)。
  • 總而言之:面板總共執行了 1,420,000 次回歸。

為了實現這一點,我使用了一個嵌套的“for循環”:在證券和時間上循環。係數被導出到 csv 文件。

正如預期的那樣,問題在於整個過程需要大量時間才能完成。有沒有一種有效的方法來處理這個問題?(當我意識到“apply”函式比“for循環”更有效時,請記住,考慮到巨大的處理時間,從“apply”函式的替代使用中獲得的時間仍然是最小的)。

這是程式碼的快照:

sec = ncol(ret.zoo)
num.factors = ncol(data)
rows = nrow(ret.zoo) - 60 + 1
col.names <- c("gvkey", "date", "intercept", colnames(data))
write.table(as.data.frame(t(col.names)), file = paste(path, "betas.csv", sep = ""),  row.names = FALSE, col.names = FALSE, sep = ",")

for(i in 1:sec) {   
   beta = data.frame(matrix(nc = num.factors + 3, nr = rows))
   df = merge(ret.zoo[,i], data)
   names(df) <- c("return", names(data))

   for(j in 1:rows) {
       #Checks if number of observations >=30. If so, regression is ran. Otherwise, it is not.
       no.na = ret.zoo[j:(j+59),i][which(!is.na(coredata(ret.zoo[j:(j+59),i])))]
       if(length(no.na) >= 30) {
           beta[j,1] = substr(colnames(ret.zoo)[i],2,7)
           beta[j,2] = as.character(index(df[(j+59),])) ### Date
           beta[j,3:(num.factors+3)] = coef(lm(return ~., data = as.data.frame(df[j:(j+59),]), na.action = na.omit))
       }
   }
   write.table(beta, file = paste(path, "betas.csv", sep = ""), append = T, sep = ",", row.names = FALSE, col.names = FALSE)
   rm(beta)    
}

注意:

  • sec:股票(證券)的數量。每個證券都有一個時間序列的回報。
  • 行:時間段數(我們在其上滾動回歸)
  • beta:每種證券的所有回歸係數矩陣。每次每秒鍾清除一次。

模型:

這是每個證券i在時間t的回歸模型:

R(i,t) = a(i,t) + b1(i,t)f1(t) + b2(i,t)f2(t) + …. + bn(i,t)fn(t ) + e(i,t)

其中b是回歸係數,f是因子,e是殘差。

請注意,

$$ 1:5000 $$,因子數n為 14,時間t在$$ 1:343 $$(343 個月)。

  • 對於每個證券i,我們在 60 個月的滾動週期內執行此回歸(因此 R 程式碼中的 j:j+59)。
  • 僅當因變數的滾動視窗的非 NA觀察次數 >= 30 時,才執行每個滾動回歸(雖然自變數不能為 NA,但因變數(此處為股票收益)可以取 NA 值,如果股票從指數中下跌)。
  • 然後,我們為每個證券i的每個因子f獲得284 = 343 - 60 + 1 個beta 係數。這些儲存在“beta”數據幀中(“beta”數據幀的 nr = 284,ncol = 14+3(14 個因子、截距、日期和標識符)。

因此,總而言之,我們對每種證券進行 284 次回歸,總共有 5000 只證券。總共有 1,420,000 次回歸。

從某種角度來看,執行此腳本大約需要 50 分鐘才能成功完成。

謝謝,

這不完全是我所說的高級,但在並行 foreach 循環中在單獨的核心上執行每個回歸會有所幫助

http://cran.r-project.org/web/packages/foreach/foreach.pdf

您似乎正在使用每個新數據點重新執行回歸。相反,您應該使用更新/線上公式(請參閱stats.se上著名的 Huber 博士的出色回答)。

您可以在 R 包biglm中找到實現。如果它沒有您需要的所有功能(沒有舊數據的視窗),您至少可以對其進行調整併使用它來對您自己的工作進行單元測試。

引用自:https://quant.stackexchange.com/questions/8697