考虑功能重要性的不同方法

时间:2018-09-10 22:48:46

标签: python scikit-learn decision-tree feature-selection

在Friedman的“Greedy Function Approximation” in the Annals of Statistics, 2001中,输入变量的相对重要性在第8.1节中进行了描述。方程式44(来自Breiman,Friedman,Olshen和Stone,1983年)表明,树中某要素的相对重要性是使用等式45对在该要素上分裂的所有节点(未归一化或成比例的)平方误差的总(即和)改善通过取总和的所有树的平均值(同样,不是比例的平均值)来计算特征对GBM的相对重要性。

此金额可在代码here

中找到

我很确定,很少使用但在使用时很重要的功能在该方法中不会排名很高。当前的定义类似于总效用,但是我想我想要平均值。这将消除使用次数的问题。例如,如果存在一个非零的二进制特征,那么一百万行中只有1个,但是当它对预测产生巨大影响时。将以上代码行的总和更改为平均值将突出显示这些功能。

这是完成的事情吗?由于节点上的功能重要性由该节点上的样本数量加权,我担心的效果是否已经达到平衡?有没有更好的方法来处理稀疏性和功能重要性?

以这种方式考虑功能重要性的目的是确保不会消除通常不重要但在少数罕见的异常情况下至关重要的功能。在进行特征选择时,很容易证明在查看汇总指标时删除此类特征是合理的。

1 个答案:

答案 0 :(得分:1)

here所述,通过树定义的功能重要性不是一个很好的指标。如果您负担得起计算时间,则最好使用排列功能的重要性。

ELI5对此有implementation。为了进行比较,您可以运行以下代码来检查训练有素的模型clf。

from eli5.sklearn import PermutationImportance
iterations = 5

#http://scikit-learn.org/stable/modules/model_evaluation.html#common-cases-predefined-values
eval_metric = 'r2'
#eval_metric = 'neg_mean_absolute_error' 
#eval_metric = 'neg_mean_squared_error'
#eval_metric = 'explained_variance'


perm_train = PermutationImportance(clf,scoring = eval_metric, n_iter=iterations).fit(X_train, y_train)
feature_importance_train = perm_train.feature_importances_
feature_importance_train_error = perm_train.feature_importances_std_/np.sqrt(iterations)

perm_test = PermutationImportance(clf,scoring = eval_metric, n_iter=iterations).fit(X_test, y_test)
feature_importance_test = perm_test.feature_importances_
feature_importance_test_error = perm_test.feature_importances_std_/np.sqrt(iterations)

# make model importances relative to max importance
feature_importance_model = clf.feature_importances_
feature_importance_model = feature_importance_train.max() * (feature_importance_model / feature_importance_model.max())

sorted_idx = np.argsort(feature_importance_model)
pos = np.arange(sorted_idx.shape[0]) + .5

featfig = plt.figure(figsize=(6, 15))
featfig.suptitle('Feature Importance')
featax = featfig.add_subplot(1, 1, 1)

featax.errorbar(x=feature_importance_train[sorted_idx], y=pos, xerr = feature_importance_train_error[sorted_idx], linestyle='none', marker='.', label = 'Train')
featax.errorbar(x=feature_importance_test[sorted_idx], y=pos, xerr = feature_importance_test_error[sorted_idx],linestyle='none', marker='.', label = 'Test')
featax.errorbar(x=feature_importance_model[sorted_idx], y=pos, linestyle='none', marker='.', label = 'Model')

featax.set_yticks(pos)
featax.set_yticklabels(np.array(features)[sorted_idx], fontsize=8)
featax.set_xlabel(eval_metric + ' change')
featlgd = featax.legend(loc=0)  

由于您可以选择评估指标,因此可以选择对异常值或多或少敏感的指标。