2012-04-26 3 views
10

私は私のデータは、私は、単にyr要因をすることによって、これを行うとlmを使用することにしました行列の乗算が係数に対して正常に機能しているのに、なぜlmはメモリ不足になるのですか?

dte yr id v1 v2 
    . . . . . 
    . . . . . 
    . . . . . 

のように見えるR.と固定効果線形回帰をやろうとしています:

lm(v1 ~ factor(yr) + v2 - 1, data = df) 

しかし、これは記憶が不足しているようです。私のファクタには20レベルあり、dfは1400万行で約2GBの記憶容量があります。これを22GBのマシンで実行しています。 t20t1行うことによって、私の年ごとにダミー変数を作成します:

私は、物事を昔ながらの方法を試してみることにしただけで

df$t1 <- 1*(df$yr==1) 
df$t2 <- 1*(df$yr==2) 
df$t3 <- 1*(df$yr==3) 
... 

とは、計算:

solve(crossprod(x), crossprod(x,y)) 

これがなく実行されます問題が発生し、すぐに回答が得られます。

私は、係数を計算する際にメモリが不足するような映画について何か特別なことがあるのでしょうか?ありがとう。

+5

場合であるあなたがlm.fit'代わりに絞るために 'lm'の'しようとしない理由問題? 'lm.fit'は、QR分解を介した多かれ少なかれ「生の」線形モデルのフィッティングを行います。モデル行列の作成などに関する無関係なものはありません。もし' lm.fit'でもメモリの問題がある場合は、 @ジェイクの答えが問題(QR対正規方程式)のように思われる。 –

答えて

8

これまでの回答のうち正しい方向を指摘したものはありませんでした。

@idrの回答がlmsummary.lmの間で混乱しています。 lmは診断統計を全く計算しません;代わりに、summary.lmがあります。だから彼はsummary.lmについて話している。

@Jakeの答えは、QR分解とLU/Choleksy分解の数値安定性に関する事実です。 Aravindakshanの答えは、両方の演算の背後にある浮動小数点演算の量を指摘することでこれを拡張します(しかし、彼は言ったように、行列の積を計算するコストは考慮しませんでした)。しかし、FLOP数とメモリコストを混同しないでください。実際には両方のメソッドがLINPACK/LAPACKで同じメモリ使用量を持っています。具体的には、QR方法がより多くのRAMを費やしてQファクタを格納するという彼の主張は、偽のものである。 lm(): What is qraux returned by QR decomposition in LINPACK/LAPACKで説明されているコンパクトストレージは、QR分解がどのように計算され格納されるかを明確にします。 QR v.s。のスピード問題Cholは私の答え:Why the built-in lm function is so slow in R?で、私の答えはfaster lmで、QRメソッドの3倍のCholeksyメソッドを使って、小さなルーチンlm.cholを提供しています。

@Gregさんの回答/提案はbiglmですが質問にはお答えしません。 biglmが記載されているので、私はQR decomposition differs in lm and biglmを指摘します。 biglmは、結果として得られるR係数が正の対角を持つようにハウスホルダ反射を計算します。詳細については、Cholesky factor via QR factorizationを参照してください。 biglmがこれを行う理由は、結果としてRがコレスキーファクタと同じになるということです。詳しくはQR decomposition and Choleski decomposition in Rを参照してください。また、biglm以外には、mgcvを使用できます。私の答えを読む:biglm predict unable to allocate a vector of size xx.x MB


を要約した後、私の答えを投稿する時間です。線形モデルを適合させるために

lm

  1. モデルフレームを生成します。
  2. は、モデル行列を生成する。
  3. QR分解のためにlm.fitを呼び出します。
  4. は、QR分解の結果とモデルフレームをlmObjectに返します。

