簡単なチュートリアルを次に示します。まず、隠し変数 (または「因子」) のマトリックスを作成します。100 個の観測値があり、2 つの独立した要因があります。
>> factors = randn(100, 2);
ローディングマトリックスを作成します。これにより、隠し変数が観測変数にマッピングされます。観測された変数に 4 つの特徴があるとします。次に、ローディングマトリックスが必要です4 x 2
>> loadings = [
1 0
0 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
元の観測をほぼ完全に再現しています。より粗い近似が必要な場合は、最初の主成分のみを使用できます。
>> 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
今回の再構築はあまり良くありません。これは、意図的に 2 つの要素を持つようにデータを構築し、そのうちの 1 つから再構築しているだけだからです。
元のデータを作成した方法とその複製との間に示唆的な類似性があるにもかかわらず、
>> observations = factors * loadings' + 0.1 * randn(100,4);
>> reconstructed = score * coeff' + repmat(mu, 100, 1);
と の間、またはfactors
との間に必ずしも対応があるとは限りません。PCA アルゴリズムは、データの構成方法については何も知りません。連続する各コンポーネントでできる限り多くの分散を説明しようとするだけです。score
loadings
coeff
ユーザー @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')