假设有一个矩阵 B
,其大小为 500*1000 double
(这里,500
表示观测值的数量,1000
表示特征的数量)。
sigma
是矩阵 B
的协方差矩阵,D
是一个对角矩阵,其对角元素是 sigma
的特征值。假设 A
是协方差矩阵 sigma
的特征向量。
我有以下几个问题:
-
我需要选择前
k = 800
个特征值绝对值最大的特征向量来对选定的特征进行排序。最终矩阵命名为Aq
。我该如何在 MATLAB 中实现这一点? -
这些选定的特征向量有什么意义?
-
一旦我计算出
Aq
,最终矩阵Aq
的大小似乎是1000*800 double
。原本的500
个时间点/观测信息已经消失。对于最终矩阵Aq
,矩阵Aq
中的值1000
现在代表什么?同样,矩阵Aq
中的值800
现在代表什么?
回答:
我假设您是从 eig
函数中确定特征向量的。我建议您将来使用 eigs
函数。这不仅为您计算特征值和特征向量,而且会为您计算 k
个最大特征值及其对应的特征向量。这可以节省计算开销,因为您不需要计算矩阵的所有特征值和相关特征向量,而只需要一个子集。您只需将数据的协方差矩阵提供给 eigs
,它就会为您返回 k
个最大的特征值和特征向量。
现在,回到您的问题,您描述的是最终的主成分分析。其背后的机制是计算数据的协方差矩阵,并找到计算结果的特征值和特征向量。已知这样做是不推荐的,因为对于大型矩阵计算特征值和特征向量存在数值不稳定性。现在最经典的方法是通过奇异值分解。具体来说,矩阵 V
的列给出了协方差矩阵的特征向量,或主成分,相关特征值是矩阵 S
对角线上产生的奇异值的平方根。
请参阅 Cross Validated 上的这篇信息性帖子,了解为什么这是首选方法:
https://stats.stackexchange.com/questions/79043/why-pca-of-data-by-means-of-svd-of-the-data
我还提供另一个链接,讨论了为什么在主成分分析中使用奇异值分解的理论依据:
现在让我们逐一回答您的问题。
问题 #1
MATLAB 生成特征值和相应的特征向量排序方式是未排序的。如果您希望从 eig
的输出中选择出最大的 k
个特征值及其对应的特征向量(您示例中为 800),您需要将特征值按降序排序,然后重新排列 eig
生成的特征向量矩阵的列,然后选择出前 k
个值。
我还应该指出,使用 eigs
并不能保证排序顺序,所以在实际操作中,您也需要明确地对这些进行排序。
在 MATLAB 中,执行我们上述描述的操作看起来像这样:
sigma = cov(B);[A,D] = eig(sigma);vals = diag(D);[~,ind] = sort(abs(vals), 'descend');Asort = A(:,ind);
值得注意的是,您应该对特征值的绝对值进行排序,因为缩放后的特征值本身也是特征值。这些缩放也包括负值。这意味着,如果我们有一个其特征值为 -10000 的成分,这是一个很好的迹象,表明这个成分对您的数据有重要意义,如果我们仅根据数值本身进行排序,这将被放置在较低的排名附近。
第一行代码找到矩阵 B
的协方差矩阵,尽管您说它已经存储在 sigma
中,但让我们使其可重现。接下来,我们找到您的协方差矩阵的特征值及其对应的特征向量。请注意,特征向量矩阵 A
的每一列代表一个特征向量。具体来说,A
的第 i 列/特征向量对应于 D
中看到的第 i 个特征值。
然而,特征值位于一个对角矩阵中,所以我们使用 diag
命令提取对角线,排序它们并确定它们的顺序,然后重新排列 A
以尊重此顺序。我使用 sort
的第二个输出,因为它告诉您未排序结果中的每个值在排序结果中出现的位置。这是我们需要重新排列特征向量矩阵 A
列的顺序。您必须选择 'descend'
作为标志,以便最大的特征值及其对应的特征向量首先出现,就像我们之前讨论的那样。
然后您可以通过以下方式选出前 k
个最大的向量和值:
k = 800;Aq = Asort(:,1:k);
问题 #2
众所周知,协方差矩阵的特征向量等于主成分。具体来说,第一个主成分(即最大的特征向量和相关的最大的特征值)为您提供了数据中最大变异性的方向。之后的每个主成分为您提供递减性质的变异性。还值得注意的是,每个主成分彼此是正交的。
这里有一个来自维基百科的关于二维数据的好例子:
我从上面链接的维基百科关于主成分分析的文章中提取了上面的图片。这是一个散点图,样本按照以 (1,3)
为中心的双变量高斯分布分布,标准偏差在 (0.878, 0.478)
方向上大约为 3,在正交方向上为 1。标准偏差为 3 的成分是第一个主成分,而正交的成分是第二个成分。显示的向量是协方差矩阵的特征向量,按相应特征值的平方根缩放,并移动其尾部到均值位置。
现在让我们回到您的问题。我们查看 k
个最大特征值的原因是进行降维的一种方式。本质上,您将执行数据压缩,将高维数据投影到低维空间中。您在投影中包含的主成分越多,它将越接近原始数据。实际上,它在某个点上开始逐渐减少,但前几个主成分允许您在很大程度上忠实地重建数据。
我之前偶然发现的一个很棒的 Quora 帖子展示了执行 PCA(或更确切地说是 SVD)以及数据重建的很好的视觉示例。
问题 #3
您将使用此矩阵将高维数据重新投影到低维空间中。行数为 1000 仍然存在,这意味着您的原始数据集中有 1000 个特征。800 是您数据的降维后的维度。请将此矩阵视为从特征的原始维度(1000)转换到其降维后的维度(800)。
然后您将使用此矩阵与重建原始数据结合使用。具体来说,这将为您提供原始数据的近似值,误差最小。在这种情况下,您不需要使用所有主成分(即仅使用 k
个最大的向量),您可以使用比之前更少的信息创建数据的近似值。
如何重建您的数据非常简单。让我们先讨论一下使用完整数据的前向和反向操作。前向操作是将您的原始数据重新投影,但不是使用低维度,我们将使用所有成分。您首先需要对原始数据进行均值减法处理:
Bm = bsxfun(@minus, B, mean(B,1));
Bm
将生成一个矩阵,其中每个样本的每个特征都进行了均值减法处理。bsxfun
允许在不等维度的两个矩阵之间进行减法操作,前提是您可以广播维度,使它们能够匹配。在这种情况下,将发生的情况是计算 B
的每一列/特征的均值,并生成一个与 B
一样大的临时复制矩阵。当您用这个复制矩阵减去原始数据时,效果是用各自的特征均值减去每个数据点,从而使每个特征的均值为 0,从而使数据去中心化。
一旦完成此操作,投影操作非常简单:
Bproject = Bm*Asort;
上述操作非常简单。您所做的是将每个样本的特征表示为主成分的线性组合。例如,给定去中心化数据的第一行或第一个样本,投影域中第一个样本的特征是该行向量(涉及整个样本)与第一个主成分(列向量)的点积。投影域中第一个样本的第二个特征是整个样本与第二个成分的加权和。您将对所有样本和所有主成分重复此操作。实际上,您是在重新投影数据,使其相对于主成分 – 这些是正交基向量,将您的数