Я пытаюсь уменьшить размерность с помощью 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 будет хуже.
Вот несколько вопросов:
- Является ли функция
princomp
лучшим способом вычислить первые k главных компонентов с помощью MATLAB? - Использование проектируемых функций PCA по сравнению с необработанными функциями не дает дополнительной точности, а дает только меньший размер векторных функций? (быстрее сравнивать векторы признаков).
- Как автоматически выбрать min k (количество главных компонентов), которые дают такую же точность по сравнению с необработанным вектором признаков?
- Что делать, если у меня очень большой набор образцов, могу ли я использовать только часть из них с сопоставимой точностью? Или я могу вычислить PCA для некоторого набора, а затем «добавить» какой-то другой набор (я не хочу повторно вычислять pca для set1 + set2, но каким-то образом итеративно добавляю информацию из set2 в существующий PCA из set1)?
Я также пробовал версию с графическим процессором, просто используя 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 Недостаточно памяти на устройстве.