考虑特征重要性的不同方式

Different way to think about feature importance

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

这个总和在代码中找到here

我很确定很少使用但使用时很重要的功能在此方法中的排名不会很高。当前的定义类似于总效用,但我想我想要平均值。这将解决使用次数的问题。例如,如果有一个二进制特征在一百万行中只有 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)  

既然您可以选择您的评估指标,那么您可以选择一个对异常值或多或少敏感的指标。