More Related Content Similar to Rによる高速処理 まだfor使ってるの? (20) Rによる高速処理 まだfor使ってるの?9. 『forを使うな』 第一弾
9
system.time({
vec <- seq1 + seq2
})
## user system elapsed
## 0.006 0.000 0.006
N <- 1000000
vec <- integer(N)
seq1 <- seq2 <- 1:N
system.time({
for(i in 1:N) vec[i] <- seq1[i] + seq2[i]
})
## user system elapsed
## 1.749 0.037 1.831
ベクトル化前
ベクトル化後
高速化の例
10. なぜ出来るか?
⇒ 関数がベクトル演算に対応しているから
10
sqrt(1:3)
## [1] 1.000000 1.414214 1.732051
iconv(c("あ", "い", "う"), to = "shift-jis")
## [1] "x82xa0" "x82xa2" "x82xa4"
できる例
できない例
Nippon::zen2han(c("1", "4", "16"))
## [1] "1416"
Warning message:
In if (Encoding(s) != "UTF-8") s <- iconv(s, from = "", to = "UTF-8") : the
condition has length > 1 and only the first element will be used
14. foreach パッケージ
• Revolution Analytics社が開発
• forと同じような使い方でわかりやすい
• applyファミリのように使い分ける必要なし
• 返り値を返す
• イテレータを使った省メモリループ
• 並列化をサポート
14
37. 結合の引数 --> .c (.combine)
37
pforeach(i = 1:3, .c = c) (sqrt(i))
## [1] 1.000000 1.414214 1.732051
pforeach(i = 1:3, .c = list) (sqrt(i))
## [[1]]
## [1] 1
##
## [[2]]
## [1] 1.414214
##
## [[3]]
## [1] 1.732051
##
pforeach(i = 1:3, .c = rbind) (sqrt(i))
## [,1]
## result.1 1.000000
## result.2 1.414214
## result.3 1.732051
デフォルトは c 関数
時々使う?
list 関数
割と使いそう
rbind 関数
38. 並列のオン・オフ
38
pforeach(i = 1:3, .parallel = FALSE) (sqrt(i))
## [1] 1.000000 1.414214 1.732051
npforeach(i = 1:3) (sqrt(i))
## [1] 1.000000 1.414214 1.732051
方法① .parallel = FALSEを付ける
方法② pforeachではなくnpforeachを使う
非並列
非並列
pforeachはデフォルトで並列化
デバック時など,非並列化したいときがある
pforeach(i = 1:3) (sqrt(i))
## [1] 1.000000 1.414214 1.732051
44. 参考
• URL
– for を捨てよ、foreach を書こう
– R で超簡単に並列処理を書けるpforeach パッケージ
– R で超簡単に並列処理を書けるパッケージ pforeach
を作った - ほくそ笑む
– foreachについてまとめたい - J's blog
– foreachでprogressbarを表示する - J's blog
• 書籍
– 『Rによるハイパフォーマンスコンピューティング』
44
49. 余談
• 並列対応のR
– pqR(ただし2系のRのみ)
– Microsoft R
• 高速化ライブラリ
– OpenBLAS(BLASという数値計算ライブラリ)
– Intel MKL(並列化可能な数値計算ライブラリ)
• Rcpp
– 参考
(https://www.gitbook.com/book/teuder/introducti
on-to-rcpp/details/ja)
49
Editor's Notes ####
library(dplyr)
cl <- makeCluster(3)
registerDoParallel(cl)
foreach(i = 1:150, .packages = "dplyr") %dopar% {
iris[i, ] %>% select(-Species) %>% sum
}
stopCluster(cl)
####
square <- function(x) x**2
execute <- function() {
cl <- makeCluster(3)
registerDoParallel(cl)
foreach(i = 1:150, .export = "square") %dopar% {
square(i)
}
stopCluster(cl)
}
execute()
####
library(foreach)
library(doParallel)
cl <- makeCluster(3)
registerDoParallel(cl)
foreach(i = 1:3) %dopar% {
sqrt(i)
}
stopCluster(cl)
####
library(pforeach)
pforeach(i=1:3) ({
sqrt(i)
})
####
pforeach(i = 1:3, .c = c) (sqrt(i))
pforeach(i = 1:3, .c = list) (sqrt(i))
pforeach(i = 1:3, .c = rbind) (sqrt(i))
####
pforeach(i = 1:3) (sqrt(i))
pforeach(i = 1:3, .parallel = FALSE) (sqrt(i))
npforeach(i = 1:3) (sqrt(i))
####
pforeach(i=1:3, .cores = 2) ({
i ** 2
})
####
pforeach(i=1:3, .seed = 71) ({
i ** 2
})
####
library(foreach)
library(kernlab)
library(randomForest)
library(doParallel)
data(spam)
cores <- detectCores()
cl <- makePSOCKcluster(cores)
registerDoParallel(cl)
fit.rf <- foreach(ntree = rep(250, cores),
.combine = combine,
.export = "spam",
.packages = "randomForest") %dopar% {
randomForest(type ~ ., data = spam, ntree = ntree)
}
stopCluster(cl)
####
library(pforeach)
library(kernlab)
library(randomForest)
data(spam)
fit.rf <- pforeach(ntree = rep(250, .cores),
.c = combine) ({
randomForest(type ~ ., data = spam, ntree = ntree)
})
####
pb <- function(N, FUN = c) {
pbar <- txtProgressBar(min = 2, max = N, style = 3)
count <- 0L
if(is.character(FUN)) {
FUN <- get(FUN)
}
function(...) {
count <<- count + length(list(...)) - 1L
setTxtProgressBar(pbar, count)
if(count == (N-1)) {
cat("\n")
}
FUN(...)
}
}
####
N <- 10000
pforeach(i = 1:N, .combine = pb(N), .multicombine = TRUE) ({
sqrt(i)
})[1:10]