2011-07-01 4 views
18

私はglmだけを使って訓練すると、すべてが機能し、疲れた記憶に近づくことさえできません。しかし、train(..., method='glm')を実行すると、メモリが不足します。キャレット・トレインはなぜそんなに多くの記憶を取りますか?

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

(私はGLM年代にはグリッドがありませんので、それは、パラメータチューニンググリッドサーチの各反復からのデータを格納することに関連していない知っている、私は信じています。)

+1

他の人が試してみると小さな再現可能な例を作るのに気をつけますか? –

答えて

34

問題が2倍です。 I)trainはちょうどglm()経由モデルに適合していない)、それはそのモデルをブートストラップしますので、でもデフォルトで、train()は問題IIと相まって、25個のブートストラップ標本を、行います(またはですa)とii)train()は、のデフォルト機能を単にglm()と呼びます。そして、これらのデフォルトはモデルフレーム(引数model = TRUE?glm)を格納することです。これにはモデルフレームスタイルのデータのコピーが含まれます。 train()によって返されたオブジェクトは、すでにデータのコピーを$trainingDataに格納しており、"glm"オブジェクトには$finalModelも実際のデータのコピーを保持しています。

この時点で、単にtrain()を用いglm()を実行すると、完全に拡張model.frameの25のコピーのすべてがリサンプリングプロセス中にメモリに保持する必要がある元のデータ、生成される - これらが同時に保持されているかどうかを、またはlapply()コールでリサンプリングが行われるため、コードを簡単に見てすぐにはっきりと分かりません。生データのコピーも25個あります。

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

列車にmodel = FALSEを追加すると、それが異なる場合があります。ここで?glmclottingデータを使用して小さな例です。

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のすべてのコピーを保持するかどうかによって異なります。

train()によって返されるオブジェクトも、glm()によって返されるオブジェクトよりも大幅に大きくなります(後述の@DWinで説明されています)。

これをさらに詳しく調べるには、コードをもっと詳しく調べるか、または保守担当者Max Khhn(キャレット)に電子メールのフットプリントを減らすオプションを問い合わせてください。

+1

良い答え(あなたにとって典型的なもの、Gavin) glmオブジェクトのサイズを追加するだけです: 'm3 = glm(lot1〜log(u)、data =凝固、family =ガンマ) > object.size(m3) 47272 bytes' –

+0

@Dwinありがとう、よかったポイント。私はもちろん、帰属にその出力を追加します。 –

+0

ありがとう、私はここに答えを追加するようにマックスに尋ねた。 – Yang

27

ギャビンの答えはスポット上にあります。私はスピードや効率よりもむしろ使いやすさのために関数を作りました[1]

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

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

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

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

ヤン - データの詳細をstr(data)で知ることができれば、ディメンションやその他の側面(たとえば、レベルが多い要素など)を理解できます。

私は、[1]私たちはときに我々はできる、可能な限りいくつかのモデルに合うように偉大な長さに行くべきではないと

マックス

、それに役立ちます願っています。 「サブモデル」トリックは、pls、gbm、rpart、earthなどの多くのモデルで使用されます。また、モデルは式と非式インターフェース(例えば。lda()またはearth()を持っているとき、私たちは非式インターフェイスをデフォルトに。

[2]毎週たまに私がtrain()機能を再起動する非常識な衝動を取得。foreachを使用すると、これらの問題のいくつかが回避される可能性があります。

+0

SO @Maxへようこそ。有益な回答に感謝します。使いやすさのために 'train()'を書いてうれしいです。私は最近いくつかの確率的なグラジエントのブーストのためにそれを使用していましたし、自分でチューニングコードを書いていたのは、**キャレット**と 'train()'に切り替える啓示でした! –

+0

私は自分自身のモデル行列と応答ベクトル(必然的に 'findCorrelation'を使うことができます)を提供していますので、私はモデルの式インタフェースを使用しません。サブモデルのトリックとは何ですか? – Yang

+1

数式のメモリ使用の問題を扱うためにあなたが挙げたパッケージは何ですか? "Rにはその問題に効果的に対処するためのパッケージがあります" – Eduardo

1

私は、上記の答えは少し古くなっていると思います.Titleは最初にFALSEに設定されていますモデルアンサンブルを使用している場合は、これらの2つのパーを指定する必要があります貪欲/スタックアンサンブルtrainControlのameters。

私の場合、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)) 
関連する問題