5桁の入力データフレームは、2 GBのデータを保存することになります。 20ファクターレベルでは、結果として得られるモデルマトリックスは約25カラムに10GBの記憶容量を占有します。次に、lmと呼ぶと、メモリ使用量がどのように増加するかを見てみましょう。

  • [グローバル環境]最初にデータフレーム用に2 GBの記憶域があります。
  • [lm envrionment]次にモデルフレームにコピーされ、2 GBのコストがかかります。
  • [lm環境]モデル・マトリックスが生成され、10 GBのコストがかかります。
  • [lm.fit環境]モデル行列のコピーは、QR分解によって上書きされ、10GBのコストがかかります。
  • [lm環境]lm.fitの結果が返され、10 GBのコストがかかります。
  • [地球環境] の結果はlmによってさらに返され、別の10 GBのコストがかかります。
  • [地球環境]lmによってモデルフレームが返され、2 GBのコストがかかります。

合計46 GBのRAMが必要です。使用可能な22 GBのRAMをはるかに上回ります。

実際にlm.fitlmに「インライン化」できる場合、20 GBのコストを節約できます。しかし、別のR関数でR関数をインライン化する方法はありません。

X <- matrix(rnorm(30), 10, 3) # a `10 * 3` model matrix 
y <- rnorm(10) ## response vector 

tracemem(X) 
# [1] "<0xa5e5ed0>" 

qrfit <- lm.fit(X, y) 
# tracemem[0xa5e5ed0 -> 0xa1fba88]: lm.fit 

lm.fitに渡されたときに実際に、Xがコピーされます。

多分私達はlm.fitの周りに何が起こるか見るために小さな例を取ることができます。さんはqrfitは、コンパクトQR行列qrfit$qr$qrがモデル行列Xほどの大きさであること

str(qrfit) 
#List of 8 
# $ coefficients : Named num [1:3] 0.164 0.716 -0.912 
# ..- attr(*, "names")= chr [1:3] "x1" "x2" "x3" 
# $ residuals : num [1:10] 0.4 -0.251 0.8 -0.966 -0.186 ... 
# $ effects  : Named num [1:10] -1.172 0.169 1.421 -1.307 -0.432 ... 
# ..- attr(*, "names")= chr [1:10] "x1" "x2" "x3" "" ... 
# $ rank   : int 3 
# $ fitted.values: num [1:10] -0.466 -0.449 -0.262 -1.236 0.578 ... 
# $ assign  : NULL 
# $ qr   :List of 5 
# ..$ qr : num [1:10, 1:3] -1.838 -0.23 0.204 -0.199 0.647 ... 
# ..$ qraux: num [1:3] 1.13 1.12 1.4 
# ..$ pivot: int [1:3] 1 2 3 
# ..$ tol : num 1e-07 
# ..$ rank : int 3 
# ..- attr(*, "class")= chr "qr" 
# $ df.residual : int 7 

注意を持っているものを見てみましょう。 lm.fitの内部に作成されますが、終了時にlm.fitにコピーされます。合計で、我々はXの3つの "コピー"を持っています:

  • 地球環境の元のもの、
  • lm.fitにコピーされ、QR分解によって上書きされます。
  • lm.fitによって返されたもの。

Xは10 GBなので、lm.fitだけのメモリコストはすでに30 GBです。他の費用はlmに関連しています。

一方

、のは

solve(crossprod(X), crossprod(X,y)) 

X

は10ギガバイトを取るを見てみましょう、しかし crossprod(X)は唯一 25 * 25行列であり、 crossprod(X,y)だけの長さ25のベクトルです。彼らは Xと比べて非常に小さいので、メモリ使用量はまったく増えません。

crossprodと呼ばれると、Xのローカルコピーが作成されることがありますか?どういたしまして! Xへの読み取りと書き込みの両方を実行するlm.fitとは異なり、crossprodXのみを読み取るため、コピーは行われません。あなたは何のコピーメッセージが表示されません

tracemem(X) 
crossprod(X) 

:私たちは、当社のおもちゃの行列Xでこれを確認することができます!


