caret: General Topics - Parallel Processingの和訳

訳注
http://topepo.github.io/caret/parallel.html の和訳です

doMCとdoMPIが紹介されてますが、doParallel（ https://cran.r-project.org/web/packages/doParallel/index.html ）の方が現在は使われている気がします。
---
このパッケージではリサンプリングは、パラメータチューニングによる予測モデルの最適化の一番の方法です。これを行うために、トレーニングセットのいろいろなバージョンがモデルトレーニングとhold-outセットの予測に使われます。このプロセスでは、新しいデータセットの一般化を評価するために多くの時間をかけて繰り返し実行を行います。リサンプルデータセットのそれぞれは別のセットとは独立であり、モデルを直列に計算する必要はありません。使っているコンピュータに複数のプロセッサかコアがあれば、これら「働き者」を広く使うことにより計算効率が上がります。caret ではRの並列化フレームワークのいくつかが有効です。foreach パッケージは R コードを直列または並列に実行可能であり、 multicore あるいは Rmpi パッケージ（要約とオプション等の詳細は Schmidberger et al, 2009 参照）を使っています。いくつかの R パッケージは foreach と一緒に使え、それは doMC (multicore 用）あるいは doMPI （Rmpi 用）です。

並列実行を用いて予測モデルのチューニングを行うために、caret パッケージの関数（例 train や rfe あるいは sbf）の書式は変える必要がありません。"register"という関数を並列実行の並列実行数指定に用います。例えば multicore パッケージを使う場合（Windows では使用不可）同じマシンで5コアを用いるならば、以下のようにします：

```r
library(doMC)
registerDoMC(cores = 5)

## All subsequent models are then run in parallel
model <- train(y ~ ., data = training, method = "rf")
```

foreeach に関する別のパッケージの書式ととても似ています。並列実行数を増やす場合、メモリ要求量も増えます。例えば、並列実行数を5とした場合、メモリ上にデータの6つのバージョンを保持できるとします。もしデータが大きいか計算するモデルがメモリをたくさん使う場合に、物理的に使用可能なメモリの制限が効いてくるかもしれません。rfe と sbf について、この関数はいくつかのモデルで train をコールします。この場合、並列実行数を M とすると M^2 のプロセッサを要求することとなります。
このヘルプがモデルフィッティングの時間削減に役立つか？ちょうどいいサイズのデータセット（4,331行と8列）を使っていくつかのモデルで並列実行を試しました。ランダムフォレストは2,000の木を使い mtry の値を10位上にしました。変数の重要度の計算もモデルフィッティングに必要です。線形判別分析と、コスト感度の高いサポートベクターマシン（コスト値を15以上とした）も実施しました。すべてのモデルでは10回のクロスバリデーションを行いました。結果は下図に示しています。y軸は並列実行数に対する実行時間の合計（モデルチューニングとフィッティングを含む）です。ランダムフォレストはトレーニングに最も時間が掛かり、LDA モデルは計算時間がとても少ないです。並列実行数の増加とともに計算時間は減少しますが、並列実行数が7くらいになると計算時間は一定となります。このデータはランダムに一般化しており、計算順について片寄りがありません。一番下の右の図は、並列実行時間で直列な実行時間を割って、スピードアップを示しています。この例では、直列な実行に比べて並列実行により3倍早くなっていることを示しています。(For example, a speed-up of three indicates that the parallel version was three times faster than the sequential version. 訳注：すみません図からは3倍ではないと思うのですが訳が分かりません) 理想的には並列化により線形にスピードアップしてほしいですが、この場合並列実行数をMとすると計算時間が1/Mとなります。これらのモデルでは並列実行数が4あるいは5以下では線形に近いスピードアップをしています。それ以降はスピードアップは鈍ります。LDA は常に計算時間が少ないですがスピードアップも早めに落ちます。線形でなくても、計算時間の減少は有用であり、モデルフィッティングに10時間掛かっていたものが90分に減少します。

いくつかのモデルでは、特に RWeka パッケージを用いる場合は、コードの構造上並列化が行えません。

train、rfe、sbf、bag、avNNet は追加の属性が必要であり、 allowParallel を TRUE にします。TRUE にすると、並列環境（例 doMC）であれば並列化を行います。FALSE にすると、並列環境は常に無視されます。rfeあるいはsbfがtrainをコールする場合において、もし並列実行でP個のプロセッサを指定した場合、P^2個のプロセッサを要求します。他の手法よりも並列化は有効なので、関数に特化した計算リソースを準備することに集中すべきです。

1つの"trick"として、サブモデルを使うことにより、計算の効率が向上します；1つのモデルで複数のチューニングパラメータを予測することが出来ます。例えば、ブースティングモデルを用いるとき、Bよりもイテレーションが少ないモデルをBブースティングモデルで作れます。 gmb モデルの場合のグリッドのチューニングは：

```r
gbmGrid <-  expand.grid(interaction.depth = c(1, 5, 9),
                        n.trees = (1:15)*100,
                        shrinkage = 0.1,
                        n.minobsinnode = 20)
```
実際に、 train ではこれらのオブジェクトから3つのモデルオブジェクトを作ります。このトリックは、以下のモデルで使えます：ada, AdaBag, AdaBoost.M1, bagEarth, blackboost, blasso, BstLm, bstSm, bstTree, C5.0, C5.0Cost, cubist, earth, enet, foba, gamboost, gbm, glmboost, glmnet, kernelpls, lars, lars2, lasso, lda2, leapBackward, leapForward, leapSeq, LogitBoost, pam, partDSA, pcr, PenalizedLDA, pls, relaxo, rfRules, rotationForest, rotationForestCp, rpart, rpart2, rpartCost, simpls, spikeslab, superpc, widekernelpls, xgbTree 。