R索引,矩阵乘法
R Indexing, Matrix multiplication
我似乎对在 R 中使用矩阵的子集时的内存使用有误解。我在尝试编写交叉验证函数时遇到过,但我认为这个问题更普遍。我在下面编了一个小例子。
# 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)
}
我不明白为什么第一个循环会在内存使用中产生大的上升峰值,而第二个循环却不会,尽管乘以一个严格更大的矩阵。
让我们比较一下循环中的第一行。
首先,简单的crossprod
:
xpx <- crossprod(X)
如果不进行子集化,您将使用矩阵 X
(已有 400 MB)和 xpx
(小)。
其次,子集化:
xpx <- crossprod(X[!which,])
您在这里使用 X
、临时矩阵 X[!which,]
和 xpx
。附加矩阵 X[!which,]
需要额外的 360 MB 内存。
object.size(X[!which,])
# 360000200 bytes
R的内存管理比较差,临时矩阵可能有一段时间不会被丢弃
我似乎对在 R 中使用矩阵的子集时的内存使用有误解。我在尝试编写交叉验证函数时遇到过,但我认为这个问题更普遍。我在下面编了一个小例子。
# 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)
}
我不明白为什么第一个循环会在内存使用中产生大的上升峰值,而第二个循环却不会,尽管乘以一个严格更大的矩阵。
让我们比较一下循环中的第一行。
首先,简单的crossprod
:
xpx <- crossprod(X)
如果不进行子集化,您将使用矩阵 X
(已有 400 MB)和 xpx
(小)。
其次,子集化:
xpx <- crossprod(X[!which,])
您在这里使用 X
、临时矩阵 X[!which,]
和 xpx
。附加矩阵 X[!which,]
需要额外的 360 MB 内存。
object.size(X[!which,])
# 360000200 bytes
R的内存管理比较差,临时矩阵可能有一段时间不会被丢弃