数据矩阵的奇异值和协方差矩阵的特征值

机器算法验证 主成分分析 matlab svd
2022-03-19 22:37:10

我在 Matlab 中计算 SVD 和 PCA 时遇到了一些问题。我不知道我是在做理论错误还是编程错误。

从数据矩阵开始,PCA 计算协方差矩阵XλiXTX/(n1)

另一方面,X 的 SVDX 给出,因此其中的奇异值的对角矩阵XX=UΣV

XTX=VΣTUTUΣVT=VΣ2VT,
Σσi

所以我们有

λi=σi2/(n1).

现在我尝试一个 Matlab 示例:

    load hald;
    [u s v] = svd(ingredients);
    sigma = cov(ingredients);
    [a,b] = eig(sigma);
    disp('sigma')
    disp(diag(s)')
    disp('lambda')
    disp(diag(b)')

这是输出:

sigma
  211.3369   77.2356   28.4597   10.2667

lambda
    0.2372   12.4054   67.4964  517.7969

获得的值不尊重原始方程。错误在哪里?

1个回答

除了说明显而易见的事情:在降序eig时以升序给出结果svdsvd特征值(和特征向量显然)与eig分解的不同,因为您的矩阵ingredients开始就不对称。稍微解释一下维基百科:“X是正规和/或半正定矩阵,分解 X=UDU也是一个奇异值分解“,不是其他的。(U是的特征向量XXT)

例如,如果您执行以下操作:

rng(0,'twister')        %just set the seed.
Q = random('normal', 0,1,5);
X =  Q' * Q;            %so X is PSD 
[U S V]=    svd(X);
[A,B]=      eig(X);

max( abs(diag(S)- fliplr(diag(B)')' ))
% ans =  7.1054e-15     % AKA equal to numerical precision.

您会发现svdeig确实给您返回相同的结果。而之前正是因为矩阵ingredients至少不是 PSD(或者甚至不是正方形),好吧..你没有得到相同的结果。:)

换一种方式来说明:X=UΣV实际上转化为:X=1ruisiviT(r排名X)。这本身就意味着你(非常棒)被允许写作Xvi=σiui. 清楚地回到特征分解Xui=λiui你首先需要ui==vi. 非正态矩阵不能保证的东西。最后一点:小的数值差异是由于在后台工作的算法不同eigsvdQR 算法的变体svd和(通常)广义Schur 分解eig

针对您的问题,您想要的是类似于:

load hald;
[u s v]=svd(ingredients);
sigma=(ingredients' * ingredients); 
lambda =eig(sigma);     
max( abs(diag(s)- fliplr(sqrt(lambda)')' ))
% ans = 5.6843e-14

如您所见,这与将数据居中以使其具有意义无关0 此时矩阵ingredients不居中。

现在,如果您使用协方差矩阵(而不是像我那样使用简单的内积矩阵),则必须将数据居中假设这ingredients2是您的零均值样本。

ingredients2 = ingredients - repmat(mean(ingredients), 13,1);

那么你确实需要这种标准化1/(n1)

[u s v] =svd(ingredients2 );        
sigma = cov(ingredients); % You don't care about centring here
lambda =eig(sigma);   

max( abs( diag(s)- fliplr(sqrt(lambda *12)')')) % n = 13 so multiply by n-1
% ans = 4.7962e-14

所以,是的,它现在是居中的我最初有点误导,因为我使用的是 PSD 矩阵而不是协方差矩阵的概念。编辑前的答案很好。它准确地解决了为什么您的特征分解不适合您的奇异值分解。通过编辑,我展示了为什么您的奇异值分解不符合特征分解。显然,人们可以用两种不同的方式看待同一个问题。:D