/ edit: Şimdi daha fazla takip irlba :: prcomp_irlba kullanabilirsiniz
/ edit: kendi gönderimde takip etmek. irlba
Şimdi, temel bileşenleri hesaplamak için kullanmanıza izin veren "merkez" ve "ölçek" argümanlarına sahiptir, örneğin:
pc <- M %*% irlba(M, nv=5, nu=0, center=colMeans(M), right_only=TRUE)$v
Büyük bir seyrek var Matrix
ben öğrenme algoritması bir makinede kullanmak istiyorum özelliklerinden:
library(Matrix)
set.seed(42)
rows <- 500000
cols <- 10000
i <- unlist(lapply(1:rows, function(i) rep(i, sample(1:5,1))))
j <- sample(1:cols, length(i), replace=TRUE)
M <- sparseMatrix(i, j)
Bu matrisin birçok sütunu olduğu için, boyutluluğunu daha yönetilebilir bir şeye düşürmek istiyorum. Mükemmel irlba paketini SVD yapmak ve ilk n ana bileşenlerini döndürmek için kullanabilirim (burada 5; gerçek veri setimde muhtemelen 100 veya 500 kullanacağım):
library(irlba)
pc <- irlba(M, nu=5)$u
Ancak, PCA'yı gerçekleştirmeden önce birinin matrisi ortalaması gerektiğini okudum (sütun ortalamasını her bir sütundan çıkarın). Bunu veri setimde yapmak çok zor ve ayrıca matrisin azlığını da mahveder.
Ölçeklendirilmemiş verilerde SVD gerçekleştirmek ve doğrudan bir makine öğrenme algoritmasına beslemek ne kadar "kötü"? Matrisin azlığını koruyarak bu verileri ölçeklendirmenin etkili yolları var mı?
/ edit: B_miner tarafından dikkatimi çekti, "PC'ler" gerçekten olmalı:
pc <- M %*% irlba(M, nv=5, nu=0)$v
Ayrıca, whuber'in cevabının crossprod
, seyrek matrislerde son derece hızlı olan fonksiyonu aracılığıyla uygulanması oldukça kolay olmalı :
system.time(M_Mt <- crossprod(M)) # 0.463 seconds
system.time(means <- colMeans(M)) #0.003 seconds
Şimdi means
çıkarmadan önce vektöre ne yapacağımdan emin değilim M_Mt
, ancak çözdüğümde yayınlayacağım.
/ edit3: İşte işlemin her aşaması için seyrek matris işlemleri kullanan, whuber kodunun değiştirilmiş hali. Eğer siz bellekte tüm seyrek matris saklayabilir, çok hızlı bir şekilde çalışır:
library('Matrix')
library('irlba')
set.seed(42)
m <- 500000
n <- 100
i <- unlist(lapply(1:m, function(i) rep(i, sample(25:50,1))))
j <- sample(1:n, length(i), replace=TRUE)
x <- sparseMatrix(i, j, x=runif(length(i)))
n_comp <- 50
system.time({
xt.x <- crossprod(x)
x.means <- colMeans(x)
xt.x <- (xt.x - m * tcrossprod(x.means)) / (m-1)
svd.0 <- irlba(xt.x, nu=0, nv=n_comp, tol=1e-10)
})
#user system elapsed
#0.148 0.030 2.923
system.time(pca <- prcomp(x, center=TRUE))
#user system elapsed
#32.178 2.702 12.322
max(abs(pca$center - x.means))
max(abs(xt.x - cov(as.matrix(x))))
max(abs(abs(svd.0$v / pca$rotation[,1:n_comp]) - 1))
Sütun sayısını 10.000'e, asıl bileşenlerin sayısını 25'e ayarlarsanız, irlba
tabanlı PCA'nın yaklaşık 50 ana bileşeni hesaplaması yaklaşık 17 dakika sürer ve yaklaşık 6 GB RAM kullanır, bu da çok da kötü değildir.
X %*% v %*% diag(d, ncol=length(d))
. Svd'deki v matrisi, bir prcomp
nesnenin "döndürme" öğesine eşdeğerdir ve X %*% v
veya bir nesnenin öğesini X %*% v %*% diag(d, ncol=length(d))
temsil eder . Bir göz atın a . x
prcomp
stats:::prcomp.default