我有一个较大的数据集(1000 个样本的 400,000 个变量)。我想确定这些变量的最佳集合,以捕获样本之间的大部分差异。
执行迭代主成分分析的最佳方法是什么,该分析可能每次都会在 Y 和 Z 变量之间进行 X 轮,并产生一个列表,其中列出了哪一轮导致最少数量的 PC 来捕获一定百分比的方差?
我有一个较大的数据集(1000 个样本的 400,000 个变量)。我想确定这些变量的最佳集合,以捕获样本之间的大部分差异。
执行迭代主成分分析的最佳方法是什么,该分析可能每次都会在 Y 和 Z 变量之间进行 X 轮,并产生一个列表,其中列出了哪一轮导致最少数量的 PC 来捕获一定百分比的方差?
据我了解您的问题,主要问题是数据集的大小,而不是它包含缺失值(即“稀疏”)。对于这样的问题,我建议进行部分 PCA 以解决领先 PC 的子集。该软件包irlba通过执行“Lanczos bidiagonalization”来实现这一点。当您只对返回一些领先的 PC 感兴趣时,对于大型矩阵来说,速度要快得多。在下面的示例中,我将我在此处讨论的引导技术改编为一个函数,该函数结合了此方法以及可变的子采样参数。在函数bootpca中,您可以定义要采样的变量n数、要返回的 PCnpc数、以及迭代次数B用于子采样程序。对于这种方法,我对子采样矩阵进行了居中和缩放,以标准化数据集的方差并允许矩阵分解的奇异值之间的可比性。通过制作这些自举奇异值的箱线图lam,您应该能够区分携带信号的 PC 和以噪声为主的 PC。
m=50
n=100
x <- (seq(m)*2*pi)/m
t <- (seq(n)*2*pi)/n
#field
Xt <-
outer(sin(x), sin(t)) +
outer(sin(2.1*x), sin(2.1*t)) +
outer(sin(3.1*x), sin(3.1*t)) +
outer(tanh(x), cos(t)) +
outer(tanh(2*x), cos(2.1*t)) +
outer(tanh(4*x), cos(0.1*t)) +
outer(tanh(2.4*x), cos(1.1*t)) +
tanh(outer(x, t, FUN="+")) +
tanh(outer(x, 2*t, FUN="+"))
Xt <- t(Xt)
image(Xt)
#Noisy field
set.seed(1)
RAND <- matrix(runif(length(Xt), min=-1, max=1), nrow=nrow(Xt), ncol=ncol(Xt))
R <- RAND * 0.2 * Xt
#True field + Noise field
Xp <- Xt + R
image(Xp)
library(irlba)
bootpca <- function(mat, n=0.5*nrow(mat), npc=10, B=40*nrow(mat)){
lam <- matrix(NaN, nrow=npc, ncol=B)
for(b in seq(B)){
samp.b <- NaN*seq(n)
for(i in seq(n)){
samp.b[i] <- sample(nrow(mat), 1)
}
mat.b <- scale(mat[samp.b,], center=TRUE, scale=TRUE)
E.b <- irlba(mat.b, nu=npc, nv=npc)
lam[,b] <- E.b$d
print(paste(round(b/B*100), "%", " completed", sep=""))
}
lam
}
res <- bootpca(Xp, n=0.5*nrow(Xp), npc=15, B=999) #50% of variables used in each iteration, 15 PCs computed, and 999 iterations
par(mar=c(4,4,1,1))
boxplot(t(res), log="y", col=8, outpch="", ylab="Lambda [log-scale]")

很明显,领先的 5 台 PC 携带的信息最多,尽管从技术上讲,示例数据集中有 9 个信号。
对于非常大的数据集,您可能希望在每次迭代中使用较小部分的变量(即行),但要进行多次迭代。
为什么不直接对全套进行 PCA 并看看它带你去哪里?PCA 的计算速度非常快,您将能够快速确定有多少变量似乎对前几个组件很重要。我已经成功处理了这么多变量(尽管样本量较小)。
或者,您可以尝试正则化 PCA 或稀疏 PCA 之类的方法。如果您使用的是 R,请查看包“elasticnet”和“mixOmics”。