代码之家  ›  专栏  ›  技术社区  ›  Keith

对功能重要性的不同思考方式

  •  1
  • Keith  · 技术社区  · 7 年前

    在弗里德曼 “Greedy Function Approximation” in the Annals of Statistics, 2001 第8.1节描述了输入变量的相对重要性。方程44(摘自Breiman,Friedman,Olshen&Stone,1983)表明,特征在树中的相对重要性是在未标准化或比例化的特征上拆分所有节点的平方误差的总(即和)改进,方程45通过采用求和的所有树的平均值(同样,不是比例的平均值)。

    这个总数在代码中找到 here

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

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

    以这种方式思考特征重要性的目的是确保不消除一般不重要但在一些罕见的异常情况下至关重要的特征。在进行功能选择时,在查看聚合度量时,很容易证明删除这些功能是合理的。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Keith    7 年前

    如所解释的 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)  
    

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

    推荐文章