/ แก้ไข: ติดตามเพิ่มเติมตอนนี้คุณสามารถใช้irlba :: prcomp_irlba
/ แก้ไข: ติดตามโพสต์ของฉันเอง irlba
ขณะนี้มีอาร์กิวเมนต์ "กลาง" และ "สเกล" ซึ่งให้คุณใช้ในการคำนวณส่วนประกอบหลักเช่น:
pc <- M %*% irlba(M, nv=5, nu=0, center=colMeans(M), right_only=TRUE)$v
ฉันมีMatrix
คุณสมบัติเบาบางขนาดใหญ่ที่ฉันต้องการใช้ในอัลกอริทึมการเรียนรู้ของเครื่อง:
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)
เนื่องจากเมทริกซ์นี้มีหลายคอลัมน์ฉันต้องการลดขนาดของมันเป็นสิ่งที่จัดการได้มากกว่า ฉันสามารถใช้แพ็คเกจ irlba ที่ยอดเยี่ยมเพื่อทำ SVD และคืนองค์ประกอบหลักตัวแรก (5 ที่แสดงที่นี่ฉันอาจใช้ 100 หรือ 500 ในชุดข้อมูลจริงของฉัน):
library(irlba)
pc <- irlba(M, nu=5)$u
อย่างไรก็ตามฉันได้อ่านแล้วว่าก่อนที่จะทำการ PCA หนึ่งควรอยู่ตรงกลางเมทริกซ์ (ลบค่าเฉลี่ยคอลัมน์จากแต่ละคอลัมน์) นี่เป็นเรื่องยากมากที่จะทำบนชุดข้อมูลของฉันและนอกจากนี้จะทำลายขอบเขตของเมทริกซ์
"ไม่ดี" ในการดำเนินการ SVD กับข้อมูลที่ไม่ได้ปรับขนาดและป้อนเข้าสู่อัลกอริทึมการเรียนรู้ของเครื่องอย่างไร มีวิธีใดที่มีประสิทธิภาพที่ฉันสามารถขยายข้อมูลนี้ในขณะที่รักษาความกระจัดกระจายของเมทริกซ์ได้หรือไม่?
/ edit: B_miner ได้รับความสนใจจากฉัน "พีซี" ควรจะเป็น:
pc <- M %*% irlba(M, nv=5, nu=0)$v
นอกจากนี้ฉันคิดว่าคำตอบของคนผิวเผินน่าจะนำไปใช้งานได้ง่ายผ่านcrossprod
ฟังก์ชั่นซึ่งเร็วมากในการฝึกอบรมแบบกระจัดกระจาย:
system.time(M_Mt <- crossprod(M)) # 0.463 seconds
system.time(means <- colMeans(M)) #0.003 seconds
ตอนนี้ฉันไม่แน่ใจว่าจะทำอย่างไรกับmeans
เวกเตอร์ก่อนที่จะลบออกM_Mt
แต่จะโพสต์ทันทีที่ฉันเข้าใจ
/ edit3: นี่คือรุ่นที่แก้ไขของรหัส whuber โดยใช้การดำเนินการเมทริกซ์กระจัดกระจายสำหรับแต่ละขั้นตอนของกระบวนการ หากคุณสามารถเก็บเมทริกซ์ sparse ทั้งหมดในหน่วยความจำมันจะทำงานได้อย่างรวดเร็ว:
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))
หากคุณตั้งค่าจำนวนคอลัมน์เป็น 10,000 และจำนวนองค์ประกอบหลักเป็น 25 irlba
PCA ที่ใช้เวลาประมาณ 17 นาทีในการคำนวณส่วนประกอบหลักประมาณ 50 รายการและใช้ RAM ประมาณ 6GB ซึ่งไม่เลวร้ายเกินไป
X %*% v %*% diag(d, ncol=length(d))
ฉันใช้ v matrix ใน svd เทียบเท่ากับองค์ประกอบ "การหมุน" ของprcomp
วัตถุและX %*% v
หรือX %*% v %*% diag(d, ncol=length(d))
แสดงถึงx
องค์ประกอบของprcomp
วัตถุ stats:::prcomp.default
ใช้เวลาดู