あなたは上記のすべてのための短い要約をしたい場合は、ここにある:lm.fit(X, y)(あるいは.lm.fit(X, y))について

  • メモリコストsolve(crossprod(X), crossprod(X,y))のそれの3倍の大きさです。
  • モデル・マトリックスがモデル・フレームよりどのくらい大きくなっているかによって、lmのメモリー・コストはsolve(crossprod(X), crossprod(X,y))のメモリー・コストの3〜6倍です。モデル・マトリックスがモデル・フレームと同じである場合、下限3は達成されず、上限6に達する。これは何の因子変数または「因子似」という用語がない場合など、bs()poly()のように、
7

lmあなたの入力機能の係数を見つけるだけではありません。たとえば、独立変数のそれぞれの標準誤差とt値を含む独立変数の係数について詳しく説明する診断統計を提供します。

回帰を実行して回帰が有効であることを理解するには、これらの診断統計を理解することが重要だと思います。

これらの追加の計算により、回帰のための行列方程式を単純に解くよりも遅くなります(lm)。例えば

mtcarsデータセットを使用して:

イドリスが、それはまた、あなたがに示すように、LMは、()正規方程式を使用してパラメータのために解決していないことを指摘する価値が言ったことに加えて
>data(mtcars) 
>lm_cars <- lm(mpg~., data=mtcars) 
>summary(lm_cars) 

Call:               
lm(formula = mpg ~ ., data = mtcars)       

Residuals:              
    Min  1Q Median  3Q  Max      
-3.4506 -1.6044 -0.1196 1.2193 4.6271      

Coefficients:             
      Estimate Std. Error t value Pr(>|t|)    
(Intercept) 12.30337 18.71788 0.657 0.5181    
cyl   -0.11144 1.04502 -0.107 0.9161    
disp   0.01334 0.01786 0.747 0.4635    
hp   -0.02148 0.02177 -0.987 0.3350    
drat   0.78711 1.63537 0.481 0.6353    
wt   -3.71530 1.89441 -1.961 0.0633 .    
qsec   0.82104 0.73084 1.123 0.2739    
vs   0.31776 2.10451 0.151 0.8814    
am   2.52023 2.05665 1.225 0.2340    
gear   0.65541 1.49326 0.439 0.6652    
carb  -0.19942 0.82875 -0.241 0.8122    
---               
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 2.65 on 21 degrees of freedom   
Multiple R-squared: 0.869,  Adjusted R-squared: 0.8066  
F-statistic: 13.93 on 10 and 21 DF, p-value: 3.793e-07  
+3

はい、それは本当です。それらの他の活動のどれもが映画に記憶をなくす原因にはならなかった – Alex

10

あなたむしろQR分解を使用するが、これは効率が悪いが数値的に正確な解を生成する傾向がある。

9

biglmパッケージを使用することをおすすめします。より小さなデータを使用してモデルに適合します。

5

ジェイクの要点を詳述します。あなたの回帰が解くことを試みているとしましょう:y = Ax(Aは設計行列です)。 m個の観測値とn個の独立変数Aはmxn行列です。 QRのコストは〜m*n^2です。あなたの場合、m = 14x10^6、n = 20のように見えます。だからm*n^2 = 14*10^6*400はかなりの費用です。

普通の方程式では、正方形でサイズnxnA'A( 'は転置を示します)を逆転しようとしています。解決は通常LUを使用して行われます。これはn^3 = 8000です。これはQRの計算コストよりもはるかに小さい。 もちろん、これには行列乗算のコストは含まれません。さらに

QRルーチンは、サイズmxm=14^2*10^12(!)であるQ行列を保存しようとした場合、その後、あなたのメモリが不十分となります。この問題がないようにQRを書くことは可能です。実際に使用されているQRのバージョンを知ることは興味深いでしょう。そしてなぜ正確にlmコールにメモリ不足が発生するのでしょうか。

関連する問題