我正在尝试使用Weka来使用PCA算法进行特征选择。
我的原始特征空间包含~9000个属性,在2700个样本中。 我尝试使用以下代码减少数据的维数:
AttributeSelection selector = new AttributeSelection();
PrincipalComponents pca = new PrincipalComponents();
Ranker ranker = new Ranker();
selector.setEvaluator(pca);
selector.setSearch(ranker);
Instances instances = SamplesManager.asWekaInstances(trainSet);
try {
selector.SelectAttributes(instances);
return SamplesManager.asSamplesList(selector.reduceDimensionality(instances));
} catch (Exception e ) {
...
}
然而,它没有在12小时内完成。它停留在selector.SelectAttributes(instances);
方法中。
我的问题是: weka的PCA需要这么长的计算时间吗?或者我错误地使用PCA?
如果预计会有长时间运行:
如何调整PCA算法以更快地运行多?你能建议一个替代方案吗? (+示例代码如何使用它)?
如果不是:
我做错了什么?我应该如何使用weka调用PCA并降低维数?
更新:这些评论证实了我的怀疑,它花费的时间远远超出预期。
我想知道:我怎样才能在java中获得PCA - 使用weka或替代库。
为此添加了赏金。
答案 0 :(得分:10)
在加深WEKA代码后,瓶颈正在创建协方差矩阵,然后计算该矩阵的特征向量。即使尝试切换到sparsed矩阵实现(我使用COLT的SparseDoubleMatrix2D)也无济于事。
我提出的解决方案是首先使用第一种快速方法(我使用信息增益排名器,基于文档频率进行过滤)来降低维度,然后在降低的维度上使用PCA来进一步减少维度。
代码更复杂,但它基本上归结为:
Ranker ranker = new Ranker();
InfoGainAttributeEval ig = new InfoGainAttributeEval();
Instances instances = SamplesManager.asWekaInstances(trainSet);
ig.buildEvaluator(instances);
firstAttributes = ranker.search(ig,instances);
candidates = Arrays.copyOfRange(firstAttributes, 0, FIRST_SIZE_REDUCTION);
instances = reduceDimenstions(instances, candidates)
PrincipalComponents pca = new PrincipalComponents();
pca.setVarianceCovered(var);
ranker = new Ranker();
ranker.setNumToSelect(numFeatures);
selection = new AttributeSelection();
selection.setEvaluator(pca);
selection.setSearch(ranker);
selection.SelectAttributes(instances );
instances = selection.reduceDimensionality(wekaInstances);
然而,当我对估计的准确度进行交叉验证时,这种方法得分更差,然后使用贪婪的信息增益和排名。
答案 1 :(得分:3)
看起来你正在使用PCA的默认配置,从长时间运行时来看,很可能它为你的目的做了太多的工作。
查看PrincipalComponents的选项。
-D
是否意味着他们会为你规范化,或者你必须自己做。您希望您的数据被标准化(以均值为中心),所以我先自己手动执行此操作。-R
设置您想要计算的差异金额。默认值为0.95
。您的数据中的相关性可能不太好,因此请尝试将其设置为0.8
。-A
设置要包含的最大属性数。我认为默认是所有这些。再次,您应该尝试将其设置为更低的值。我建议首先使用非常宽松的设置(例如-R=0.1
和-A=2
),然后逐步达到可接受的结果。
答案 2 :(得分:0)