parallelパッケージ - parSapply

効率的なRコードの書き方

Colin Gillespie

Jumping Rivers & Newcastle University

applyファミリー

applyファミリーには並列版があります

  • apply()- parApply()
  • sapply()- parSapply()
    • ベクターへの関数適用(forループ相当)
  • lapply()- parLapply()
    • リストへの関数適用
効率的なRコードの書き方

sapply()関数

sapply()はforループの別の書き方です

ループ

for(i in 1:10)
    x[i] <- simulate(i)

次のように書けます

sapply(1:10, simulate)

ベクターの各要素に関数を適用しています

効率的なRコードの書き方

parSapply()への切り替え

手順は同じです!

  1. パッケージの読み込み
  2. クラスターの作成
  3. parSapply()に切り替え
  4. 停止!
効率的なRコードの書き方

例:ポケモンバトル

plot(pokemon$Defense, pokemon$Attack)
abline(lm(pokemon$Attack ~ pokemon$Defense), col = 2)
cor(pokemon$Attack, pokemon$Defense)
0.437

効率的なRコードの書き方

ブートストラップ法

理想的には母集団から再サンプリングしたいが、それは不可能です

代わりに、元のサンプルが母集団を代表すると仮定します

  1. データから_復元_抽出を行う
    • 同じデータ点が複数回現れる場合があります
  2. 新しいサンプルから相関統計量を計算する
  3. 繰り返す
効率的なRコードの書き方

単一のブートストラップ

bootstrap <- function(data_set) {
    # Sample with replacement
    s <- sample(1:nrow(data_set), replace = TRUE)
    new_data <- data_set[s,]

    # Calculate the correlation
    cor(new_data$Attack, new_data$Defense)
}
# 100 independent bootstrap simulations
sapply(1:100, function(i) bootstrap(pokemon))
効率的なRコードの書き方

並列処理への変換

  • パッケージの読み込み
  • コア数の指定
  • クラスターオブジェクトの作成
  • 関数・データのエクスポート
  • parSapply()に切り替え
  • 停止!
library("parallel")
no_of_cores <- 7
cl <- makeCluster(no_of_cores)
clusterExport(cl,
  c("bootstrap", "pokemon"))
parSapply(cl, 1:100,
  function(i) bootstrap(pokemon))
stopCluster(cl)
効率的なRコードの書き方

処理時間の比較

効率的なRコードの書き方

では、練習しましょう!

効率的なRコードの書き方

Preparing Video For Download...