随机森林与失衡

时间:2018-12-20 12:29:23

标签: python scikit-learn classification random-forest

我正在处理约20000行的数据集。 目的是预测某人是否已被公司雇用,并提供一些诸如性别,经验,申请日期,考试分数,工作技能等功能。数据集不平衡:类别为“ 1”或“ 0” '(已雇用/未雇用),比例为1:10。

我选择训练随机森林分类器来解决这个问题。 我将数据集的70%-30%随机分为训练集和测试集。

仔细阅读了解决不平衡问题的各种选项后(例如Dealing with the class imbalance in binary classificationUnbalanced classification using RandomForestClassifier in sklearn),我坚持在测试集上获得高分。

我尝试了几件事:

    我在整个X_train上训练了三个不同的随机森林,分别在欠采样训练X_und和过采样X_sm上进行了训练。 X_und是通过简单地随机削减用0标记的X_train的行以得到50-50、66-33或75-25的0s和1s比率来生成的; X_sm由SMOTE生成。

我使用scikit-learn GridSearchCV调整了三个模型以获得最佳参数:

param_grid = {'min_samples_leaf':[3,5,7,10,15],'max_features':[0.5,'sqrt','log2'],
          'max_depth':[10,15,20],
          'class_weight':[{0:1,1:1},{0:1,1:2},{0:1,1:5},'balanced'],
          'criterion':['entropy','gini']}

sss = StratifiedShuffleSplit(n_splits=5)
grid = GridSearchCV(RandomForestClassifier(),param_grid,cv=sss,verbose=1,n_jobs=-1,scoring='roc_auc')
grid.fit(X_train,y_train)

最佳分数来自

rfc = RandomForestClassifier(n_estimators=150, criterion='gini', min_samples_leaf=3, 
max_features=0.5, n_jobs=-1, oob_score=True, class_weight={0:1,1:5})

对整个X_train进行了训练,并给出了测试集的分类报告

          precision    recall  f1-score   support

       0     0.9397    0.9759    0.9575      5189
       1     0.7329    0.5135    0.6039       668

micro avg     0.9232    0.9232    0.9232      5857
macro avg     0.8363    0.7447    0.7807      5857
weighted avg     0.9161    0.9232    0.9171      5857

通过采样方法,我得到了相似的结果,但没有更好的结果。欠采样导致精度下降,而过采样则得到几乎相同的结果。

对于欠采样:

    precision    recall  f1-score   support

 0     0.9532    0.9310    0.9420      5189
 1     0.5463    0.6452    0.5916       668

对于SMOTE:

    precision    recall  f1-score   support

 0     0.9351    0.9794    0.9567     5189
 1     0.7464    0.4716    0.5780      668
  • 我使用参数class_weights来使1的权重更大,并且在拟合过程中也使用了sample_weight
  • 我试图找出除准确度之外还要考虑的得分。运行GridSearchCV来调整森林,我使用了不同的分数,特别关注f1roc_auc,希望减少误报率。我在SMOTE过采样方面得分很高,但是该模型在测试集上的推广效果不佳。我无法理解如何更改随机森林的分割标准或评分,以减少假阴性的数量并增加1的召回率。我看到cohen_kappa_score对于不平衡的数据集也很有用,但不能用于GridSearch等sklearn的交叉验证方法中。
  • 仅选择最重要的功能,但这并没有改变结果,相反,情况变得更糟。我指出,在SMOTE之后通过训练RF获得的功能重要性与正常样本完全不同。
  • 除了将其视为训练森林时获得的免费验证分数之外,我不知道该如何处理oob_score。通过过采样,我得到了最高的oob_score = 0.9535,但这是很自然的,因为在这种情况下训练集是平衡的,问题仍然在于它不能很好地推广到测试集。

现在我的想法已经用光了,所以我想知道我是缺少什么还是做错了什么。还是我应该尝试其他模型而不是随机森林?

0 个答案:

没有答案