PCA降维分类
PCA Dimension reducion for classification
我正在对从 CNN 的不同层提取的特征使用主成分分析。我已经从here.
下载了降维工具箱
我总共有11232张训练图像,每张图像的特征是6532。所以特征矩阵是这样的11232x6532
如果我想要前 90% 的特征,我可以很容易地做到这一点,使用减少数据的 SVM 的训练准确度是 81.73%,这是公平的。
但是,当我尝试包含 2408 张图像的测试数据时,每张图像的特征是 6532。所以测试数据的特征矩阵是 2408x6532
。在那种情况下,前 90% 特征的输出不正确,它显示 2408x2408
。
测试准确率为25%。
在不使用降维的情况下,训练准确率为 82.17%,测试准确率为 79%。
更新:
其中 X
是数据,no_dims
是输出时所需的维数。
此 PCA 函数的输出是变量 mappedX
和结构 mapping
.
% Make sure data is zero mean
mapping.mean = mean(X, 1);
X = bsxfun(@minus, X, mapping.mean);
% Compute covariance matrix
if size(X, 2) < size(X, 1)
C = cov(X);
else
C = (1 / size(X, 1)) * (X * X'); % if N>D, we better use this matrix for the eigendecomposition
end
% Perform eigendecomposition of C
C(isnan(C)) = 0;
C(isinf(C)) = 0;
[M, lambda] = eig(C);
% Sort eigenvectors in descending order
[lambda, ind] = sort(diag(lambda), 'descend');
if no_dims < 1
no_dims = find(cumsum(lambda ./ sum(lambda)) >= no_dims, 1, 'first');
disp(['Embedding into ' num2str(no_dims) ' dimensions.']);
end
if no_dims > size(M, 2)
no_dims = size(M, 2);
warning(['Target dimensionality reduced to ' num2str(no_dims) '.']);
end
M = M(:,ind(1:no_dims));
lambda = lambda(1:no_dims);
% Apply mapping on the data
if ~(size(X, 2) < size(X, 1))
M = bsxfun(@times, X' * M, (1 ./ sqrt(size(X, 1) .* lambda))'); % normalize in order to get eigenvectors of covariance matrix
end
mappedX = X * M;
% Store information for out-of-sample extension
mapping.M = M;
mapping.lambda = lambda;
根据您的建议。我已经计算了训练数据的向量。
numberOfDimensions = round(0.9*size(Feature,2));
[mapped_data, mapping] = compute_mapping(Feature, 'PCA', numberOfDimensions);
然后使用相同的向量测试数据:
mappedX_test = Feature_test * mapping.M;
仍然准确率为 32%
通过做减法解决:
Y = bsxfun(@minus, Feature_test, mapping.mean);
mappedX_test = Y * mapping.M;
您似乎正在分别对训练数据和测试数据进行降维。在训练期间,您应该记住训练期间示例的主要分数或基向量。请记住,您正在根据训练数据使用一组新的正交轴找到数据的新表示。在测试过程中,您重复与训练数据完全相同的过程,因为您正在表示关于这些基本向量的数据。因此,您使用 训练数据 的基向量来减少数据。您只得到一个 2408 x 2408
矩阵,因为您正在对测试示例执行 PCA,因为不可能生成超出相关矩阵等级(即 2408)的基向量。
保留训练阶段的基向量,当需要在测试阶段执行分类时,必须使用训练阶段的相同基向量。请记住,在 PCA 中,您必须在降维之前通过执行均值减法来使数据居中。为此,在您的代码中,我们注意到基向量存储在 mapping.M
中,相关的均值向量存储在 mapping.mean
中。当谈到测试阶段时,请确保您的意思是从训练阶段减去带有 mapping.mean
的测试数据:
Y = bsxfun(@minus, Feature_test, mapping.mean);
一旦你有了这个,最后继续并降维你的数据:
mappedX_test = Y * mapping.M;
我正在对从 CNN 的不同层提取的特征使用主成分分析。我已经从here.
下载了降维工具箱我总共有11232张训练图像,每张图像的特征是6532。所以特征矩阵是这样的11232x6532
如果我想要前 90% 的特征,我可以很容易地做到这一点,使用减少数据的 SVM 的训练准确度是 81.73%,这是公平的。
但是,当我尝试包含 2408 张图像的测试数据时,每张图像的特征是 6532。所以测试数据的特征矩阵是 2408x6532
。在那种情况下,前 90% 特征的输出不正确,它显示 2408x2408
。
测试准确率为25%。
在不使用降维的情况下,训练准确率为 82.17%,测试准确率为 79%。
更新:
其中 X
是数据,no_dims
是输出时所需的维数。
此 PCA 函数的输出是变量 mappedX
和结构 mapping
.
% Make sure data is zero mean
mapping.mean = mean(X, 1);
X = bsxfun(@minus, X, mapping.mean);
% Compute covariance matrix
if size(X, 2) < size(X, 1)
C = cov(X);
else
C = (1 / size(X, 1)) * (X * X'); % if N>D, we better use this matrix for the eigendecomposition
end
% Perform eigendecomposition of C
C(isnan(C)) = 0;
C(isinf(C)) = 0;
[M, lambda] = eig(C);
% Sort eigenvectors in descending order
[lambda, ind] = sort(diag(lambda), 'descend');
if no_dims < 1
no_dims = find(cumsum(lambda ./ sum(lambda)) >= no_dims, 1, 'first');
disp(['Embedding into ' num2str(no_dims) ' dimensions.']);
end
if no_dims > size(M, 2)
no_dims = size(M, 2);
warning(['Target dimensionality reduced to ' num2str(no_dims) '.']);
end
M = M(:,ind(1:no_dims));
lambda = lambda(1:no_dims);
% Apply mapping on the data
if ~(size(X, 2) < size(X, 1))
M = bsxfun(@times, X' * M, (1 ./ sqrt(size(X, 1) .* lambda))'); % normalize in order to get eigenvectors of covariance matrix
end
mappedX = X * M;
% Store information for out-of-sample extension
mapping.M = M;
mapping.lambda = lambda;
根据您的建议。我已经计算了训练数据的向量。
numberOfDimensions = round(0.9*size(Feature,2));
[mapped_data, mapping] = compute_mapping(Feature, 'PCA', numberOfDimensions);
然后使用相同的向量测试数据:
mappedX_test = Feature_test * mapping.M;
仍然准确率为 32%
通过做减法解决:
Y = bsxfun(@minus, Feature_test, mapping.mean);
mappedX_test = Y * mapping.M;
您似乎正在分别对训练数据和测试数据进行降维。在训练期间,您应该记住训练期间示例的主要分数或基向量。请记住,您正在根据训练数据使用一组新的正交轴找到数据的新表示。在测试过程中,您重复与训练数据完全相同的过程,因为您正在表示关于这些基本向量的数据。因此,您使用 训练数据 的基向量来减少数据。您只得到一个 2408 x 2408
矩阵,因为您正在对测试示例执行 PCA,因为不可能生成超出相关矩阵等级(即 2408)的基向量。
保留训练阶段的基向量,当需要在测试阶段执行分类时,必须使用训练阶段的相同基向量。请记住,在 PCA 中,您必须在降维之前通过执行均值减法来使数据居中。为此,在您的代码中,我们注意到基向量存储在 mapping.M
中,相关的均值向量存储在 mapping.mean
中。当谈到测试阶段时,请确保您的意思是从训练阶段减去带有 mapping.mean
的测试数据:
Y = bsxfun(@minus, Feature_test, mapping.mean);
一旦你有了这个,最后继续并降维你的数据:
mappedX_test = Y * mapping.M;