MATLAB の を使用して次元削減を試みていますprincomp
が、正しく行っているかどうかはわかりません。
テスト用のコードは次のとおりですが、投影を正しく行っているかどうかはわかりません。
A = rand(4,3)
AMean = mean(A)
[n m] = size(A)
Ac = (A - repmat(AMean,[n 1]))
pc = princomp(A)
k = 2; %Number of first principal components
A_pca = Ac * pc(1:k,:)' %Not sure I'm doing projection right
reconstructedA = A_pca * pc(1:k,:)
error = reconstructedA- Ac
そして、ORL データセットを使用した顔認識のコード:
%load orl_data 400x768 double matrix (400 images 768 features)
%make labels
orl_label = [];
for i = 1:40
orl_label = [orl_label;ones(10,1)*i];
end
n = size(orl_data,1);
k = randperm(n);
s = round(0.25*n); %Take 25% for train
%Raw pixels
%Split on test and train sets
data_tr = orl_data(k(1:s),:);
label_tr = orl_label(k(1:s),:);
data_te = orl_data(k(s+1:end),:);
label_te = orl_label(k(s+1:end),:);
tic
[nn_ind, estimated_label] = EuclDistClassifier(data_tr,label_tr,data_te);
toc
rate = sum(estimated_label == label_te)/size(label_te,1)
%Using PCA
tic
pc = princomp(data_tr);
toc
mean_face = mean(data_tr);
pc_n = 100;
f_pc = pc(1:pc_n,:)';
data_pca_tr = (data_tr - repmat(mean_face, [s,1])) * f_pc;
data_pca_te = (data_te - repmat(mean_face, [n-s,1])) * f_pc;
tic
[nn_ind, estimated_label] = EuclDistClassifier(data_pca_tr,label_tr,data_pca_te);
toc
rate = sum(estimated_label == label_te)/size(label_te,1)
十分な数の主成分を選択すると、同等の認識率が得られます。少数の主成分(PCA) を使用すると、PCA を使用した率は低くなります。
ここにいくつかの質問があります:
- 関数は、MATLAB を使用して最初のk主成分を
princomp
計算する最良の方法ですか? - PCA 投影された機能と生の機能を使用しても、精度は向上しませんが、機能のベクトル サイズが小さくなるだけですか? (特徴ベクトルを比較する方が速い)。
- 生の特徴ベクトルと同じ精度を与える最小k (主成分の数) を自動的に選択する方法は?
- 非常に大きなサンプル セットがある場合、同等の精度でそれらのサブセットのみを使用できますか? または、あるセットで PCA を計算し、後で別のセットを「追加」できますか (set1 + set2 の pca を再計算したくありませんが、set2 の情報を set1 の既存の PCA に繰り返し追加します)。
また、次を使用して単純に GPU バージョンを試しましたgpuArray
。
%Test using GPU
tic
A_cpu = rand(30000,32*24);
A = gpuArray(A_cpu);
AMean = mean(A);
[n m] = size(A)
pc = princomp(A);
k = 100;
A_pca = (A - repmat(AMean,[n 1])) * pc(1:k,:)';
A_pca_cpu = gather(A_pca);
toc
clear;
tic
A = rand(30000,32*24);
AMean = mean(A);
[n m] = size(A)
pc = princomp(A);
k = 100;
A_pca = (A - repmat(AMean,[n 1])) * pc(1:k,:)';
toc
clear;
より高速に動作しますが、大きな行列には適していません。たぶん私は間違っています?
大きな行列を使用すると、次のようになります。
gpuArray の使用エラー デバイスのメモリが不足しています。