14

いくつかのランダム フォレスト (回帰用) をトレーニングして、それらを競合させ、どの機能選択とどのパラメーターが最適なモデルを提供するかを確認しようとしています。

しかし、トレーニングには非常に時間がかかるようで、何か間違ったことをしているのだろうかと思っています.

私がトレーニングに使用しているデータセット (以下で呼び出されtrainます) には 217,000 行、58 列があります (ランダム フォレストで予測子として機能するのはそのうちの 21 のみです。クラスのブール値を除いて、それらはすべてnumericorです) .出力は) です。integercharacterynumeric

次のコードを 4 回実行して、値41005002000を指定しましたnb_trees

library("randomForest")
nb_trees <- #this changes with each test, see above
ptm <- proc.time()
fit <- randomForest(y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 
    + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 
    + x20 + x21, 
    data = train, 
    ntree = nb_trees, 
    do.trace=TRUE)
proc.time() - ptm

それぞれのトレーニングにかかった時間は次のとおりです。

nb_trees | time
4          4mn
100        1h 41mn
500        8h 40mn
2000       34h 26mn

私の会社のサーバーには 12 コアと 125Go の RAM があるので、この回答に従って、トレーニングを並列化できると考えました(ただし、doParallelパッケージを使用したのdoSNOWは、.私が見た場所も見つけられませんでしたdoParallel、申し訳ありません)。

library("randomForest")
library("foreach")
library("doParallel")
nb_trees <- #this changes with each test, see table below
nb_cores <- #this changes with each test, see table below
cl <- makeCluster(nb_cores)
registerDoParallel(cl)
ptm <- proc.time()
fit <- foreach(ntree = rep(nb_trees, nb_cores), .combine = combine, .packages = "randomForest") 
    %dopar% {
        randomForest(y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 
        + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 
        + x20 + x21,
        data = train, 
        ntree = ntree,
        do.trace=TRUE)}
proc.time() - ptm
stopCluster(cl)

実行すると、並列化されていないコードよりも時間がかかりません。

nb_trees | nb_cores | total number of trees              | time
1          4          4                                    2mn13s
10         10         100                                  52mn
9          12         108 (closest to 100 with 12 cores)   59mn
42         12         504 (closest to 500 with 12 cores)   I won't be running this one
167        12         2004 (closest to 2000 with 12 cores) I'll run it next week-end

とはいえ、まだまだ時間がかかると思いますよね?ツリーを最終的なフォレストに結合するのに時間がかかることは承知しているので、12 コアで 12 倍高速になるとは思っていませんでしたが、〜 2 倍しか高速ではありません...

  • これは正常ですか?
  • そうでない場合、実行時間を根本的に短縮するために、データやコードでできることはありますか?
  • そうでない場合は、サーバーの担当者にもっと高速にする必要があることを伝えるべきですか?

回答ありがとうございます。

ノート :

  • このサーバーを使用しているのは私だけです
  • 次のテストでは、ランダム フォレストで使用されていない列を削除します。
  • randomForest(predictors,decision)の代わりに呼び出すことで実行時間を改善できることにかなり遅れて気づきましたrandomForest(decision~.,data=input)。これからもそうしますが、上記の質問はまだ有効だと思います。
4

3 に答える 3

9

私は、並列化や非常に長い時間コードを実行するなどのブルート フォース テクニックのファンですが、ブルート フォース テクニックを使用する必要がないようにアルゴリズムを改善することのさらに大きなファンです。

2000 本の木を使用してランダム フォレストをトレーニングすると法外なコストがかかり始めましたが、より少ない数の木を使用したトレーニングにはより妥当な時間がかかりました。まず、たとえば4, 8, 16, 32, ...,ツリーでトレーニングし256512メトリックを注意深く観察して、モデルの堅牢性を知ることができます。これらのメトリクスには、最適な定数モデル (すべての入力の中央値を予測するモデルと比較して、フォレストがデータ セットに対してどの程度うまく機能するか) や out-of-bag エラーが含まれます。さらに、上位の予測因子とその重要性、およびツリーを追加するにつれてそこに収束が見られるようになるかどうかを観察できます。

理想的には、モデルを構築するために何千ものツリーを使用する必要はありません。モデルが収束し始めたら、さらにツリーを追加してもモデルが悪化するわけではありませんが、同時に新しい情報は追加されません。あまり多くのツリーを使用しないようにすることで、1 週間程度かかっていた計算を 1 日未満に短縮できる場合があります。これに加えて、十数個の CPU コアを活用すると、数時間単位で何かを見ている可能性があります。

各ランダム フォレストの実行後に変数の重要度を調べるには、次の行に沿って何かを試すことができます。

fit <- randomForest(...)
round(importance(fit), 2)

最初に言う 5 ~ 10 個の予測子がモデルに最も大きな影響を与えることを私は理解しています。ツリーを増やしても、これらの上位の予測子の相対的な位置が実際には変わらず、重要度のメトリックが同じままであることに気付いた場合は、あまり多くのツリーを使用しないことを検討してください。

于 2016-05-12T14:54:45.157 に答える
5

このrandomForest()関数は、「フォーミュラ インターフェイス」または「マトリックス インターフェイス」のいずれかを使用してデータを受け取ることができます。マトリックス インターフェイスは、はるかに優れたパフォーマンス数値を提供することが知られています。

フォーミュラ インターフェイス:

rf.formula = randomForest(Species ~ ., data = iris)

マトリックス インターフェイス:

rf.matrix = randomForest(y = iris[, 5], x = iris[, 1:4])
于 2016-05-12T18:56:25.810 に答える