[英]Vectorization using apply family of functions in R
我正在使用線性回歸 model,我想手動計算一些性能指標。 我使用 Leave One Out Cross-Validation (LOOCV) 拆分數據。
下面的 R 代碼給了我想要的結果,但需要很長時間,因為我使用的是帶有 LOOCV 的 for 循環。
有沒有辦法快速重寫我的代碼,例如,在 R 中應用一系列函數?
數據集從這里上傳
wdbc <- read_excel("Folds5x2_pp.xlsx")
wdbc[] <- lapply(wdbc, scale)
dim(wdbc)
9568 5
head(wdbc)
1 -0.629 -0.987 1.82 -0.00952 0.521
2 0.742 0.681 1.14 -0.975 -0.586
3 -1.95 -1.17 -0.185 1.29 2.00
4 0.162 0.237 -0.508 0.228 -0.462
5 -1.19 -1.32 -0.678 1.60 1.14
6 0.888 0.404 -0.173 -0.996 -0.627
fitted_value <- rep(0,nrow(wdbc))
for(i in 1:nrow(wdbc)){
test<-wdbc[i,]
training<-wdbc[-i,]
m=lad(PE ~ ., data=training, method="BR")
co.data = coef(m)
x = cbind(1, as.matrix(test[, !(colnames(test) %in% "PE")]))
fitted_value[i] <- x %*% co.data
}
R2<-(cor(wdbc$PE,fitted_value)^2)
SAD<-sum(abs(wdbc$PE-fitted_value))
c(round(SAD,2) ,round(R2,2))
注1
問題中使用的數據僅用於解釋,因為在我的項目中,我有許多高維度的數據集。
編輯
根據@Dominic van Essen 的回答,我使用了來自parallel
package 的parSapply
function 的以下 R 代碼,但它需要的時間比 for 循環多。
library(parallel)
mycluster=makeCluster(detectCores()-1)
wdbc <- read_excel("Folds5x2_pp.xlsx")
wdbc[] <- lapply(wdbc, scale)
clusterExport(mycluster,c("lad","wdbc"))
fitted_value = parSapply(mycluster,seq_len(nrow(wdbc)),function(i) {
for(i in 1:nrow(wdbc)){
test<-wdbc[i,]
training<-wdbc[-i,]
m=lad(PE ~ ., data=training, method="BR")
co.data = coef(m)
x = cbind(1, as.matrix(test[, !(colnames(test) %in% "PE")]))
}
return (x %*% co.data)
})
筆記2
我有 8 個核心,“PE”是我數據集中的因變量。
您可以使用sapply
而不是for...
輕松地重新編寫循環,盡管正如 bzki 評論的那樣,僅此一項不會加快您的代碼:
# sapply version:
fitted_value = sapply(seq_len(nrow(wdbc)),function(i) {
# put all the gubbins in here
# ...
return (x %*% co.data)
})
但是,如果您的計算機上有多個可用內核,或者 - 甚至更好 - 訪問具有許多處理器的服務器,則可以使用“並行” parSapply
中的 parSapply 輕松並行化sapply
循環,如下例所示:
# slow sapply loop (takes 12s):
data=123
answer = sapply(1:12,function(i) {
Sys.sleep(1)
return(data+i)
})
# faster parallel version (takes 4s on my laptop with 4 cores):
library(parallel)
mycluster=makeCluster(detectCores()-1) # leave 1 core available for system
data=123
clusterExport(mycluster,"data") # specify variable(s) that should be available to parallel function
answer = parSapply(mycluster,1:12,function(i) {
Sys.sleep(1)
return(data+i)
})
stopCluster(mycluster)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.