在随机森林中查找重要特征非常缓慢。

3
我有一组与二元类标签相关联的特征向量,每个向量大约有40,000个特征。我使用来自sklearn的RandomForestClassifier训练了一个随机森林分类器,这需要大约10分钟的时间。然而,我想知道哪些是最重要的特征。
我尝试简单地打印clf.feature_importances_,但每个特征需要大约1秒钟,总共需要大约40,000秒(大约12小时)。这比第一次训练分类器所需的时间长得多!
有没有更有效的方法找出哪些特征最重要?
以下是我所说的例子:
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=50)
clf = clf.fit(X, Y)
for i in xrange(len(clf.feature_importances_)):
    print clf.feature_importances_[i]

基于个人经验和那么多的功能,我建议你尝试一下Spark MLlib。 - ahajib
@ahajib 谢谢,但为什么找到重要特征的时间比构建分类器本身要长得多呢?另外,您尝试过xgboost吗?也许它更适合找到重要特征? - Simd
你能发一下你代码的一部分吗?据我所知,feature_importances_返回一个大小为n的数组,其中n是你特征数量,每个值表示特征的重要性。我不确定你所指的每个特征需要1秒钟是什么意思。 - ahajib
@ahajib 添加了一个示例。每个新功能需要大约1秒钟才能打印出来。也许它每次都在重新计算整个数组? - Simd
是的,那就是问题所在。在发布答案之前没有看到这个。顺便说一下,我建议你将结果写入文件而不是打印出来,因为通常打印会有自己的延迟。 - ahajib
2个回答

1

你需要做的就是将 clf.feature_importances_ 的结果存储在一个数组中,然后使用该数组来打印结果。例如:

from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=50)
clf = clf.fit(X, Y)

featureImportance = clf.feature_importances_
for i in xrange(len(featureImportance)):
    print featureImportance[i]

你现在处理的方式是每次都重新计算数组。

谢谢。这在事后看来有些显而易见。 - Simd
1
当然。这就是为什么我要求您发布您的代码。有时候我们会忽略掉显而易见的问题。祝你好运。 - ahajib

1
我建议做出小的变化,可以自动解决问题,因为它只获取了feature_importances_
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=50)
clf = clf.fit(X, Y)
for feature_importance in clf.feature_importances_:
    print feature_importance

如果您需要在循环中的其他位置使用循环索引i,只需使用enumerate:
for i, feature_importance in enumerate(clf.feature_importances_):
    print feature_importance

这也是比使用

更符合 Python 风格的方式。
for i in xrange(len(<some-array>)): 
    <some-array>[i]

我认为如果一些类似于RandomForestClassifier的分类器能够在后台跟踪其状态会更好。如果状态发生变化(例如更改n_estimators或其他参数),它应该重新计算feature_importances_(像现在一样实时计算)。否则,它应该只返回当前缓存的特征重要性。
然而,在幕后这更加复杂。
也许最简单的方法是将属性更改为实际方法:calc_feature_importances()
再说一遍,我没有付出努力创建RandomForestClassifier,所以我不能抱怨。

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