应该取多少个主成分?

50

我知道主成分分析在矩阵上执行SVD然后生成特征值矩阵。为了选择主成分,我们只需要取前几个特征值。那么,我们如何决定从特征值矩阵中应该取多少个特征值呢?

6个回答

55

要决定保留多少个特征值/特征向量,你需要考虑最初进行PCA的原因。是为了减少存储需求,为分类算法降维,还是出于其他原因?如果没有严格的限制,建议绘制特征值的累计和(假设它们按降序排列)。如果在绘图之前将每个值除以特征值的总和,则您的图将显示所保留的总方差的分数与特征值数量的关系。然后,该图将提供一个很好的指示,告诉您何时达到收益递减点(即,通过保留额外的特征值几乎不会增加方差)。


1
这是一篇很棒的文章,提供了更详细的解释和代码计算,该计算方法在下面的答案中有所描述。https://www.mikulskibartosz.name/pca-how-to-choose-the-number-of-components/ - jbmeerkat

33

这个问题没有正确答案,它应该在1到n之间。

把主成分想象成你从未去过的一个镇上的街道。你需要走多少条街才能了解这个镇?

显然,你应该先游览主要街道(也就是第一个成分),可能还要走一些其他大街。你需要游览每一条街道才能完全了解这个镇吗?也许不需要。

要完美地了解这个镇,你应该游览所有的街道。但是如果你只需要游览50条街道中的10条,就能对这个镇有95%的了解程度,那么这已经足够好了吗?

基本上,你应该选择足够数量的成分来解释足够多的方差,以使你感到满意。


11

正如其他人所说,绘制解释的方差对结果并没有害处。

如果你将PCA作为监督学习任务的预处理步骤,你应该交叉验证整个数据处理流程,并将PCA维度数量视为超参数,使用最终监督得分(例如分类的F1得分或回归的RMSE)在网格搜索中选择。

如果在整个数据集上进行交叉验证的网格搜索过于昂贵,请在两个子样本上尝试,例如一个包含1%的数据,另一个包含10%的数据,并查看是否得出相同的PCA维度的最优值。


9

有许多启发式算法可以使用。

例如,选择捕获至少85%总方差的前k个特征向量。

但是,对于高维度情况下,这些启发式算法通常不太好用。


2
谢谢。只是一个小问题。特征向量会按降序排列,对吗?您的意思是前k个特征值占总特征值和的85%吗? - London guy
9
是的,特征值对应于相对方差。但是高方差是否等于高重要性还有疑问。在低维度中,例如物理x、y、z轴,这是有意义的。但当维度具有不同的含义和比例时,这种解释就不再有意义了。 - Has QUIT--Anony-Mousse

7
根据您的情况,定义最大允许相对误差可能很有趣,方法是将数据投影到ndim维度上。 Matlab示例 我将用一个小的Matlab示例来说明这一点。如果您对此不感兴趣,请跳过代码。
我将首先生成一个随机矩阵,包含n个样本(行)和p个特征,恰好包含100个非零主成分。
n = 200;
p = 119;
data = zeros(n, p);
for i = 1:100
  data = data + rand(n, 1)*rand(1, p);
end

图像将类似于:

enter image description here

对于这个示例图像,可以通过以下方式计算将输入数据投影到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

在维度(主成分)数量的函数相对误差图中绘制结果如下:

enter image description here

根据此图表,您可以决定需要考虑多少主成分。在这个理论图像中,使用100个成分会得到精确的图像表示。因此,超过100个元素是没有用的。例如,如果您想要最大5%的误差,则应该考虑约40个主成分。
免责声明:所获得的值仅适用于我的人工数据。因此,请不要盲目地在您的情况下使用建议的值,而是执行相同的分析并在您需要的成分数量和误差之间进行权衡。
代码参考:
- 迭代算法基于 pcares 的源代码 - 有关 pcaresStackOverflow帖子

请原谅我的无知,您的代码是用哪种语言编写的? - ww2406
@ww2406 代码是用Matlab编写的。更新了答案以清楚地指示它,并提供了正确的代码高亮显示。 - m7913d

6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接