サーチ…


備考

リモートマシンでの並列化では、各マシンにライブラリをダウンロードする必要があります。 package::function()が好きです。いくつかのパッケージには、 caretplsplyrなどの並列化がネイティブに組み込まれていcaret

Microsoft R Open (Revolution R)は、多くの共通機能を本質的に並列化するマルチスレッドBLAS / LAPACKライ​​ブラリも使用します。

foreachパッケージによる並列処理

foreachパッケージは並列処理能力をRにもたらしますが、マルチコアCPUを使用する前にマルチコアクラスタを割り当てる必要があります。 doSNOWパッケージは1つの可能性があります。

foreachループの簡単な使い方は、平方根と1から100000までのすべての数の平方和を計算することです。

library(foreach)
library(doSNOW)

cl <- makeCluster(5, type = "SOCK")
registerDoSNOW(cl)

f <- foreach(i = 1:100000, .combine = c, .inorder = F) %dopar% {
    k <- i ** 2 + sqrt(i)
    k
} 

foreachの出力の構造は、 .combine引数によって制御されます。デフォルトの出力構造はリストです。上記のコードでは、代わりにcを使用してベクトルを返します。 "+"などの計算関数(または演算子)を使用して計算を実行し、さらに処理されたオブジェクトを返すこともできます。

それぞれのforeach-loopの結果が最後の呼び出しであることに言及することは重要です。したがって、この例では、 kが結果に加算されます。

パラメータ 詳細
.combine 関数を結合する。ループの結果をどのように組み合わせるかを決定します。可能な値はccbindrbind"+""*" ...です。
。順番に TRUEの場合、結果は反復可能な順序(ここではi )に従って並べられます。 FALSE 、結果は順序付けされません。これは、計算時間に影響を与える可能性があります。
パッケージ base以外のパッケージ、例えばmassrandomForestなどで提供される関数の場合、これらのパッケージにはc("mass", "randomForest")を指定する必要があります

並列パッケージによる並列処理

基本パッケージparallelは、フォーク、ソケット、および乱数生成による並列計算を可能にします。

ローカルホスト上に存在するコアの数を検出します。

parallel::detectCores(all.tests = FALSE, logical = TRUE)

localhostにコアのクラスタを作成します。

parallelCluster <- parallel::makeCluster(parallel::detectCores())

まず、並列化に適した関数を作成する必要があります。 mtcarsデータセットを考えてみましょう。 cyl各レベルについて個別の回帰モデルを作成することで、 mpgの回帰を改善できます。

data <- mtcars
yfactor <- 'cyl'
zlevels <- sort(unique(data[[yfactor]]))
datay <- data[,1]
dataz <- data[,2]
datax <- data[,3:11]


fitmodel <- function(zlevel, datax, datay, dataz) {
  glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}

zlevelsすべての可能な反復をループすることができる関数を作成します。これはまだシリアルで行われていますが、並列化される正確なプロセスを決定する重要なステップです。

fitmodel <- function(zlevel, datax, datay, dataz) {
  glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}


for (zlevel in zlevels) {
  print("*****")
  print(zlevel)
  print(fitmodel(zlevel, datax, datay, dataz))
}

カレーこの機能:

worker <- function(zlevel) {
    fitmodel(zlevel,datax, datay, dataz)
  }

パラレルを使用parallel並列コンピューティングは、地球環境にはアクセスできません。幸運なことに、各機能はローカル環境のparallelアクセスを作成します。ラッパー関数を作成すると、並列化が可能になります。適用される機能も環境内に配置する必要があります。

wrapper <- function(datax, datay, dataz) {
  # force evaluation of all paramters not supplied by parallelization apply
  force(datax)
  force(datay)
  force(dataz)
  # these variables are now in an enviroment accessible by parallel function
  
  # function to be applied also in the environment
  fitmodel <- function(zlevel, datax, datay, dataz) {
    glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
  }
  
  # calling in this environment iterating over single parameter zlevel
  worker <- function(zlevel) {
    fitmodel(zlevel,datax, datay, dataz)
  }
  return(worker) 
}

今すぐクラスターを作成し、ラッパー関数を実行します。

parallelcluster <- parallel::makeCluster(parallel::detectCores())
models <- parallel::parLapply(parallelcluster,zlevels,
                              wrapper(datax, datay, dataz))

完了したら、必ずクラスタを停止してください。

parallel::stopCluster(parallelcluster)

parallelパッケージは全体が含まapply()が付い家族、 par

乱数生成

並列化の大きな問題は、RNGをシードとして使用することです。数値による乱数は、セッションの開始または最新のset.seed()いずれかからの操作の数によって反復されます。並列処理は同じ関数から発生するため、同一のシードを使用することができ、同じ結果が生じる可能性があります。コールは、さまざまなコアでシリアルに実行され、利点を提供しません。

一連のシードを生成して各並列プロセスに送信する必要があります。これはいくつかのパッケージ( parallelsnowなど)で自動的に行われますが、他のパッケージでは明示的に対処する必要があります。

s <- seed
for (i in 1:numofcores) {
    s <- nextRNGStream(s)
    # send s to worker i as .Random.seed
}

種子を再現性のために設定することもできます。

clusterSetRNGStream(cl = parallelcluster, iseed)

mcparallelDo

mcparallelDoパッケージを使用すると、UNIX系(LinuxやMacOSXなど)のオペレーティングシステムでRコードを非同期的に評価することができます。パッケージの根底にある考え方は、コーディングではなく、探索的データ分析のニーズに合わせています。非同期をコーディングするには、 futureパッケージを考慮してください。

データを作成する

data(ToothGrowth)

フォーク上で分析を実行するためにmcparallelDoをトリガする

mcparallelDo({glm(len ~ supp * dose, data=ToothGrowth)},"interactionPredictorModel")

他のこと、例えば

binaryPredictorModel <- glm(len ~ supp, data=ToothGrowth)
gaussianPredictorModel <- glm(len ~ dose, data=ToothGrowth)

mcparallelDoの結果はtargetEnvironmentなどで返されます(例:.GlobalEnv)。メッセージが完了すると(デフォルトでは)

summary(interactionPredictorModel)

その他の例

# Example of not returning a value until we return to the top level
for (i in 1:10) {
  if (i == 1) {
    mcparallelDo({2+2}, targetValue = "output")
  }
  if (exists("output")) print(i)
}

# Example of getting a value without returning to the top level
for (i in 1:10) {
  if (i == 1) {
    mcparallelDo({2+2}, targetValue = "output")
  }
  mcparallelDoCheck()
  if (exists("output")) print(i)
}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow