【问题标题】:Different way to think about feature importance考虑特征重要性的不同方式
【发布时间】:2019-02-15 09:37:00
【问题描述】:

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

这个总和在代码here 中找到

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

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

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

【问题讨论】:

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


    【解决方案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)  
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-27
      • 2020-11-02
      • 2018-12-14
      • 2021-12-23
      • 2021-02-03
      • 2016-11-07
      • 1970-01-01
      • 2022-07-17
      相关资源
      最近更新 更多