Scikit-learn RandomForestClassifier() 特征选择,只选择训练集?

Posted

技术标签:

【中文标题】Scikit-learn RandomForestClassifier() 特征选择,只选择训练集?【英文标题】:Scikit-learn RandomForestClassifier() feature selection, just select the train set? 【发布时间】:2015-08-10 22:48:51 【问题描述】:

我正在使用 scikit-learn 进行机器学习。

我有 800 个具有 2048 个特征的样本,因此我想减少我的特征以获得更好的准确性。

这是一个多类问题(0-5类),特征由10组成:[1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0....,0]

我使用的是集成方法,RandomForestClassifier()

我是否应该只选择训练数据

如果我使用这段代码就够了吗

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size = .3 )

clf = RandomForestClassifier( n_estimators = 200,
                              warm_start   = True,
                              criterion    = 'gini',
                              max_depth    = 13
                              )

clf.fit( X_train, y_train ).transform( X_train )

predicted       = clf.predict( X_test )
expected        = y_test
confusionMatrix = metrics.confusion_matrix( expected, predicted )

因为准确率没有提高。代码中一切正常还是我做错了什么?

非常感谢您的帮助。

【问题讨论】:

您介意吗,Herb,同时发布您从 sklearn.__version__ 获得的值,以及从 clf.set_params( oob_score = True ).fit( ... ).oob_score_ 获得的 ( X_train, y_train ) 的值。 ( X, y ) ?谢谢。 也可以检查 >>> ***.com/a/30471026/3666197 -- 即 Breiman (Berkeley) 的关于 bootstrap-aggregation 方法的论文,通过设计避免过拟合工件 b> 以及在.fit( X_test, y_test ).oob_score_ lim-> .fit( X, y ).oob_score_ 和其他重要事物上经过验证的极限定理,这些都是特定于基于 RF 的集成方法的。解决 2048D-binary-0|1-space 内部问题的目标本身不受“维度”的影响。深入了解 RF 的优势(可能max_depth 有限,但“森林宽度”增加(多样性))会有所帮助。 【参考方案1】:

我不确定我是否正确理解了你的问题,所以我会回答我认为我理解的内容 =)

首先,减少特征的维度(例如从 2048 到 500)可能不会为您提供更好的结果。这完全取决于模型捕捉数据几何形状的能力。例如,如果您通过非线性方法减少尺寸,可以捕获特定几何图形并将其“线性化”,而不是直接在原始数据上使用此线性模型,您可以获得更好的结果,例如使用线性模型。但这是因为您的数据本质上是非线性的,并且线性模型不好,因此在原始空间中无法捕捉到这种几何图形(想想 2D 中的圆)。

在您提供的代码中,您并没有降低维度,而是将数据拆分为两个数据集(特征维度相同,2048,只是样本数发生了变化)。大多数时候在较小的数据集上进行训练会导致最差的准确性(数据=信息,当您遗漏一些信息时,您会丢失信息)。但是拆分数据可以让你特别测试过拟合,这是非常重要的。但是,一旦选择了最佳参数(请参阅交叉验证),您就应该了解您拥有的所有数据!

鉴于您的 0.7*800=560 个样本,我认为 13 的深度相当大,您可能会过拟合。如果您想提高准确性,您可能需要先使用此参数!

【讨论】:

【参考方案2】:

1) 通常减少特征空间无助于提高准确性,而使用正则化分类器会带来更好的结果。 2)要进行特征选择,您需要两种方法:一种是减少特征集,另一种是执行实际的监督任务(此处为分类)。

您是否尝试过仅使用标准分类器?显然您尝试了 RF,但我也会尝试线性方法,如 LinearSVC/LogisticRegression 或内核 SVC。

如果你想做特征选择,你需要做的是这样的:

feature_selector = LinearSVC(penalty='l1') #或者可能从 SelectKBest() 开始 特征选择器.train(X_train, y_train)

X_train_reduced = feature_selector.transform(X_train) X_test_reduced = feature_selector.transform(X_test)

分类器 = RandomForestClassifier().fit(X_train_reduced, y_train)

预测 = 分类器.predict(X_test_reduced)

或者您使用管道,如下所示:http://scikit-learn.org/dev/auto_examples/feature_selection/feature_selection_pipeline.html 也许我们应该在示例中添加一个没有管道的版本?

[从最初提出此问题的邮件列表中交叉发布]

【讨论】:

【参考方案3】:

如果您的特征多于样本,则绝对建议降维或选择特征。您可以查看Principal Component Analysis 和sklearn.decomposition 中的其他模块以减少功能数量。在 scikit-learn 文档中还有一个关于 Feature Selection 的有用部分。

在拟合 sklearn.decomposition.PCA 后,您可以检查 explained_variance_ratio_ 以确定可减少的特征数量 (n_components)原始特征空间的差异)。有些人可能希望保留累积 explained_variance_ratio_ 高于 0.9、0.95 等的特征,有些人喜欢删除超过 explained_variance_ratio_ 突然下降的特征。然后用你喜欢的n_componentstransform 你的X_trainX_test 改装PCA,并像上面一样装配你的分类器。

【讨论】:

以上是关于Scikit-learn RandomForestClassifier() 特征选择,只选择训练集?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 python 输出 RandomForest 分类器?

scikit-learn随机森林调参小结

转载:scikit-learn随机森林调参小结

使用 scikit-learn 并行生成随机森林

如何在 scikit-learn 的随机森林的 graphviz-graph 中找到一个类?

在 Python Scikit-Learn 中训练测试拆分得分高但 CV 得分低