在数据分析中选择协方差矩阵中最大的特征值和特征向量意味着什么?
What does selecting the largest eigenvalues and eigenvectors in the covariance matrix mean in data analysis?
假设有一个矩阵B
,它的大小是一个500*1000 double
(这里,500
代表观测数,1000
代表特征数).
sigma
是B
的协方差矩阵,D
是对角元素为sigma
的特征值的对角矩阵。假设 A
是协方差矩阵 sigma
.
的特征向量
我有以下问题:
我需要select前k = 800
个对应于具有最大幅度的特征值的特征向量来对selected特征进行排序。最终矩阵命名为 Aq
。我如何在 MATLAB 中执行此操作?
这些selected特征向量是什么意思?
一旦我计算 Aq
,最终矩阵 Aq
的大小似乎是 1000*800 double
。 500
的时间points/observation信息已经消失。对于最终的矩阵Aq
,矩阵Aq
中的值1000
现在代表什么?另外,矩阵Aq
中的值800
现在代表什么?
我假设您从 eig
function. What I would recommend to you in the future is to use the eigs
函数中确定了特征向量。这不仅会为您计算特征值和特征向量,还会为您计算 k
largest 特征值及其相关的特征向量。这可以节省计算开销,您不必计算矩阵的所有特征值和关联的特征向量,因为您只需要一个子集。您只需将数据的协方差矩阵提供给 eigs
,它 returns 为您提供 k
最大的特征值和特征向量。
现在,回到你的问题,你所描述的最终是Principal Component Analysis. The mechanics behind this would be to compute the covariance matrix of your data and find the eigenvalues and eigenvectors of the computed result. It has been known that doing it this way is not recommended due to numerical instability with computing the eigenvalues and eigenvectors for large matrices. The most canonical way to do this now is via Singular Value Decomposition。具体来说,V
矩阵的列为您提供协方差矩阵的特征向量或主成分,相关的特征值是矩阵 S
对角线上产生的奇异值的平方根.
在 Cross Validated 上查看此信息 post,了解为什么首选此方法:
https://stats.stackexchange.com/questions/79043/why-pca-of-data-by-means-of-svd-of-the-data
我还要再补充一个link,讨论为什么在主成分分析中使用奇异值分解背后的理论:
现在让我们一次回答一个问题。
问题 #1
MATLAB 以未排序 的方式生成特征值和特征向量的相应排序。如果您希望 select 给出最大的 k
特征值和相关的特征向量,给定 eig
的输出(在您的示例中为 800),您需要 sort 特征值按降序排列,然后重新排列从 eig
产生的特征向量矩阵的列,然后 select 出第一个 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
的第ith列/特征向量对应于D
中看到的第ith个特征值。
然而,特征值在对角矩阵中,因此我们使用 diag
命令提取对角线,对它们进行排序并计算出它们的顺序,然后重新排列 A
以遵守此顺序。我使用 sort
的第二个输出,因为它告诉您未排序结果中的每个值在排序结果中出现的位置。这是我们需要重新排列特征向量矩阵 A
列的顺序。必须选择 'descend'
作为标志,这样最大的特征值和关联的特征向量首先出现,就像我们之前谈到的那样。
然后您可以通过以下方式提取前 k
个最大的向量和值:
k = 800;
Aq = Asort(:,1:k);
问题 #2
众所周知,协方差矩阵的特征向量等于主成分。具体而言,第一个主成分(即最大特征向量和关联的最大特征值)为您提供数据中 最大可变性 的方向。此后的每个主成分都会为您提供递减性质的可变性。还需要注意的是,每个主成分彼此 正交 。
这是维基百科中二维数据的一个很好的例子:
我从关于主成分分析的维基百科文章中提取了上面的图片,我 link 将你带到了上面。这是根据以 (1,3)
为中心的双变量高斯分布分布的样本散点图,标准差在大致 (0.878, 0.478)
方向上为 3,在正交方向上为 1。标准差为 3 的分量是第一主分量,而正交的分量是第二主分量。显示的向量是协方差矩阵的特征向量,按相应特征值的平方根缩放,并移动以使它们的尾部位于平均值。
现在让我们回到你的问题。我们之所以看k
个最大的特征值是一种执行dimensionality reduction的方式。本质上,您将执行数据压缩,您将获取高维数据并将它们投影到低维 space。您在投影中包含的主要成分越多,它就越像原始数据。它实际上在某个点开始逐渐减少,但前几个主成分允许您忠实地重建大部分数据。
执行 PCA(或更确切地说是 SVD)和数据重建的一个很好的视觉示例是由这个很棒的 Quora post 我过去偶然发现的。
问题 #3
您将使用此矩阵将高维数据重新投影到低维 space。行数 1000 仍然存在,这意味着您的数据集中最初有 1000 个要素。 800 是数据的降维数。将此矩阵视为从特征的原始维度 (1000) 向下到其缩减维度 (800) 的转换。
然后您可以将此矩阵与重构原始数据结合使用。具体来说,这将为您提供原始数据的近似值,并且误差最少。在这种情况下,您不需要使用所有主要成分(即仅 k
个最大的向量),您可以使用比以前更少的信息创建数据的近似值。
重建数据的方式非常简单。先用全量数据说一下正向和反向操作。前向操作是获取原始数据并对其进行重新投影,但我们将使用 all 组件而不是较低的维度。你首先需要有你的原始数据,但要减去平均值:
Bm = bsxfun(@minus, B, mean(B,1));
Bm
将生成一个矩阵,其中每个样本的每个特征都被平均减去。 bsxfun
允许在不等维的情况下对两个矩阵进行减法,前提是您可以 广播 维数,以便它们可以匹配。具体来说,在这种情况下会发生的是计算 B
的每一列/特征的平均值,并生成一个与 B
一样大的临时复制矩阵。当您用这个复制矩阵减去原始数据时,效果将减去每个数据点及其各自的特征均值,从而分散数据,使每个特征的均值为 0。
一旦你这样做了,对项目的操作就是:
Bproject = Bm*Asort;
以上操作很简单。您正在做的是将每个样本的特征表示为主要成分的线性组合。例如,给定分散数据的第一个样本或第一行,投影域中的第一个样本的特征是属于整个样本的行向量与作为列向量的第一个主成分的点积。第一个样本在投影域中的第二个特征是整个样本和第二个分量的加权和。您将为所有样本和所有主要成分重复此操作。实际上,您正在重新投影数据,使其与主成分有关——主成分是将数据从一种表示形式转换为另一种表示形式的正交基向量。
可以在此处找到对我刚才谈到的内容的更好描述。看Amro的回答:
Matlab Principal Component Analysis (eigenvalues order)
现在要倒退,你只需进行逆运算,但特征向量矩阵的一个特殊 属性 是,如果你转置它,你会得到逆。要取回原始数据,您撤消上面的操作并将方法添加回问题:
out = bsxfun(@plus, Bproject*Asort.', mean(B, 1));
您想取回原始数据,因此您要解决 Bm
关于我之前所做的操作。然而, Asort
的倒数在这里只是转置。执行此操作后发生的事情是您正在取回原始数据,但数据仍然是分散的。要取回原始数据,必须将每个特征的均值加回到数据矩阵中,才能得到最终的结果。这就是我们在这里使用另一个 bsxfun
调用的原因,这样您就可以为每个样本的特征值执行此操作。
上面两行代码应该可以在原始域和投影域之间来回切换。现在降维(或原始数据的近似值)发挥作用的是反向操作。您首先需要做的是将数据投影到主成分的基础上(即前向操作),但现在回到我们试图用减少数量的主成分重建数据的原始域,您只需将上面代码中的 Asort
替换为 Aq
并减少您在 Bproject
中使用的功能数量。具体来说:
out = bsxfun(@plus, Bproject(:,1:k)*Aq.', mean(B, 1));
Bproject(:,1:k)
select 得出数据投影域中的 k
特征,对应于 k
最大特征向量。有趣的是,如果您只想要关于降维的数据表示,您可以只使用 Bproject(:,1:k)
就足够了。然而,如果你想继续计算原始数据的近似值,我们需要计算反向步骤。上面的代码只是我们之前对您的数据的完整维度所做的,但是我们使用 Aq
以及 select 排除 Bproject
中的 k
特征。这将为您提供由矩阵中 k
最大特征向量/特征值表示的原始数据。
如果您想看一个很棒的示例,我将模仿我 link 教给您的 Quora post,但使用另一张图片。考虑使用灰度图像执行此操作,其中每一行都是一个 "sample",每一列都是一个特征。让我们以图像处理工具箱中的摄影师图像为例:
im = imread('camerman.tif');
imshow(im); %// Using the image processing toolbox
我们得到这张图片:
这是一张 256 x 256 的图像,这意味着我们有 256 个数据点,每个点有 256 个特征。我要做的是将图像转换为 double
以精确计算协方差矩阵。现在我要做的是重复上面的代码,但每次从 3、11、15、25、45、65 和 125 开始逐渐增加 k
。因此,对于每个 k
,我们正在引入更多的主成分,我们应该慢慢开始重建我们的数据。
这里有一些可运行的代码可以说明我的观点:
%%%%%%%// Pre-processing stage
clear all;
close all;
%// Read in image - make sure we cast to double
B = double(imread('cameraman.tif'));
%// Calculate covariance matrix
sigma = cov(B);
%// Find eigenvalues and eigenvectors of the covariance matrix
[A,D] = eig(sigma);
vals = diag(D);
%// Sort their eigenvalues
[~,ind] = sort(abs(vals), 'descend');
%// Rearrange eigenvectors
Asort = A(:,ind);
%// Find mean subtracted data
Bm = bsxfun(@minus, B, mean(B,1));
%// Reproject data onto principal components
Bproject = Bm*Asort;
%%%%%%%// Begin reconstruction logic
figure;
counter = 1;
for k = [3 11 15 25 45 65 125 155]
%// Extract out highest k eigenvectors
Aq = Asort(:,1:k);
%// Project back onto original domain
out = bsxfun(@plus, Bproject(:,1:k)*Aq.', mean(B, 1));
%// Place projection onto right slot and show the image
subplot(4, 2, counter);
counter = counter + 1;
imshow(out,[]);
title(['k = ' num2str(k)]);
end
如您所见,大部分代码与我们看到的相同。不同之处在于,我遍历 k
的所有值,投影回具有 k
最高特征向量的原始 space(即计算近似值),然后显示图像。
我们得到了这个漂亮的数字:
如您所见,从 k=3
开始并没有真正给我们带来任何好处...我们可以看到一些通用结构,但添加更多内容也无妨。随着我们开始增加组件的数量,我们开始更清楚地了解原始数据的样子。在 k=25
,我们实际上可以完美地看到摄影师的样子,而且我们不需要 26 及以后的组件来查看发生了什么。这就是我所说的关于数据压缩的内容,您无需处理所有主要组件即可清楚地了解正在发生的事情。
我想通过向您推荐 Chris Taylor 关于主成分分析主题的精彩阐述来结束这篇笔记,其中包含代码、图表和精彩的解释!这是我开始使用 PCA 的地方,但是 Quora post 巩固了我的知识。
Matlab - PCA analysis and reconstruction of multi dimensional data
假设有一个矩阵B
,它的大小是一个500*1000 double
(这里,500
代表观测数,1000
代表特征数).
sigma
是B
的协方差矩阵,D
是对角元素为sigma
的特征值的对角矩阵。假设 A
是协方差矩阵 sigma
.
我有以下问题:
我需要select前
k = 800
个对应于具有最大幅度的特征值的特征向量来对selected特征进行排序。最终矩阵命名为Aq
。我如何在 MATLAB 中执行此操作?这些selected特征向量是什么意思?
一旦我计算
Aq
,最终矩阵Aq
的大小似乎是1000*800 double
。500
的时间points/observation信息已经消失。对于最终的矩阵Aq
,矩阵Aq
中的值1000
现在代表什么?另外,矩阵Aq
中的值800
现在代表什么?
我假设您从 eig
function. What I would recommend to you in the future is to use the eigs
函数中确定了特征向量。这不仅会为您计算特征值和特征向量,还会为您计算 k
largest 特征值及其相关的特征向量。这可以节省计算开销,您不必计算矩阵的所有特征值和关联的特征向量,因为您只需要一个子集。您只需将数据的协方差矩阵提供给 eigs
,它 returns 为您提供 k
最大的特征值和特征向量。
现在,回到你的问题,你所描述的最终是Principal Component Analysis. The mechanics behind this would be to compute the covariance matrix of your data and find the eigenvalues and eigenvectors of the computed result. It has been known that doing it this way is not recommended due to numerical instability with computing the eigenvalues and eigenvectors for large matrices. The most canonical way to do this now is via Singular Value Decomposition。具体来说,V
矩阵的列为您提供协方差矩阵的特征向量或主成分,相关的特征值是矩阵 S
对角线上产生的奇异值的平方根.
在 Cross Validated 上查看此信息 post,了解为什么首选此方法:
https://stats.stackexchange.com/questions/79043/why-pca-of-data-by-means-of-svd-of-the-data
我还要再补充一个link,讨论为什么在主成分分析中使用奇异值分解背后的理论:
现在让我们一次回答一个问题。
问题 #1
MATLAB 以未排序 的方式生成特征值和特征向量的相应排序。如果您希望 select 给出最大的 k
特征值和相关的特征向量,给定 eig
的输出(在您的示例中为 800),您需要 sort 特征值按降序排列,然后重新排列从 eig
产生的特征向量矩阵的列,然后 select 出第一个 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
的第ith列/特征向量对应于D
中看到的第ith个特征值。
然而,特征值在对角矩阵中,因此我们使用 diag
命令提取对角线,对它们进行排序并计算出它们的顺序,然后重新排列 A
以遵守此顺序。我使用 sort
的第二个输出,因为它告诉您未排序结果中的每个值在排序结果中出现的位置。这是我们需要重新排列特征向量矩阵 A
列的顺序。必须选择 'descend'
作为标志,这样最大的特征值和关联的特征向量首先出现,就像我们之前谈到的那样。
然后您可以通过以下方式提取前 k
个最大的向量和值:
k = 800;
Aq = Asort(:,1:k);
问题 #2
众所周知,协方差矩阵的特征向量等于主成分。具体而言,第一个主成分(即最大特征向量和关联的最大特征值)为您提供数据中 最大可变性 的方向。此后的每个主成分都会为您提供递减性质的可变性。还需要注意的是,每个主成分彼此 正交 。
这是维基百科中二维数据的一个很好的例子:
我从关于主成分分析的维基百科文章中提取了上面的图片,我 link 将你带到了上面。这是根据以 (1,3)
为中心的双变量高斯分布分布的样本散点图,标准差在大致 (0.878, 0.478)
方向上为 3,在正交方向上为 1。标准差为 3 的分量是第一主分量,而正交的分量是第二主分量。显示的向量是协方差矩阵的特征向量,按相应特征值的平方根缩放,并移动以使它们的尾部位于平均值。
现在让我们回到你的问题。我们之所以看k
个最大的特征值是一种执行dimensionality reduction的方式。本质上,您将执行数据压缩,您将获取高维数据并将它们投影到低维 space。您在投影中包含的主要成分越多,它就越像原始数据。它实际上在某个点开始逐渐减少,但前几个主成分允许您忠实地重建大部分数据。
执行 PCA(或更确切地说是 SVD)和数据重建的一个很好的视觉示例是由这个很棒的 Quora post 我过去偶然发现的。
问题 #3
您将使用此矩阵将高维数据重新投影到低维 space。行数 1000 仍然存在,这意味着您的数据集中最初有 1000 个要素。 800 是数据的降维数。将此矩阵视为从特征的原始维度 (1000) 向下到其缩减维度 (800) 的转换。
然后您可以将此矩阵与重构原始数据结合使用。具体来说,这将为您提供原始数据的近似值,并且误差最少。在这种情况下,您不需要使用所有主要成分(即仅 k
个最大的向量),您可以使用比以前更少的信息创建数据的近似值。
重建数据的方式非常简单。先用全量数据说一下正向和反向操作。前向操作是获取原始数据并对其进行重新投影,但我们将使用 all 组件而不是较低的维度。你首先需要有你的原始数据,但要减去平均值:
Bm = bsxfun(@minus, B, mean(B,1));
Bm
将生成一个矩阵,其中每个样本的每个特征都被平均减去。 bsxfun
允许在不等维的情况下对两个矩阵进行减法,前提是您可以 广播 维数,以便它们可以匹配。具体来说,在这种情况下会发生的是计算 B
的每一列/特征的平均值,并生成一个与 B
一样大的临时复制矩阵。当您用这个复制矩阵减去原始数据时,效果将减去每个数据点及其各自的特征均值,从而分散数据,使每个特征的均值为 0。
一旦你这样做了,对项目的操作就是:
Bproject = Bm*Asort;
以上操作很简单。您正在做的是将每个样本的特征表示为主要成分的线性组合。例如,给定分散数据的第一个样本或第一行,投影域中的第一个样本的特征是属于整个样本的行向量与作为列向量的第一个主成分的点积。第一个样本在投影域中的第二个特征是整个样本和第二个分量的加权和。您将为所有样本和所有主要成分重复此操作。实际上,您正在重新投影数据,使其与主成分有关——主成分是将数据从一种表示形式转换为另一种表示形式的正交基向量。
可以在此处找到对我刚才谈到的内容的更好描述。看Amro的回答:
Matlab Principal Component Analysis (eigenvalues order)
现在要倒退,你只需进行逆运算,但特征向量矩阵的一个特殊 属性 是,如果你转置它,你会得到逆。要取回原始数据,您撤消上面的操作并将方法添加回问题:
out = bsxfun(@plus, Bproject*Asort.', mean(B, 1));
您想取回原始数据,因此您要解决 Bm
关于我之前所做的操作。然而, Asort
的倒数在这里只是转置。执行此操作后发生的事情是您正在取回原始数据,但数据仍然是分散的。要取回原始数据,必须将每个特征的均值加回到数据矩阵中,才能得到最终的结果。这就是我们在这里使用另一个 bsxfun
调用的原因,这样您就可以为每个样本的特征值执行此操作。
上面两行代码应该可以在原始域和投影域之间来回切换。现在降维(或原始数据的近似值)发挥作用的是反向操作。您首先需要做的是将数据投影到主成分的基础上(即前向操作),但现在回到我们试图用减少数量的主成分重建数据的原始域,您只需将上面代码中的 Asort
替换为 Aq
并减少您在 Bproject
中使用的功能数量。具体来说:
out = bsxfun(@plus, Bproject(:,1:k)*Aq.', mean(B, 1));
Bproject(:,1:k)
select 得出数据投影域中的 k
特征,对应于 k
最大特征向量。有趣的是,如果您只想要关于降维的数据表示,您可以只使用 Bproject(:,1:k)
就足够了。然而,如果你想继续计算原始数据的近似值,我们需要计算反向步骤。上面的代码只是我们之前对您的数据的完整维度所做的,但是我们使用 Aq
以及 select 排除 Bproject
中的 k
特征。这将为您提供由矩阵中 k
最大特征向量/特征值表示的原始数据。
如果您想看一个很棒的示例,我将模仿我 link 教给您的 Quora post,但使用另一张图片。考虑使用灰度图像执行此操作,其中每一行都是一个 "sample",每一列都是一个特征。让我们以图像处理工具箱中的摄影师图像为例:
im = imread('camerman.tif');
imshow(im); %// Using the image processing toolbox
我们得到这张图片:
这是一张 256 x 256 的图像,这意味着我们有 256 个数据点,每个点有 256 个特征。我要做的是将图像转换为 double
以精确计算协方差矩阵。现在我要做的是重复上面的代码,但每次从 3、11、15、25、45、65 和 125 开始逐渐增加 k
。因此,对于每个 k
,我们正在引入更多的主成分,我们应该慢慢开始重建我们的数据。
这里有一些可运行的代码可以说明我的观点:
%%%%%%%// Pre-processing stage
clear all;
close all;
%// Read in image - make sure we cast to double
B = double(imread('cameraman.tif'));
%// Calculate covariance matrix
sigma = cov(B);
%// Find eigenvalues and eigenvectors of the covariance matrix
[A,D] = eig(sigma);
vals = diag(D);
%// Sort their eigenvalues
[~,ind] = sort(abs(vals), 'descend');
%// Rearrange eigenvectors
Asort = A(:,ind);
%// Find mean subtracted data
Bm = bsxfun(@minus, B, mean(B,1));
%// Reproject data onto principal components
Bproject = Bm*Asort;
%%%%%%%// Begin reconstruction logic
figure;
counter = 1;
for k = [3 11 15 25 45 65 125 155]
%// Extract out highest k eigenvectors
Aq = Asort(:,1:k);
%// Project back onto original domain
out = bsxfun(@plus, Bproject(:,1:k)*Aq.', mean(B, 1));
%// Place projection onto right slot and show the image
subplot(4, 2, counter);
counter = counter + 1;
imshow(out,[]);
title(['k = ' num2str(k)]);
end
如您所见,大部分代码与我们看到的相同。不同之处在于,我遍历 k
的所有值,投影回具有 k
最高特征向量的原始 space(即计算近似值),然后显示图像。
我们得到了这个漂亮的数字:
如您所见,从 k=3
开始并没有真正给我们带来任何好处...我们可以看到一些通用结构,但添加更多内容也无妨。随着我们开始增加组件的数量,我们开始更清楚地了解原始数据的样子。在 k=25
,我们实际上可以完美地看到摄影师的样子,而且我们不需要 26 及以后的组件来查看发生了什么。这就是我所说的关于数据压缩的内容,您无需处理所有主要组件即可清楚地了解正在发生的事情。
我想通过向您推荐 Chris Taylor 关于主成分分析主题的精彩阐述来结束这篇笔记,其中包含代码、图表和精彩的解释!这是我开始使用 PCA 的地方,但是 Quora post 巩固了我的知识。
Matlab - PCA analysis and reconstruction of multi dimensional data