21

を使用してトレーニングするとglm、すべてが機能し、メモリを使い果たすことさえありません。しかし、train(..., method='glm')実行するとメモリが不足します。

これtrainは、クロス検証の反復ごとに大量のデータを保存しているためですか (または trControl プロシージャが何であれ)? 私は見てtrainControlいますが、これを防ぐ方法が見つかりません...ヒントはありますか?私が気にするのは、パフォーマンスの概要と、おそらく予測された応答だけです。

(glmのグリッドがないため、パラメーター調整グリッド検索の各反復からのデータの保存に関連していないことはわかっています。)

4

3 に答える 3

38

問題は2つあります。i) を介してモデルを適合さtrainせるだけでなく、そのモデルをブートストラップするため、デフォルトでも25のブートストラップサンプルを実行します。これは、問題ii)と相まって、問題(または)原因であり、ii デフォルトで関数を呼び出すだけです。そして、それらのデフォルトは、モデルフレーム(の引数)を格納することです。これには、モデルフレームスタイルのデータのコピーが含まれます。によって返されるオブジェクトは、にデータのコピーをすでに格納しており、のオブジェクトにも実際のデータのコピーがあります。glm()train() train()glm()model = TRUE?glmtrain()$trainingData"glm"$finalModel

この時点で、をglm()使用して実行するだけで、完全に拡張さtrain()た元のデータの25コピーが生成されます。これらはすべて、リサンプリングプロセス中にメモリに保持する必要があります。これらが同時に保持されるか連続して保持されるかは、クイックルックからすぐにはわかりません。呼び出しでリサンプリングが行われるときにコードで。生データの25のコピーもあります。model.frame lapply()

リサンプリングが完了すると、返されるオブジェクトには、生データの2つのコピーとの完全なコピーが含まれますmodel.frame。トレーニングデータが使用可能なRAMに比べて大きい場合、またはで拡張される多くの要素が含まれているmodel.frame場合は、データのコピーを持ち歩くだけで大量のメモリを簡単に使用できます。

model = FALSE電車の呼び出しに追加すると、違いが生じる可能性があります。clotting以下のデータを使用した小さな例を次に示し?glmます。

clotting <- data.frame(u = c(5,10,15,20,30,40,60,80,100),
                       lot1 = c(118,58,42,35,27,25,21,19,18),
                       lot2 = c(69,35,26,21,18,16,13,12,12))
require(caret)

それから

> m1 <- train(lot1 ~ log(u), data=clotting, family = Gamma, method = "glm", 
+             model = TRUE)
Fitting: parameter=none 
Aggregating results
Fitting model on full training set
> m2 <- train(lot1 ~ log(u), data=clotting, family = Gamma, method = "glm",
+             model = FALSE)
Fitting: parameter=none 
Aggregating results
Fitting model on full training set
> object.size(m1)
121832 bytes
> object.size(m2)
116456 bytes
> ## ordinary glm() call:
> m3 <- glm(lot1 ~ log(u), data=clotting, family = Gamma)
> object.size(m3)
47272 bytes
> m4 <- glm(lot1 ~ log(u), data=clotting, family = Gamma, model = FALSE)
> object.size(m4)
42152 bytes

したがって、返されるオブジェクトにはサイズの違いがあり、トレーニング中のメモリ使用量は少なくなります。どれだけ低くなるかは、内部がリサンプリングプロセス中にtrain()のすべてのコピーをmodel.frameメモリに保持するかどうかによって異なります。

によって返されるオブジェクトも、以下のコメントで@DWinによって言及されているように、によって返されるオブジェクトtrain()よりも大幅に大きくなります。glm()

これをさらに進めるには、コードをさらに詳しく調べるか、caretの保守者であるMax Kuhnに電子メールを送信して、メモリフットプリントを削減するためのオプションについて問い合わせてください。

于 2011-07-01T08:19:28.583 に答える
32

ギャビンの答えは的を射ています。速度や効率ではなく、使いやすさのために関数を構築しました [1]

まず、数式インターフェイスを使用すると、多くの予測子がある場合に問題が発生する可能性があります。これは R Core で修正できるものです。式のアプローチでは、非常に大きいがまばらなterms()行列を保持する必要があり、R にはその問題を効果的に処理するためのパッケージがあります。たとえば、n = 3,000 および p = 2,000 の場合、式インターフェイスを使用した場合、3 ツリー ランダム フォレスト モデル オブジェクトはサイズが 1.5 倍大きくなり、実行に 23 倍の時間がかかりました (282 秒と 12 秒)。

次に、トレーニング データを保持する必要はありません ( のreturnData引数を参照してくださいtrainControl())。

また、R には実際の共有メモリ インフラストラクチャがないため、メモリに保持されるデータのコピーの数について Gavin は正しいです。基本的に、リサンプルごとにリストが作成されlapply()、リストを処理するために使用され、リサンプルされた推定値のみが返されます。別の方法として、(現在のリサンプル用に) データの 1 つのコピーを順次作成し、必要な操作を実行してから、残りの反復を繰り返します。問題は I/O であり、並列処理を行うことができません。[2]

大規模なデータ セットがある場合は、式以外のインターフェイスを使用することをお勧めします (glm などの実際のモデルは最終的に式を使用しますが)。また、大規模なデータ セットの場合、および他の関数train()で使用するためにリサンプリング インデックスを保存します。resamples()おそらくそれらも削除できます。

str(data)ヤン -ディメンションやその他の側面 (たとえば、多くのレベルを持つ要因など) を理解できるように、データについて詳しく知ることは良いことです。

それが役立つことを願っています、

マックス

[1] できるだけ少ないモデルに適合させるために多大な努力をするべきではありません。「サブモデル」トリックは、pls、gbm、rpart、earth などの多くのモデルに使用されます。また、モデルに式と非式のインターフェースがある場合 (例:lda()またはearth()、非式のインターフェースをデフォルトに設定します。

[2] ときどき、機能を再起動したいという非常識な衝動に駆られtrain()ます。を使用foreachすると、これらの問題のいくつかを回避できる場合があります。

于 2011-07-02T03:52:50.533 に答える
5

上記の回答は少し時代遅れだと思います。caret および caretEnsemble パッケージには、trainControl 'trim' に追加のパラメーターが含まれるようになりました。Trim は最初は FALSE に設定されていますが、TRUE に変更するとモデルのサイズが大幅に縮小されます。モデルのサイズを可能な限り小さくするには、これを returnData=FALSE と組み合わせて使用​​する必要があります。モデル アンサンブルを使用している場合は、貪欲/スタック アンサンブルの trainControl でこれら 2 つのパラメーターも指定する必要があります。

私の場合、1.6GB のモデルは、アンサンブル コントロールの両方のパラメーターを使用して ~500mb に縮小し、貪欲なアンサンブル コントロールのパラメーターを使用してさらに ~300mb に縮小しました。

Ensemble_control_A9 <- trainControl(trim=TRUE, method = "repeatedcv", number = 3, repeats = 2, verboseIter = TRUE, returnData = FALSE, returnResamp = "all", classProbs = TRUE, summaryFunction = twoClassSummary, savePredictions = TRUE, allowParallel = TRUE, sampling = "up")


Ensemble_greedy_A5 <- caretEnsemble(Ensemble_list_A5, metric="ROC",  trControl=trainControl(number=2, trim=TRUE, returnData = FALSE, summaryFunction=twoClassSummary, classProbs=TRUE))
于 2018-03-05T00:27:27.760 に答える