2013-05-29 181 views
2

我想在r中生成一个30000 x 30000的矩阵,将30000个元素的向量与其转置相乘,然后获得该矩阵的SVD,但程序告诉我r无法定位一个大小为900000000的矢量图。帮助我,我该怎么办?该SVD的美丽R中非常大的矩阵的SVD

y <- read.csv("C:\\Users\\jmarescr\\Desktop\\BigLetra50.csv",header=TRUE) 

x <- matrix(y[1:30000,1],30000,1) 
tx <- as.matrix(t(x)) 

mat <- x %*% tx 

Error: can not allocate vector of length 900000000 

s <- svd(mat) 

Error in svd (x): object 'mat' not found 

回答

7

部分原因是,你不需要采取x的双重交叉,以获得双重交叉的SVD。

您可以直接从x的SVD元素中获得x%*%t(x)(又名tcrossprod(x))的SVD。具体而言(并且直到U列的符号)SVD(x%*%t(x))= U D^2 t(U),其中U和D取自x的SVD。 (对于一个参考,see here

要看到它的行动,尝试了一个小例子:

set.seed(1) 
x <- matrix(rnorm(15), ncol=5) 


svd(x)$d 
# [1] 3.046842 1.837539 1.411585 
sqrt(svd(tcrossprod(x))$d) 
# [1] 3.046842 1.837539 1.411585 

svd(x)$u 
#   [,1]  [,2]  [,3] 
# [1,] -0.3424029 0.7635281 0.5475264 
# [2,] -0.8746155 -0.4719093 0.1111273 
# [3,] 0.3432316 -0.4408248 0.8293766 
svd(tcrossprod(x))$u 
#   [,1]  [,2]  [,3] 
# [1,] -0.3424029 0.7635281 0.5475264 
# [2,] -0.8746155 -0.4719093 0.1111273 
# [3,] 0.3432316 -0.4408248 0.8293766 
svd(tcrossprod(x))$v 
#   [,1]  [,2]  [,3] 
# [1,] -0.3424029 0.7635281 0.5475264 
# [2,] -0.8746155 -0.4719093 0.1111273 
# [3,] 0.3432316 -0.4408248 0.8293766 

另一种方式来看到这一点:

sss <- svd(x) 

with(sss, u %*% diag(d)^2 %*% t(u)) 
#   [,1]  [,2]  [,3] 
# [1,] 3.654154 1.684675 -1.322649 
# [2,] 1.684675 7.877802 -1.900721 
# [3,] -1.322649 -1.900721 3.120415 

tcrossprod(x) 
#   [,1]  [,2]  [,3] 
# [1,] 3.654154 1.684675 -1.322649 
# [2,] 1.684675 7.877802 -1.900721 
# [3,] -1.322649 -1.900721 3.120415 
+0

另外,请注意(视在你的应用程序中),你可以通过计算比完整的左奇异向量少的数据来加快速度。请参阅'svd'的“Details”部分,了解更多关于如何/为什么要手动将nu设置为小于min(nrow(x),ncol(x))的详细信息。 –