先日、潜在クラス分析のBLRT、要するにブートストラップを走らせるとやたらと時間がかかった。999回に設定してあることが大きな原因になっているが、Rががシングルコア処理をしているのも原因ではないかと考え、並列処理について検討してみた。MplusであればCPUのコア数を指定するコマンドがあるので、Rでもできないかと考え、試してみた。
ちなみに、先のエントリで実行したのは下記のスクリプトである。
library(randomLCA) data(dentistry) dentistry.lca2 <- randomLCA(dentistry[,1:5],freq=dentistry$freq,nclass=2) dentistry.lca3 <- randomLCA(dentistry[,1:5],freq=dentistry$freq,nclass=3) obslrt <- 2*(logLik(dentistry.lca3)-logLik(dentistry.lca2)) ## 以下BLRT nsims <- 999 thesims <- simulate(dentistry.lca2, nsims) simlrt <- rep(NA,nsims) for (isim in 1:nsims) { submodel <- refit(dentistry.lca2,newpatterns=thesims[[isim]]) fullmodel <- refit(dentistry.lca3,newpatterns=thesims[[isim]]) simlrt[isim] <- 2*(logLik(fullmodel)-logLik(submodel)) }
以下BLRTの所が時間がかかる場所。
処理時間の計測
処理時間は次のようにすると計測できるようだ。標準機能である。
stat.ethz.ch
ptm<-proc.time() スクリプト proc.time()-ptm
処理時間を知りたいスクリプトをサンドウィッチすると計測できる。
シングルコアでの計測
上記のBLRTの部分を走らせた結果が以下。。
ユーザ システム 経過 272.84 0.75 273.61
ユーザーがRが実際に動いていたCPU時間で、経過が実際の経過時間なので273.61秒ということになる。
Microsoft R Open
Microsoft R OpenはCPUコア数を自動で判断して並列処理をする機能がある。
Microsoft R Openについてはこちらを参照のこと。
RStudioでMicrosoft R Open 3.5.3を動かすと以下のようにCPU使用率が変わった。
いい感じで並列処理がされている。
処理時間は以下のようになった。
ユーザ システム 経過 1303.42 0.62 340.08
速くなっているのかなと思ったら、遅くなっていた。あれれ?
ユーザの時間の増加はマルチコア処理がされていてCPUの使用時間の総計が多くなっているためだろう。ユーザー時間が増えて、経過時間が遅くなっているということは、並列処理をしても早くならない、計算を仕分けしたり統合したりしていると、余計に時間がかかる、ことだろうか。
doSNOW
Rでは並列化させてた処理をする方法はいくつかある。代表的なdoSNOWパッケージを利用してみた。
下記のシミュレーションでもdoSNOWは良い値を出している。
インストールして呼び出し、処理するスクリプトを下記のようにサンドイッチする。
atm<-proc.time() library(doSNOW) cl.SOCK <- makeCluster(12, type="SOCK") registerDoSNOW(cl.SOCK) スクリプト stopCluster(cl.SOCK) proc.time()-atm
結果は下記。
ユーザ システム 経過 290.06 1.09 295.94
結果は悪くないが、並列化をしないよりもやや遅い。
考察
結果失敗である。
スクリプトが並列化に対応すれば、処理も早くなるのだろうが、今の形では速くはならないようだ。
ベイズ統計学をするときにも並列化は必要になるが、RStanには並列化のコマンドがデフォルトで存在しているのでMicrosoft R OpenやdoSNOWは不要である。
ブートストラップは他の分析でも使用するが、今のところ僕は潜在クラス分析の時くらいしか使わないし、人生でそれほど数を走らせるわけではないので、時間とコストを考えると何も考えずシングルコアに頑張ってもらうのでもいいのかもしれない。