これまでの回答のうち正しい方向を指摘したものはありませんでした。
@idrの回答がlm
とsummary.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
う
- モデルフレームを生成します。
- は、モデル行列を生成する。
- QR分解のために
lm.fit
を呼び出します。
- は、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.fit
をlm
に「インライン化」できる場合、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
とは異なり、crossprod
はX
のみを読み取るため、コピーは行われません。あなたは何のコピーメッセージが表示されません
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()
のように、
場合であるあなたがlm.fit'代わりに絞るために 'lm'の'しようとしない理由問題? 'lm.fit'は、QR分解を介した多かれ少なかれ「生の」線形モデルのフィッティングを行います。モデル行列の作成などに関する無関係なものはありません。もし' lm.fit'でもメモリの問題がある場合は、 @ジェイクの答えが問題(QR対正規方程式)のように思われる。 –