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类),特征由1
和0
组成:[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_components
、transform
你的X_train
和X_test
改装PCA
,并像上面一样装配你的分类器。
【讨论】:
以上是关于Scikit-learn RandomForestClassifier() 特征选择,只选择训练集?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 python 输出 RandomForest 分类器?