2017-07-27 5 views
1

Ich habe ein falsches Verständnis über die Speichernutzung, wenn ich eine Teilmenge einer Matrix in R verwende. Ich bin gestolpert, als ich versuchte, eine Kreuzvalidierungsfunktion zu programmieren, aber ich denke, das Problem ist allgemeiner. Ich habe unten ein kleines Beispiel gekocht.R-Indexierung, Matrix-Multiplikation

# parameters 
n <- 1e6 # the real data are much bigger, but this will do 
m <- 50 
nfolds <- 10 
X <- matrix(rnorm(n*m,0,1),nrow=n,ncol=m) 
y <- rnorm(n,0,1) 
mse <- rep(0,nfolds) 
foldid <- sample(rep(seq(nfolds), length = n)) 

# produces big spikes in memory 
for (i in (1:nfolds)) { 
    which <- foldid == i 
    xpx <- crossprod(X[!which,]) 
    xpy <- crossprod(X[!which,],y[!which]) 
    b <- solve(xpx,xpy) 
    mse[i] <- mean((y[which] - X[which,] %*% b)**2) 
} 

# does not produce spikes in memory usage 
for (i in (1:nfolds)) { 
    xpx <- crossprod(X) 
    xpy <- crossprod(X,y) 
    b <- solve(xpx,xpy) 
    mse[i] <- mean((y - X %*% b)**2) 
} 

I verstehen nicht, warum die erste Schleife große Aufwärtsspitzen im Speicherverbrauch erzeugt, während die zweite Schleife nicht an, obwohl eine streng größer Matrix multipliziert wird.

Antwort

1

Vergleichen wir die ersten Zeilen mit den Schleifen.

Zuerst die einfache crossprod:

xpx <- crossprod(X) 

Ohne subsetting arbeiten Sie mit Matrizen X (bereits vorhandenen 400 MB) und xpx (klein).

Zweitens mit subsetting:

xpx <- crossprod(X[!which,]) 

Hier arbeiten Sie mit X, temporäre Matrix X[!which,] und xpx. Die zusätzliche Matrix X[!which,] benötigt zusätzliche 360 ​​MB Speicher.

object.size(X[!which,]) 
# 360000200 bytes 

R hat eine relativ schlechte Speicherverwaltung, so dass die temporäre Matrix für einige Zeit nicht verworfen werden.