web-dev-qa-db-ja.com

randomForestのパフォーマンスを向上させる方法は?

サイズが38 MBのトレーニングセットがあります(12の属性と420000行)。以下のRスニペットを実行して、randomForestを使用してモデルをトレーニングします。これは私にとって何時間もかかっています。

rf.model <- randomForest(
              Weekly_Sales~.,
              data=newdata,
              keep.forest=TRUE,
              importance=TRUE,
              ntree=200,
              do.trace=TRUE,
              na.action=na.roughfix
            )

na.roughfix、実行に時間がかかります。たくさんありますNA'sトレーニングセット内。

誰かがパフォーマンスを向上させる方法を教えてもらえますか?

私のシステム構成は:

Intel(R) Core i7 CPU @ 2.90 GHz
RAM - 8 GB
HDD - 500 GB
64 bit OS
14
user3497321

(tl; drは、a)nodesizeを>> 1に増やし、b)非常に重要度の低い機能列を除外します。おそらく、列の80%を除外します(たとえば)。問題はほぼ確実に_na.roughfix_ではありませんが、疑わしい場合は、randomForestを呼び出す前に、スタンドアロンステップとして_na.roughfix_を個別に実行してください。最初にその赤いニシンを邪魔にならないようにします。)

さて、次のアドバイスはすべて、メモリ制限をクリアするまでしか適用されないので、メモリ使用量を測定し、超過していないことを確認してください。 (途方もなく小さいパラメーターから始めて、それらを拡大し、実行時間を測定し、それが過度に増加していないことを確認し続けます。)

RandomForestのパフォーマンスに影響を与える主なパラメーターは次のとおりです。

  • mtry(少ないほど高速です)
  • ntrees
  • データ内の機能の数/ cols-より多くは二次的に遅いか、より悪いです!下記参照
  • データ内の観測/行の数
  • ncores(並列オプションが使用されている限り、より高速です。)
  • 重要度= Fおよびプロキシミティ= F(プロキシミティ行列を計算しない)を設定することによるパフォーマンスの向上
  • 分類のために非常識なデフォルト_nodesize=1_を使用しないでください! Breimanのパッケージでは、maxdepthを直接設定することはできませんが、nodesizeをそのプロキシとして使用してください。また、次のURLですべての良いアドバイスを読んでください CrossValidated: "Random Forestsのチューニングに関する実用的な質問"
  • したがって、ここではデータに4.2e + 5行があるため、各ノードを〜0.01%より小さくすべきでない場合は、_nodesize=42_を試してください。 (最初にnodesize = 4200(1%)を試して、どれだけ速いかを確認してから、再実行し、nodesizeを小さく調整してください。このデータセットの適切なnodesizeを経験的に決定してください。)
  • 実行時間は〜2 ^ D_maxに比例します。つまり、多項式は(-log1p(nodesize))になります。
  • オプションで、サンプリングを使用してスピードアップすることもできます。_strata,sampsize_引数を参照してください

次に、mtry = M、ntrees = T、ncores = C、nfeatures = F、nrows = R、maxdepth = D_maxを表すランタイムの1次推定は、次のとおりです。

_Runtime proportional to: T * F^2 * (R^1.something) * 2^D_max / C
_

(ここでも、メモリを超えた場合、すべての賭けは無効になります。また、1つのコア、2、4の順に実行して、実際に線形スピードアップが得られることを確認してください。スローダウンではありません。)(大きなRの影響は、リニアよりも悪いツリー分割ではデータ行のすべてのパーティションを考慮する必要があるため、おそらく2次式です。確かに、これは線形よりもやや劣ります。サンプリングまたはインデックスを使用して、行の10%とだけ言うことを確認してください)。

ヒント:大量のがらくた重要度の低い機能を維持すると、実行時間が2次的に増加し、精度が線形に低下します。これは、各ノードで、可能なすべての機能選択(またはmtryが許可する数)を考慮する必要があるためです。そして、各ツリー内で、機能のすべての(F-choose-mtry)可能な組み合わせを検討する必要があります。したがって、ここでは「高速でダーティな機能選択」を実行する私の方法論を示します。パフォーマンスのために」:

  1. 常識的な_nodesize=42_以上を使用しますが、通常(遅い)ツリーを生成します
  2. rf $ importancesまたはrandomForest::varImpPlot()を見てください。 Kを選択する場合、上位Kの機能のみを選択します。ばかばかしい例では、K = 3を選択します。そのリスト全体を後で参照できるように保存します。
  3. ツリーを再実行しますが、_newdata[,importantCols]_のみを指定します
  4. 速度が2次的に速く、oob.errorはそれほど悪くないことを確認します
  5. 変数の重要度がわかったら、_importance=F_をオフにできます
  6. Mtryとnodesizeを微調整し(一度に1つ微調整)、再実行して速度の向上を測定します
  7. パフォーマンス結果を対数軸にプロットします
  8. 結果を投稿してください!上記を裏付けましたか?メモリ使用量に関するコメントはありますか?

(上記は実際の機能選択のための統計的に有効な手順ではないことに注意してください。そのためにそれに依存しないでください。RFベースの機能選択の実際の適切な方法については、randomForestパッケージをお読みください。)

51
smci

Do.traceも時間を消費するのではないかと思います...代わりにdo.trace = TRUE、do.trace = 5(5つのトレースのみを表示)を使用して、エラーについての感覚をつかむことができます。大規模なデータセットの場合、do.traceも時間がかかります。

1
Manoj Kumar