我正在处理约20000行的数据集。 目的是预测某人是否已被公司雇用,并提供一些诸如性别,经验,申请日期,考试分数,工作技能等功能。数据集不平衡:类别为“ 1”或“ 0” '(已雇用/未雇用),比例为1:10。
我选择训练随机森林分类器来解决这个问题。 我将数据集的70%-30%随机分为训练集和测试集。
仔细阅读了解决不平衡问题的各种选项后(例如Dealing with the class imbalance in binary classification,Unbalanced classification using RandomForestClassifier in sklearn),我坚持在测试集上获得高分。
我尝试了几件事:
我使用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
来调整森林,我使用了不同的分数,特别关注f1
和roc_auc
,希望减少误报率。我在SMOTE过采样方面得分很高,但是该模型在测试集上的推广效果不佳。我无法理解如何更改随机森林的分割标准或评分,以减少假阴性的数量并增加1的召回率。我看到cohen_kappa_score
对于不平衡的数据集也很有用,但不能用于GridSearch等sklearn的交叉验证方法中。 oob_score
。通过过采样,我得到了最高的oob_score = 0.9535
,但这是很自然的,因为在这种情况下训练集是平衡的,问题仍然在于它不能很好地推广到测试集。现在我的想法已经用光了,所以我想知道我是缺少什么还是做错了什么。还是我应该尝试其他模型而不是随机森林?