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? Я искал в документации, но не нашел.
Ответы
Ответ 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