我编写了以下Python代码,用于在UCI ML repo的Forest CoverType数据集上运行RandomForestClassifier(使用默认参数设置)。然而,结果非常糟糕,准确度在60%左右,而这种技术应该能够达到90%以上(例如Weka)。我已经尝试过将n_estimators增加到100,但是并没有带来太大的改善。
有什么办法可以让我在scikit-learn中使用这种技术获得更好的结果吗?或者是什么原因导致这种糟糕的表现?
from sklearn.datasets import fetch_covtype
from sklearn.ensemble import RandomForestClassifier
from sklearn import cross_validation
covtype = fetch_covtype()
clf = RandomForestClassifier()
scores = cross_validation.cross_val_score(clf, covtype.data, covtype.target)
print scores
[ 0.5483831 0.58210057 0.61055001]
我设法通过使用GridSearchCV
对您的模型进行了很好的改进
from sklearn.datasets import fetch_covtype
from sklearn.ensemble import RandomForestClassifier
from sklearn import cross_validation
from sklearn import grid_search
import numpy as np
covtype = fetch_covtype()
clf = RandomForestClassifier()
X_train, X_test, y_train, y_test = cross_validation.train_test_split(covtype.data,
covtype.target,
test_size=0.33,
random_state=42)
params = {'n_estimators':[30, 50, 100],
'max_features':['sqrt', 'log2', 10]}
gsv = grid_search.GridSearchCV(clf, params, cv=3,
n_jobs=-1, scoring='f1')
gsv.fit(X_train, y_train)
print metrics.classification_report(y_train, gsv.best_estimator_.predict(X_train))
print metrics.classification_report(y_test, gsv.best_estimator_.predict(X_test))
输出:
precision recall f1-score support
1 1.00 1.00 1.00 141862
2 1.00 1.00 1.00 189778
3 1.00 1.00 1.00 24058
4 1.00 1.00 1.00 1872
5 1.00 1.00 1.00 6268
6 1.00 1.00 1.00 11605
7 1.00 1.00 1.00 13835
avg / total 1.00 1.00 1.00 389278
precision recall f1-score support
1 0.97 0.95 0.96 69978
2 0.95 0.97 0.96 93523
3 0.95 0.96 0.95 11696
4 0.92 0.86 0.89 875
5 0.94 0.78 0.86 3225
6 0.94 0.90 0.92 5762
7 0.97 0.95 0.96 6675
avg / total 0.96 0.96 0.96 191734
这与Kaggle排行榜上的分数相差不大(请注意,Kaggle竞争使用更具挑战性的数据分割!)
如果你想看到更多的改进,那么你将不得不考虑不均衡的类别以及如何最好地选择你的训练数据。
注意
为了节省时间,我使用了比通常情况下更少的估计器,但是模型在训练集上表现得很好,所以你可能不必考虑这个。
我使用了少量的max_features
,因为这通常会减少模型训练中的偏差。虽然这并不总是正确的。
我使用f1
评分,因为我不太了解数据集,而f1
往往在分类问题上工作得很好。
你可以尝试以下方法来提高你的分数:-
-
用所有可用的属性训练你的模型。它会过度训练,但它会让你知道你可以在训练集上达到多少准确度。
-
接下来使用clf.feature_importances_
删除最不重要的特性 使用网格搜索CV来调整模型的超参数。使用交叉验证和oob_score(out of bag score)来更好地估计泛化。
使用相同的数据集和相同的估计器,您获得了90%吗?因为数据集被分割成
用于训练数据子集
的前11,340条记录下3780条记录用于验证数据子集
最近用于测试数据子集
的565,892条记录
和文档声明了以下性能,这使得未调谐的随机森林不那么差:
70%神经网络(反向传播)
线性判别分析
对于n_estimators
= 100,您可以增加到500,1.000甚至更多。检查每一个结果,当分数开始稳定时保持数字。
与Scikit-Learn相比,问题可能来自Weka的默认超参数。您可以调优其中的一些来改善您的结果:
-
max_features
表示在每个树节点上分裂的特征数量。 -
max_depth
也许模型过于拟合你的训练数据了 -
min_samples_split
,min_samples_leaf
,min_weight_fraction_leaf
和max_leaf_nodes
处理样品在叶片之间的重新划分-何时保留它们,或者不保留它们。
您也可以尝试通过组合它们或通过降低维度来处理您的特征。
您应该看看kaggle脚本,例如这里,它们描述了如何使用ExtraTreesClassifier
获得78%(然而,训练集包含11.340 + 3780个recors -他们似乎使用了更高数量的n_estimators
,尽管