我正在尝试使用随机森林和逻辑回归来预测一个二元变量。我的数据类别非常不平衡(约1.5%的Y=1)。
随机森林中默认的特征重要性技术是基于分类准确率(错误率)的——这种方法已被证明对于不平衡类别来说是一个不好的衡量标准(参见这里和这里)。
用于随机森林特征选择的两个标准VIM是Gini VIM和置换VIM。大致来说,感兴趣的预测变量的Gini VIM是森林中由该预测变量在每次被选中用于分裂时产生的Gini不纯度减少的总和,按树的数量进行缩放。
我的问题是:这种方法在scikit-learn中是否有实现(就像在R包party
中那样)?或者可能有变通方法?
附注:这个问题与另一个问题有些关联。
回答:
经过一些研究后,这是我得出的结果:
from sklearn.cross_validation import ShuffleSplitfrom collections import defaultdictnames = db_train.iloc[:,1:].columns.tolist()# -- Gridsearched parametersmodel_rf = RandomForestClassifier(n_estimators=500, class_weight="auto", criterion='gini', bootstrap=True, max_features=10, min_samples_split=1, min_samples_leaf=6, max_depth=3, n_jobs=-1)scores = defaultdict(list)# -- Fit the model (could be cross-validated)rf = model_rf.fit(X_train, Y_train)acc = roc_auc_score(Y_test, rf.predict(X_test))for i in range(X_train.shape[1]): X_t = X_test.copy() np.random.shuffle(X_t[:, i]) shuff_acc = roc_auc_score(Y_test, rf.predict(X_t)) scores[names[i]].append((acc-shuff_acc)/acc)print("Features sorted by their score:")print(sorted([(round(np.mean(score), 4), feat) for feat, score in scores.items()], reverse=True))Features sorted by their score:[(0.0028999999999999998, 'Var1'), (0.0027000000000000001, 'Var2'), (0.0023999999999999998, 'Var3'), (0.0022000000000000001, 'Var4'), (0.0022000000000000001, 'Var5'), (0.0022000000000000001, 'Var6'), (0.002, 'Var7'), (0.002, 'Var8'), ...]
输出结果并不美观,但你应该能明白意思。这种方法的弱点在于特征重要性似乎非常依赖于参数。我使用不同的参数(max_depth
,max_features
等)运行了它,得到了很多不同的结果。因此,我决定对参数进行网格搜索(scoring = 'roc_auc'
),然后将这种VIM(变量重要性度量)应用于最佳模型。
我的灵感来自于这个(很棒的)笔记本。
欢迎所有建议和评论!