Подтвердить что ты не робот

R: разреженное преобразование матрицы

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

Однако эта матрица "dummy" очень велика (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? Я искал в документации, но не нашел.

4b9b3361

Ответ 1

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

Начнем с разреженной матрицы из пакета 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