Matlab - 多维数据的PCA分析与重构

Posted

技术标签:

【中文标题】Matlab - 多维数据的PCA分析与重构【英文标题】:Matlab - PCA analysis and reconstruction of multi dimensional data 【发布时间】:2012-09-23 04:33:19 【问题描述】:

我有一个大型多维数据集(132 维)。

我是执行数据挖掘的初学者,我想使用 Matlab 应用主成分分析。但是,我看到网上解释了很多功能,但我不明白它们应该如何应用。

基本上,我想应用 PCA 并从我的数据中获取特征向量及其对应的特征值。

在这一步之后,我希望能够根据选择的获得的特征向量对我的数据进行重建。

我可以手动执行此操作,但我想知道是否有任何预定义的函数可以执行此操作,因为它们应该已经过优化。

我的初始数据类似于:size(x) = [33800 132]。所以基本上我有132 features(dimensions) 和33800 数据点。我想在这个数据集上执行 PCA。

任何帮助或提示都可以。

【问题讨论】:

【参考方案1】:

这里有一个快速演练。首先,我们创建一个隐藏变量(或“因素”)的矩阵。它有 100 个观测值,并且有两个独立的因素。

>> factors = randn(100, 2);

现在创建一个载荷矩阵。这会将隐藏变量映射到观察到的变量上。假设你观察到的变量有四个特征。那么你的负载矩阵需要是4 x 2

>> loadings = [
      1   0
      0   1
      1   1
      1  -1   ];

这告诉您第一个观察到的变量负载在第一个因素上,第二个负载在第二个因素上,第三个变量负载在因素的总和上,第四个变量负载在因素的差异上。

现在创建您的观察结果:

>> observations = factors * loadings' + 0.1 * randn(100,4);

我添加了少量随机噪声来模拟实验误差。现在我们使用统计工具箱中的pca 函数执行 PCA:

>> [coeff, score, latent, tsquared, explained, mu] = pca(observations);

变量score 是主成分分数的数组。这些将通过构造正交,您可以检查 -

>> corr(score)
ans =
    1.0000    0.0000    0.0000    0.0000
    0.0000    1.0000    0.0000    0.0000
    0.0000    0.0000    1.0000    0.0000
    0.0000    0.0000    0.0000    1.0000

score * coeff' 的组合将再现您观察的居中版本。在执行 PCA 之前减去平均值 mu。要重现您的原始观察结果,您需要将其重新添加,

>> reconstructed = score * coeff' + repmat(mu, 100, 1);
>> sum((observations - reconstructed).^2)
ans =
   1.0e-27 *
    0.0311    0.0104    0.0440    0.3378

要获得原始数据的近似值,您可以开始从计算的主成分中删除列。为了了解要删除哪些列,我们检查了explained 变量

>> explained
explained =
   58.0639
   41.6302
    0.1693
    0.1366

这些条目告诉您每个主成分解释了多少百分比的方差。我们可以清楚地看到前两个分量比后两个分量更显着(它们解释了它们之间超过 99% 的差异)。使用前两个分量来重建观测值可以得到 rank-2 近似值,

>> approximationRank2 = score(:,1:2) * coeff(:,1:2)' + repmat(mu, 100, 1);

我们现在可以尝试绘图了:

>> for k = 1:4
       subplot(2, 2, k);
       hold on;
       grid on
       plot(approximationRank2(:, k), observations(:, k), 'x');
       plot([-4 4], [-4 4]);
       xlim([-4 4]);
       ylim([-4 4]);
       title(sprintf('Variable %d', k));
   end

我们几乎完美地再现了原始观察结果。如果我们想要更粗略的近似,我们可以只使用第一个主成分:

>> approximationRank1 = score(:,1) * coeff(:,1)' + repmat(mu, 100, 1);

并绘制它,

>> for k = 1:4
       subplot(2, 2, k);
       hold on;
       grid on
       plot(approximationRank1(:, k), observations(:, k), 'x');
       plot([-4 4], [-4 4]);
       xlim([-4 4]);
       ylim([-4 4]);
       title(sprintf('Variable %d', k));
   end

这次重建不太好。那是因为我们故意将数据构建为包含两个因素,而我们只是从其中一个因素中重建它。

请注意,尽管我们构建原始数据的方式与其复制的方式相似,

>> observations  = factors * loadings'  +  0.1 * randn(100,4);
>> reconstructed = score   * coeff'     +  repmat(mu, 100, 1);

factorsscore 之间或loadingscoeff 之间不一定有任何对应关系。 PCA 算法对数据的构造方式一无所知 - 它只是尝试尽可能多地解释每个连续分量的总方差。


用户@Mari 在 cmets 中询问她如何将重建误差绘制为主成分数量的函数。使用上面的变量explained 非常容易。我将生成一些具有更有趣的因子结构的数据来说明效果 -

>> factors = randn(100, 20);
>> loadings = chol(corr(factors * triu(ones(20))))';
>> observations = factors * loadings' + 0.1 * randn(100, 20);

现在,所有观察结果都加载在一个重要的公因子上,而其他因素的重要性逐渐降低。我们可以像以前一样得到 PCA 分解

>> [coeff, score, latent, tsquared, explained, mu] = pca(observations);

并绘制解释方差的百分比如下,

>> cumexplained = cumsum(explained);
   cumunexplained = 100 - cumexplained;
   plot(1:20, cumunexplained, 'x-');
   grid on;
   xlabel('Number of factors');
   ylabel('Unexplained variance')

【讨论】:

很棒的答案。谢谢克里斯! 很好学习。非常感谢。不过,我有一个小小的疑问,为什么我们首先需要创建隐藏变量?我可以从[w pc ev] = princomp(X); 开始分析我的原始给定数据吗?再次感谢。 是的 - 我只需要生成数据,以便我有一些东西可以使用。如果您已经有数据,当然可以使用它。 我想弄清楚如何编写代码,将重构误差绘制为不同数量的主成分的函数。你能提示我吗?再次感谢。 我们如何使用它来预测一条新数据?【参考方案2】:

http://homepage.tudelft.nl/19j49/Matlab_Toolbox_for_Dimensionality_Reduction.html 有一个很好的降维工具箱 除了 PCA,这个工具箱还有很多其他的降维算法。

做PCA的例子:

Reduced = compute_mapping(Features, 'PCA', NumberOfDimension);

【讨论】:

以上是关于Matlab - 多维数据的PCA分析与重构的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB做主成分分析(PCA)

PCA图像数据降维及重构误差分析实战并使用TSNE进行异常数据可视化分析

十一.PCA案例分析及小结

PCA主成分分析(降维)

多维尺度分析(Multidimensional scaling)与MATLAB实现

主分量分析PCA