我知道主成分分析对矩阵进行 SVD,然后生成特征值矩阵。要选择主成分,我们只需要取前几个特征值。现在,我们如何确定应该从特征值矩阵中获取的特征值的数量?
6 回答
要决定保留多少个特征值/特征向量,您应该首先考虑您进行 PCA 的原因。您这样做是为了减少存储需求,减少分类算法的维数,还是出于其他原因?如果您没有任何严格的约束,我建议绘制特征值的累积和(假设它们按降序排列)。如果在绘图之前将每个值除以特征值的总和,那么您的绘图将显示保留的总方差与特征值数量的比例。然后,该图将很好地指示您何时达到收益递减点(即,通过保留额外的特征值获得的方差很小)。
没有正确答案,它介于 1 和 n 之间。
将主要组成部分想象为您从未去过的城镇中的一条街道。您应该走多少条街道才能了解这座城市?
好吧,您显然应该参观主要街道(第一个组成部分),也许还应该参观其他一些大街道。您是否需要走遍每条街道才能充分了解这座城市?可能不是。
要完全了解这个小镇,你应该走遍所有的街道。但是,如果你可以参观,比如说 50 条街道中的 10 条,并且对小镇有 95% 的了解,那会怎样?这够好吗?
基本上,您应该选择足够多的组件来解释您所接受的足够多的方差。
正如其他人所说,绘制解释的方差并没有什么坏处。
如果您使用 PCA 作为监督学习任务的预处理步骤,您应该交叉验证整个数据处理管道并将 PCA 维度的数量视为超参数,以使用最终监督分数的网格搜索(例如分类的 F1 分数)或 RMSE 进行回归)。
如果对整个数据集进行交叉验证的网格搜索成本太高,请尝试使用 2 个子样本,例如,一个具有 1% 的数据,第二个具有 10% 的数据,看看您是否为 PCA 维度得出相同的最佳值。
有许多启发式方法用于此。
例如,取前 k 个特征向量,它至少捕获总方差的 85% 。
然而,对于高维,这些启发式方法通常不是很好。
根据您的情况,通过在ndim
维度上投影数据来定义最大允许相对误差可能会很有趣。
Matlab 示例
我将用一个小的 matlab 示例来说明这一点。如果您对它不感兴趣,请跳过代码。
我将首先生成一个包含恰好 100 个非零主成分的n
样本(行)和特征的随机矩阵。p
n = 200;
p = 119;
data = zeros(n, p);
for i = 1:100
data = data + rand(n, 1)*rand(1, p);
end
该图像将类似于:
对于此示例图像,可以通过将输入数据投影到ndim
维度来计算相对误差,如下所示:
[coeff,score] = pca(data,'Economy',true);
relativeError = zeros(p, 1);
for ndim=1:p
reconstructed = repmat(mean(data,1),n,1) + score(:,1:ndim)*coeff(:,1:ndim)';
residuals = data - reconstructed;
relativeError(ndim) = max(max(residuals./data));
end
绘制维数(主成分)函数的相对误差,得到下图:
根据此图,您可以决定需要考虑多少主成分。在这个理论图像中,100 个分量会产生精确的图像表示。所以,取超过 100 个元素是没有用的。例如,如果您想要最大 5% 的误差,您应该采用大约 40 个主成分。
免责声明:获得的值仅对我的人工数据有效。因此,不要在您的情况下盲目使用建议的值,而是执行相同的分析并在您犯的错误和您需要的组件数量之间进行权衡。
代码参考
- 迭代算法是基于源代码的
pcares
- 一篇关于StackOverflow 的帖子
pcares
我强烈推荐 Gavish 和 Donoho 的以下论文:The Optimal Hard Threshold for Singular Values is 4/sqrt(3)。
我在CrossValidated (stats.stackexchange.com)上发布了一个更长的总结。简而言之,他们在非常大的矩阵的限制下获得了一个最佳过程。该过程非常简单,不需要任何手动调整的参数,并且在实践中似乎效果很好。
他们在这里有一个很好的代码补充:https ://purl.stanford.edu/vg705qn9070