web-dev-qa-db-ja.com

Matlab-PCA分析と多次元データの再構築

多次元データ(132次元)の大きなデータセットがあります。

私はデータマイニングの初心者で、Matlabを使用して主成分分析を適用したいと考えています。しかし、私はウェブ上で説明されている多くの機能があることを見てきましたが、それらがどのように適用されるべきか理解していません。

基本的に、PCAを適用し、データから固有ベクトルとそれに対応する固有値を取得します。

このステップの後、取得した固有ベクトルの選択に基づいてデータの再構成を実行できるようにしたいと考えています。

これを手動で行うことはできますが、既に最適化されている必要があるため、これを行うことができる定義済みの関数があるかどうか疑問に思っていました。

私の初期データはsize(x) = [33800 132]のようなものです。だから基本的に私は132機能(次元)および33800データポイント。そして、このデータセットに対してPCAを実行したいと思います。

任意のヘルプまたはヒントがあります。

19
Simon

ここに簡単なウォークスルーがあります。最初に、隠し変数(または「ファクター」)のマトリックスを作成します。 100個の観測値があり、2つの独立した要因があります。

>> factors = randn(100, 2);

次に、負荷マトリックスを作成します。これにより、非表示変数が観測変数にマップされます。観測された変数には4つの機能があるとします。次に、負荷行列は4 x 2

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

これは、最初に観測された最初の変数の負荷が第1因子に、2番目の負荷が2番目の因子に、3番目の変数が因子の合計に、4番目の変数が因子の差に負荷することを示しています。

次に、観測を作成します。

>> 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'は、観測の中央バージョンを再現します。平均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

元のデータの近似値を取得するには、計算された主成分から列の削除を開始できます。どの列を削除するかを知るために、explained変数を調べます

>> explained
explained =
   58.0639
   41.6302
    0.1693
    0.1366

エントリは、各主成分によって説明される分散の割合を示します。最初の2つのコンポーネントは、2番目の2つのコンポーネントよりも重要であることが明確にわかります(それらは、それらの間の分散の99%以上を説明します)。最初の2つのコンポーネントを使用して観測値を再構築すると、ランク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

enter image description here

元の観察結果をほぼ完璧に再現できます。より粗い近似が必要な場合は、最初の主成分を使用できます。

>> 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

enter image description here

今回は再構築はあまり良くありません。これは、2つの要素を持つようにデータを意図的に構築し、そのうちの1つからのみ再構築しているためです。

元のデータの作成方法とその再現方法の間に示唆的な類似性があるにもかかわらず、

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

factorsscoreの間、またはloadingscoeffの間には必ずしも対応関係はありません。 PCAアルゴリズムは、データの構築方法については何も知りません-連続する各コンポーネントでできる限りの分散全体を説明しようとするだけです。


ユーザー@Mariは、再構成エラーを主成分の数の関数としてプロットする方法をコメントで尋ねました。これより上の変数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')

enter image description here

48
Chris Taylor

http://homepage.tudelft.nl/19j49/Matlab_Toolbox_for_Dimensionality_Reduction.html に非常に優れた次元削減ツールボックスがあります。PCAの他に、このツールボックスには次元削減のための他の多くのアルゴリズムがあります。

PCAの実行例:

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