Matlab - PCA分析和多维数据重建

Sim*_*mon 19 matlab data-mining pca

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

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

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

在此步骤之后,我希望能够基于所获得的特征向量的选择来对我的数据进行重建.

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

我的初始数据如下:size(x) = [33800 132].所以基本上我有132功能(维度)和33800数据点.我想在这个数据集上执行PCA.

任何帮助或提示都可以.

Chr*_*lor 48

这是一个快速的演练.首先,我们创建隐藏变量(或"因子")的矩阵.它有100个观测值,有两个独立因素.

>> factors = randn(100, 2);
Run Code Online (Sandbox Code Playgroud)

现在创建一个加载矩阵.这将隐藏变量映射到您观察到的变量.假设您观察到的变量有四个特征.然后你的装载矩阵需要4 x 2

>> loadings = [
      1   0
      0   1
      1   1
      1  -1   ];
Run Code Online (Sandbox Code Playgroud)

这告诉你第一个观察变量加载第一个因子,第二个加载第二个因子,第三个变量加载因子之和,第四个变量加载因子之差.

现在创建您的观察:

>> observations = factors * loadings' + 0.1 * randn(100,4);
Run Code Online (Sandbox Code Playgroud)

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

>> [coeff, score, latent, tsquared, explained, mu] = pca(observations);
Run Code Online (Sandbox Code Playgroud)

变量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
Run Code Online (Sandbox Code Playgroud)

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

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

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

>> explained
explained =
   58.0639
   41.6302
    0.1693
    0.1366
Run Code Online (Sandbox Code Playgroud)

条目告诉您每个主要组件解释的方差百分比.我们可以清楚地看到前两个组件比后两个组件更重要(它们解释了它们之间99%以上的差异).使用前两个组件重建观察值得出秩-2近似值,

>> approximationRank2 = score(:,1:2) * coeff(:,1:2)' + repmat(mu, 100, 1);
Run Code Online (Sandbox Code Playgroud)

我们现在可以尝试绘图:

>> 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
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我们得到了原始观测的几乎完美的再现.如果我们想要更粗略的近似,我们可以使用第一个主成分:

>> approximationRank1 = score(:,1) * coeff(:,1)' + repmat(mu, 100, 1);
Run Code Online (Sandbox Code Playgroud)

并绘制它,

>> 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
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这次重建不太好.那是因为我们故意构建我们的数据有两个因素,我们只是从其中一个重构它.

请注意,尽管我们构建原始数据的方式与其再现之间存在暗示的相似性,

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

未必存在之间的任何通信factorsscore之间,或loadingscoeff.PCA算法对数据的构造方式一无所知 - 它只是试图解释尽可能多的每个连续组件的总方差.


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

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

现在,所有的观察结果都是一个重要的共同因素,其他因素的重要性正在下降.我们可以像以前一样得到PCA分解

>> [coeff, score, latent, tsquared, explained, mu] = pca(observations);
Run Code Online (Sandbox Code Playgroud)

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

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

在此输入图像描述


小智 6

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

做PCA的例子:

Reduced = compute_mapping(Features, 'PCA', NumberOfDimension);
Run Code Online (Sandbox Code Playgroud)