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

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

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

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

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

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

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

任何帮助或提示都可以。

【问题讨论】:

    标签: matlab data-mining 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 2017-08-19
      • 2017-08-05
      • 2012-03-01
      • 2020-04-13
      • 2014-01-02
      相关资源
      最近更新 更多