使用PCA选择特征

5

我正在进行无监督分类。为此,每个图像的分类都有8个特征(绿色方差、绿色标准偏差、红色平均值、红色方差、红色标准偏差、色相平均值、色相方差、色相标准偏差),我希望使用PCA选择3个最重要的特征。以下是我编写的特征选择代码(特征维度为:179X8):

for c=1:size(feature,1)
   feature(c,:)=feature(c,:)-mean(feature)
end

DataCov=cov(feature); % covariance matrix
[PC,variance,explained] = pcacov(DataCov)

这是给我的信息:
PC =
0.0038   -0.0114    0.0517    0.0593    0.0039    0.3998    0.9085   -0.0922
0.0755   -0.1275    0.6339    0.6824   -0.3241   -0.0377   -0.0641    0.0052
0.7008    0.7113   -0.0040    0.0496   -0.0207    0.0042    0.0012    0.0002
0.0007   -0.0012    0.0051    0.0101    0.0272    0.0288    0.0873    0.9953
0.0320   -0.0236    0.1521    0.2947    0.9416   -0.0142   -0.0289   -0.0266
0.7065   -0.6907   -0.1282   -0.0851    0.0060    0.0003    0.0010   -0.0001
0.0026   -0.0037    0.0632   -0.0446    0.0053    0.9125   -0.4015    0.0088
0.0543   -0.0006    0.7429   -0.6574    0.0838   -0.0705    0.0311   -0.0001

方差 =

0.0179
0.0008
0.0001
0.0000
0.0000
0.0000
0.0000
0.0000

解释 =

94.9471
4.1346
0.6616
0.2358
0.0204
0.0003
0.0002
0.0000

这意味着第一个主成分解释了94.9%的方差,以此类推...但这些按照最显著到最不显著的顺序排列。基于以上信息,我该如何知道应选择哪些特征(从1到8)?

1
你可以把feature变量的内容复制到一个网站上,例如http://codepaste.net/,然后分享链接吗? - petrichor
3个回答

6
你的问题与Mahoney和Drineas在"CUR matrix decompositions for improved data analysis"中讨论的COLUMNSELECT问题相同。他们首先计算每个维度的杠杆得分,然后使用杠杆得分作为权重随机选择其中的3个。或者你可以选择最大的那些。以下是适用于你的问题的脚本:
我首先从网络上获取了一个真实的自然图像,并将其调整为你要求的尺寸。该图像如下:

img

%# Example data from real image of size 179x8
%# You can skip it for your own data
features = im2double(rgb2gray(imread('img.png')));

%# m samples, n dimensions
[m,n] = size(features);

然后,计算集中式数据:

%# Remove the mean
features = features - repmat(mean(features,2), 1, size(features,2));

我使用SVD来计算PCA,因为它可以同时给出主成分和系数。如果样本在列中,则U保存主成分。请参考this paper的第二页了解相关关系。
%# Compute the SVD
[U,S,V] = svd(features);

这里的关键思想是我们希望获取具有大部分变化的维度。假设数据中存在一些噪声。我们仅选择主要的特征向量,例如代表95%的数据的特征向量。
%# Compute the number of eigenvectors representing
%#  the 95% of the variation
coverage = cumsum(diag(S));
coverage = coverage ./ max(coverage);
[~, nEig] = max(coverage > 0.95);

然后使用主成分的nEig个计算杠杆得分。也就是说,我们取nEig个系数的范数。

%# Compute the norms of each vector in the new space
norms = zeros(n,1);
for i = 1:n
    norms(i) = norm(V(i,1:nEig))^2;
end

然后,我们可以对杠杆得分进行排序:
%# Get the largest 3
[~, idx] = sort(norms);
idx(1:3)'

并获取具有最大杠杆得分的向量的索引:
ans =
   6     8     5

你可以查看论文以获取更多细节。
但请记住,如果你有很多维度,基于PCA的技术是很好的选择。在你的情况下,搜索空间非常小。我的建议是在空间中进行彻底的搜索,并像@amit建议的那样选择最佳方案。

1
@ petrichor。我从图像的某个感兴趣区域提取了特征,例如,我有一张包含不同血管的图像,并且在每个血管上,我提取了血管中心线像素上的特征。正如您上面所描述的那样,您的特征矩阵是一个图像,而不是来自某个感兴趣区域的特征。我想知道您的方法是否仍适用于我的情况。 - Dev
2
@Dev 我的例子只是一个玩具般的无意义示例,展示了如何在MATLAB中实现它。但在你的情况下,它确实是有意义的。 - petrichor

3
PCA实际上生成一组新的特征,每个特征都是从原始元素进行线性变换得到的。 因此,你得到的向量不能直接转换为你需要选择的特征,以便获得这个方差-它只是基于原始特征创建一个新的特征。 在你的情况下,你得到:
New_Feature = 0.038*F1 + 0.0755*F2 + 0.7008*F3 + ... + 0.0543*F8

New_Feature能够提供94.9471%的信息增益,即使在减少维度的情况下仍然如此。
(如果你对接下来的主要组件也使用同样的方法并将它们作为新特性,显然会增加你的信息增益。)
如果你需要获得原始数据的子集而不是创建新的特征,我会使用PCA之外的其他方法。
对于子集选择,遗传算法通常非常有效,如果您的特征集仅包含8个特征,则还可以考虑暴力搜索 - 只有2 8 = 256种可能的子集, 在某些情况下尝试所有子集并查看哪个能给你最好的表现是可能的。

@Amit。谢谢您的回复。我正在使用无监督分类,即我没有训练数据集。据我所知,我不能使用遗传算法(GA),因为它需要训练数据集。如果我错了,请纠正我。我的意思是,我可以在无监督分类中使用GA吗? - Dev
1
@Dev:你是指聚类吗?如果是的话,也许你可以使用所有特征来找到聚类,并将其与基本事实进行比较,然后使用GA或其他子集选择算法来找到一个足够接近的子集。或者,你可以坚持使用PCA - 但要注意,你得到的是“新特征”,而不是原始特征的子集。 - amit

1

来自pcacov文档

COEFF是一个p乘p的矩阵,每列包含一个主成分的系数。这些列按降序排列。

由于explained表明只有第一个成分对解释方差做出了重要贡献,您应该查看PC的第一列,以查看它使用了哪些原始特征:

0.0038
0.0755
0.7008 <---
0.0007 
0.0320 
0.7065 <---
0.0026 
0.0543 

原来在你的例子中,第三个和第六个特征(用 <-- 表示)是第一主成分的主要贡献者。可以说这些特征是最重要的。
同样地,基于第一、第四和第七个特征只在 PC 的某些最后列中获得大权重的事实,可以得出它们相对不重要的结论。
然而,对于这种逐个特征的分析,PCA 可能不是最合适的选择;你同样可以从原始特征的标准差中得出这样的信息。

谢谢您的回答,但是能否详细解释一下最后一句话。我不明白如何从标准差中提取特征... 预先感谢您。 - Dev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接