Линейная регрессия с большими матрицами - PullRequest
0 голосов
/ 11 сентября 2018

Я хотел бы выполнить линейную регрессию с большими матрицами.

Это то, что я пробовал до сих пор:

library(bigmemory)
library(biganalytics)
library(bigalgebra)

nrows <- 1000000
X <- as.big.matrix( replicate(100, rnorm(nrows)) )
y <- rnorm(nrows)

biglm.big.matrix(y ~ X)
# Error in CreateNextDataFrameGenerator(formula, data, chunksize, fc, getNextChunkFunc,  : 
  argument "data" is missing, with no default

biglm.big.matrix(y ~ X, data = cbind(y, X))
# Error in bigmemory:::mmap(vars, colnames(data)) : 
  Couldn't find a match to one of the arguments.

biglm.big.matrix(y ~ X, data = cbind(y = y, X = X))
# Error in bigmemory:::mmap(vars, colnames(data)) : 
  Couldn't find a match to one of the arguments.

Как мне решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Вы можете легко реализовать это с помощью пакета {bigstatsr} (отказ от ответственности: я автор).

Истинное значение

nrows <- 1000000
X <- replicate(100, rnorm(nrows))
y <- rnorm(nrows)
system.time(
  true <- lm(y ~ X)
) # 11.3 sec

С {bigstatsr}

library(bigstatsr)
system.time({
  X2 <- as_FBM(X)
  X2$add_columns(1)
  X2[, ncol(X2)] <- 1

  inv_XtX <- solve(big_crossprodSelf(X2)[])
  Xty <- big_cprodVec(X2, y)
  betas <- inv_XtX %*% Xty
  RSS <- drop(crossprod(y - big_prodVec(X2, betas)))
  df <- nrow(X2) - ncol(X2)
  std_err <- sqrt(RSS * diag(inv_XtX) / df)
}) # 1.6 sec

Проверка

head(summary(true)$coefficients)
# Intercept at the end
head(betas)  ## Estimate
head(std_err)
head(t_stat <- betas / std_err) ## t value
head(pval <- 2 * pt(abs(t_stat), df = df, lower.tail = FALSE))
0 голосов
/ 11 сентября 2018

Здесь X - это (большая) матрица с 100 столбцами. Поскольку biglm.big.matrix() требует аргумента data=, похоже, что вы не можете попросить эту функцию запустить линейную модель для всех столбцов в X одновременно, как вы можете с помощью lm(). Также обратите внимание, что когда вы cbind() a с big.matrix, как в cbind(y, X), результатом будет list !!.

Похоже, вам нужно, чтобы y и X были частью одного big.matrix, тогда вам нужно будет самостоятельно построить формулу модели:

library(bigmemory)
library(biganalytics)
library(bigalgebra)

# Construct an empty big.matrix with the correct number of dimensions and
# with column names
nrows <- 1000000
dat <- big.matrix(nrow=nrows, ncol=101, 
                  dimnames=list(
                    NULL, # no rownames
                    c("y", paste0("X", 1:ncol(X))) # colnames: y, X1, X2, ..., X100
                  ))

# fill with y and X:
dat[,1] <- rnorm(nrows)
dat[,2:101] <- replicate(100, rnorm(nrows)) 

# construct the model formula as a character vector using paste:
# (Or you need to type y ~ X1 + X2 + ... + X100 manually in biglm.big.matrix()!)
f <- paste("y ~", paste(colnames(dat)[-1], collapse=" + "))

# run the model
res <- biglm.big.matrix(as.formula(f), data=dat)
summary(res)
...