使用 PCA 在 Matlab 中降维
Dimensions Reduction in Matlab using PCA
我有一个包含 35 列的矩阵,我正在尝试使用 PCA 降维。我的数据 运行 PCA:
[coeff,score,latent,tsquared,explained,mu] = pca(data);
explained =
99.9955
0.0022
0.0007
0.0003
0.0002
0.0001
0.0001
0.0001
然后,通过查看向量 explained
,我注意到第一个元素的值为 99。基于此,我决定只取第一个组件。所以我做了以下操作:
k=1;
X = bsxfun(@minus, data, mean(data)) * coeff(:, 1:k);
现在,我使用 X
进行 SVM 训练:
svmStruct = fitcsvm(X,Y,'Standardize',true, 'Prior','uniform','KernelFunction','linear','KernelScale','auto','Verbose',0,'IterationLimit', 1000000);
但是,当我尝试预测和计算 miss-classification 比率时:
[label,score,cost] = predict(svmStruct, X);
结果令人失望。我注意到,当我select只有一个组件(k=1
)时,我所有的分类都是错误的。但是,随着我增加包含的组件数量 k
,结果会有所改善,如下图所示。但是根据explained
,这没有意义,这表明我应该只使用第一个特征向量。
我是不是做错了什么?
此图显示了分类错误与包含的 eginvectors 数量的函数关系:
此图是按照@zelanix 的建议在进行 PCA 之前进行归一化后生成的:
这也是绘制的图表:
和这个解释在PCA之前进行归一化后获得的值:
>> [coeff,score,latent,tsquared,explained,mu] = pca(data_normalised);
Warning: Columns of X are linearly dependent to within machine precision.
Using only the first 27 components to compute TSQUARED.
> In pca>localTSquared (line 501)
In pca (line 347)
>> explained
explained =
32.9344
15.6790
5.3093
4.7919
4.0905
3.8655
3.0015
2.7216
2.6300
2.5098
2.4275
2.3078
2.2077
2.1726
2.0892
2.0425
2.0273
1.9135
1.8809
1.7055
0.8856
0.3390
0.2204
0.1061
0.0989
0.0334
0.0085
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
PCA给出了数据中方差最大的方向,不一定非得做更好的分类。如果您想在尝试最大限度地提高准确性的同时减少数据,您应该做 LDA
.
下图正是我想表达的意思。
完全正确,没有理由期望 PCA 会自动改善您的分类结果。它是一种无监督方法,因此不是为了提高可分离性,只是为了找到具有最大方差的组件。
但是您的代码还有其他一些问题。特别是,这一行让我感到困惑:
X = bsxfun(@minus, data, mean(data)) * coeff(:, 1:k);
您需要在 执行 PCA 之前 规范化您的数据,并且每个特征都需要单独规范化。我使用以下内容:
data_normalised = data;
for f = 1:size(data, 2)
data_normalised(:, f) = data_normalised(:, f) - nanmean(data_normalised(:, f));
data_normalised(:, f) = data_normalised(:, f) / nanstd(data_normalised(:, f));
end
pca_coeff = pca(data_normalised);
data_pca = data_normalised * pca_coeff;
然后您可以将第一个主成分提取为 data_pca(:, 1)
。
此外,请始终绘制 PCA 结果以了解实际情况:
figure
scatter(data_pca(Y == 1, 1), data_pca(Y == 1, 2))
hold on;
scatter(data_pca(Y == 2, 1), data_pca(Y == 2, 2))
我有一个包含 35 列的矩阵,我正在尝试使用 PCA 降维。我的数据 运行 PCA:
[coeff,score,latent,tsquared,explained,mu] = pca(data);
explained =
99.9955
0.0022
0.0007
0.0003
0.0002
0.0001
0.0001
0.0001
然后,通过查看向量 explained
,我注意到第一个元素的值为 99。基于此,我决定只取第一个组件。所以我做了以下操作:
k=1;
X = bsxfun(@minus, data, mean(data)) * coeff(:, 1:k);
现在,我使用 X
进行 SVM 训练:
svmStruct = fitcsvm(X,Y,'Standardize',true, 'Prior','uniform','KernelFunction','linear','KernelScale','auto','Verbose',0,'IterationLimit', 1000000);
但是,当我尝试预测和计算 miss-classification 比率时:
[label,score,cost] = predict(svmStruct, X);
结果令人失望。我注意到,当我select只有一个组件(k=1
)时,我所有的分类都是错误的。但是,随着我增加包含的组件数量 k
,结果会有所改善,如下图所示。但是根据explained
,这没有意义,这表明我应该只使用第一个特征向量。
我是不是做错了什么?
此图显示了分类错误与包含的 eginvectors 数量的函数关系:
此图是按照@zelanix 的建议在进行 PCA 之前进行归一化后生成的:
这也是绘制的图表:
和这个解释在PCA之前进行归一化后获得的值:
>> [coeff,score,latent,tsquared,explained,mu] = pca(data_normalised);
Warning: Columns of X are linearly dependent to within machine precision.
Using only the first 27 components to compute TSQUARED.
> In pca>localTSquared (line 501)
In pca (line 347)
>> explained
explained =
32.9344
15.6790
5.3093
4.7919
4.0905
3.8655
3.0015
2.7216
2.6300
2.5098
2.4275
2.3078
2.2077
2.1726
2.0892
2.0425
2.0273
1.9135
1.8809
1.7055
0.8856
0.3390
0.2204
0.1061
0.0989
0.0334
0.0085
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
PCA给出了数据中方差最大的方向,不一定非得做更好的分类。如果您想在尝试最大限度地提高准确性的同时减少数据,您应该做 LDA
.
下图正是我想表达的意思。
但是您的代码还有其他一些问题。特别是,这一行让我感到困惑:
X = bsxfun(@minus, data, mean(data)) * coeff(:, 1:k);
您需要在 执行 PCA 之前 规范化您的数据,并且每个特征都需要单独规范化。我使用以下内容:
data_normalised = data;
for f = 1:size(data, 2)
data_normalised(:, f) = data_normalised(:, f) - nanmean(data_normalised(:, f));
data_normalised(:, f) = data_normalised(:, f) / nanstd(data_normalised(:, f));
end
pca_coeff = pca(data_normalised);
data_pca = data_normalised * pca_coeff;
然后您可以将第一个主成分提取为 data_pca(:, 1)
。
此外,请始终绘制 PCA 结果以了解实际情况:
figure
scatter(data_pca(Y == 1, 1), data_pca(Y == 1, 2))
hold on;
scatter(data_pca(Y == 2, 1), data_pca(Y == 2, 2))