2013-06-28 4 views
13

У меня есть матрица факторов в R и вы хотите преобразовать ее в матрицу фиктивных переменных 0-1 для всех возможных уровней каждого фактора.R: разреженное преобразование матрицы

Однако эта «фиктивная» матрица очень большая (91690x16593) и очень редкая. Мне нужно сохранить его в разреженной матрице, иначе он не поместится в моем 12 ГБ оперативной памяти.

В настоящее время я использую следующий код, и она работает очень хорошо, и занимает несколько секунд:

library(Matrix) 
X_factors <- data.frame(lapply(my_matrix, as.factor)) 
#encode factor data in a sparse matrix 
X <- sparse.model.matrix(~.-1, data = X_factors) 

Однако я хочу использовать пакет e1071 в R, и в конечном итоге сохранить эту матрицу libsvm формат с write.matrix.csr() , поэтому сначала мне нужно преобразовать мою разреженную матрицу в формат SparseM.

Я попытался сделать:

library(SparseM) 
X2 <- as.matrix.csr(X) 

но очень быстро заполняет мою оперативную память и в конечном итоге R аварии. Я подозреваю, что внутренне, as.matrix.csr сначала преобразует разреженную матрицу в плотную матрицу, которая не соответствует моей памяти компьютера.

Моим другим вариантом было бы создание моей разреженной матрицы непосредственно в формате SparseM.
Я пробовал as.matrix.csr(X_factors), но он не принимает рамку данных факторов.

Есть ли эквивалент sparse.model.matrix(~.-1, data = X_factors) в пакете SparseM? Я искал в документации, но не нашел.

ответ

18

Довольно сложно, но я думаю, что получил.

Начнем с разреженной матрицей из Matrix пакета:

i <- c(1,3:8) 
j <- c(2,9,6:10) 
x <- 7 * (1:7) 
X <- sparseMatrix(i, j, x = x) 

Пакет Matrix использует формат сжатия колонки-ориентированный, в то время как SparseM поддерживает оба столбцов и строк ориентированных форматов и имеет функции, которые могут легко обращаться с преобразование из одного формата в другой.

Таким образом, мы сначала преобразуем наш колонные ориентированное Matrix в колонке-ориентированная SparseM матрицы: нам просто нужно быть осторожными, называя правильный конструктор и, заметив, что оба пакета использует различные соглашения для индексов (начало в 0 или 1):

X.csc <- new("matrix.csc", ra = [email protected], 
          ja = [email protected] + 1L, 
          ia = [email protected] + 1L, 
          dimension = [email protected]) 

Затем переход от колонки-ориентированной грести-ориентированном формате:

X.csr <- as.matrix.csr(X.csc) 

А ты молодец! Вы можете проверить, что две матрицы идентичны (на моем небольшом примере):

range(as.matrix(X) - as.matrix(X.csc)) 
# [1] 0 0 
+0

Он отлично работал. Спасибо за быстрый ответ. –