[英]How to split a sparse matrix into two
我有一個大的稀疏矩陣,我需要將其關聯起來,這對我來說是不可能的,因為:
bigstats
和bigmemory
,我的 R 凍結了(使用 windows 10、8GB 筆記本電腦)Matrix
package中沒有相關性function 注意:我正在嘗試以'M'X + X'M - M'M'
格式關聯一個稀疏矩陣,這是不可能的,這就是為什么我試圖將稀疏矩陣分成兩個或三個,轉向密集使用as.matrix()
的矩陣,然后使用cor()
進行關聯,然后使用cbind()
() 將相關結果合並為一個
現在:
我想問是否可以將稀疏矩陣拆分為兩個或三個部分,轉換為密集矩陣,然后關聯每個密集矩陣,然后將兩個或三個密集矩陣合並為一個,然后導出到文本文件。
我可以使用什么 function 將稀疏矩陣拆分為兩個或三個,記住稀疏矩陣的i
和p
部分大小相等且dim
相同
Formal class 'dgCMatrix' [package "Matrix"] with 7 slots
..@ i : int [1:73075722] ...
..@ p : int [1:73075722] 0 0 1 1 1 1 1 2 2 2 ...
..@ Dim : int [1:2] 500232 500232
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ x : num [1:73075722] ...
..@ uplo : chr "L"
..@ factors : list()
相關性 output 將采用以下格式:
[,1] [,2] [,3] [,4]
[1,] 1.00000000 -0.8343860 0.3612926 0.09678096
[2,] -0.83438600 1.0000000 -0.8154071 0.24611830
[3,] 0.36129256 -0.8154071 1.0000000 -0.51801346
[4,] 0.09678096 0.2461183 -0.5180135 1.00000000
[5,] 0.67411584 -0.3560782 -0.1056124 0.60987601
[6,] 0.23071712 -0.4457467 0.5117711 0.21848068
[7,] 0.49200080 -0.4246502 0.2016633 0.46971736
[,5] [,6] [,7]
[1,] 0.6741158 0.2307171 0.4920008
[2,] -0.3560782 -0.4457467 -0.4246502
[3,] -0.1056124 0.5117711 0.2016633
[4,] 0.6098760 0.2184807 0.4697174
[5,] 1.0000000 0.2007979 0.7198228
[6,] 0.2007979 1.0000000 0.6965899
[7,] 0.7198228 0.6965899 1.0000000
cor()
function 是一種有效計算所有列之間的pearson
相關性的方法。 cor
非常有效,但如果我們不介意效率下降,我們可以手動計算pearson
相關性:
n_row <- nrow(res)
cor_mat <- Matrix(0L,n_row, ncol(res))
cMeans <- Matrix::colMeans(res)
for (i in seq_len(nrow(res)-1)){
x_delta = res[, i] - cMeans[i]
sum_x_delta_sq = sum(x_delta^2)
for (j in (i+1):nrow(res)){
y_delta = res[, j] - cMeans[j]
tmp <- sum(x_delta * y_delta) / sqrt((sum_x_delta_sq * sum(y_delta^2)))
if (abs(tmp) > 0.05) cor_mat[i, j] <- tmp
}
}
隨着矩陣稀疏度的增加,我們可以通過分離涉及非稀疏元素的操作和涉及稀疏元素的操作來使上述更復雜但性能更高:
n_row <- nrow(res)
cor_mat <- Matrix(0L,n_row, ncol(res))
cMeans <- Matrix::colMeans(res)
for (i in 1){
sp_i <- res[, i, drop = F]
i_s <- sp_i@i + 1
i_zero_delta = 0 - cMeans[i]
i_non_zero_delta = sp_i@x - cMeans[i]
sum_x_delta_sq = sum(c((n_row - length(i_s)) * i_zero_delta^2, i_non_zero_delta^2))
for (j in (i+1):nrow(res)){
sp_j <- res[, j, drop = F]
j_s <- sp_j@i + 1
j_zero_delta = 0L - cMeans[j]
j_non_zero_delta = sp_j@x - cMeans[j]
sum_y_delta_sq = sum(c((n_row - length(j_s)) * j_zero_delta^2, j_non_zero_delta^2))
common <- intersect(i_s, j_s)
only_i <- setdiff(i_s, j_s)
only_j <- setdiff(j_s, i_s)
none <- n_row - length(c(common, only_i, only_j))
numerator = 0
if (length(common) > 0) numerator = numerator + sum(i_non_zero_delta[match(common, i_s)] * j_non_zero_delta[match(common, j_s)])
if (length(only_i) > 0) numerator = numerator + j_zero_delta * sum(i_non_zero_delta[match(only_i, i_s)])
if (length(only_j) > 0) numerator = numerator + i_zero_delta * sum(j_non_zero_delta[match(only_j, j_s)])
if (length(none) > 0) numerator = numerator + i_zero_delta * j_zero_delta * none
tmp <- numerator / sqrt(sum_x_delta_sq * sum_y_delta_sq)
if (abs(tmp) > 0.05) cor_mat[i, j] <- tmp
}
}
我通過行索引實現 sparse_matrix 的切片:
as.DF_spM <- function(data.use,chun_size="20000000",dg_class="dgCMatrix") {
lapply( split(seq(nrow(data.use)), (seq(nrow(data.use))-1) %/% as.numeric(chun_size) ) , function(nx) {
switch(dg_class,
dgTMatrix = {as(as.matrix(data.use[nx,]),"dgTMatrix")},
dgCMatrix = {as(as.matrix(data.use[nx,]),"dgCMatrix")},
dgRMatrix = {as(as.matrix(data.use[nx,]),"dgRMatrix")}
)
}) %>% Matrix.utils::rBind.fill()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.