permutation:特征重要性-学习笔记

特征重要性:Permutation Importance

方法简介

一个最基本的问题大概会是什么特征对我模型预测的影响最大呢?我们有很多方法来衡量特征的重要性,这里呢,将会介绍一种方法:排列重要性。

工作原理

排列重要性,一定是在model训练完成后,才可以计算的。简单来说,就是改变数据表格中某一列的数据的排列,保持其余特征不动,看其对预测精度的影响有多大。

注意事项

  1. 事先排除相关性大的特征。
  2. 对于类别型特征,不适用。
  3. 对于类别特征做完one-hot编码之后,不太适用(因为有大量0,不能保证全部打乱,并且会导致一个样本有多个值为1),应该在做one-hot编码之前打乱顺序做。但是如何操作呢?:我现在还不知道。

    两种方式

方式一

在数据集上训练并计算特征重要性。cv=None,或者k-fold,还可以用于与selectModel、RFE结合用于特征选择。

方式二

  1. 在数据集A上训练一个模型model
  2. 在数据集B上测试这个模型,得到MSE(回归)或者logloss(分类,或者auc)
  3. 对数据集B中的某一个特征中的值打乱(随机置换,random permute),再用模型进行预测,得到新的指标,这个指标在步骤2和3之间的差值,就是这个特征的重要性
  4. 把上一个步骤中打乱的column复原,换下一个column重复上一个步骤,直到所有column都算一遍。

    代码

参数

  1. estimator:已经训练好的模型、未训练的模型
  2. cv值:有三种模式:prefit,None,k-fold.其中prefit适合检验模型、None、k-fold还可以用于与selectModel、RFE结合用于特征选择。prefit意味需要传入的是已经训练好的模型,对应的数据集可以是训练数据或者验证数据,它不再训练模型,只是在数据集上计算特征重要性,如果用于验证数据,则输出的特征重要性表征的是一般化的特征的重要性;None,训练和计算特征重要性在同一组数据集,输出的不是一般化的特征重要性;k-fold训练模型,并在一系列的训练测试集上计算特征重要性,最终的特征重要性返回的是平均值,不是最终模型的特征重要性,但是是一般化的特征重要性。
  3. refit:如果使用交叉验证,是否在所有数据集上训练模型,默认是True。
  4. n_iter:默认为5,迭代次数,降低该值以提高速度,增加以获得更精确的估计。
  5. scoring:评价指标。

    属性

  6. feature_importances_:特征重要性,返回的是当每列被随机打乱后和打乱前的差值。

  7. feature_importances_std_:特征重要性方差。
  8. results_:所有实验的所有差值。
  9. scores_s:所有实验的所有初始值。
  10. estimator_:如果模型传入时是未训练好的模型时,返回训练后的模型。

    代码说明

  11. eli5.show_weights好像用不了,建议自己实现。

  12. 本代码没有设置cv值,默认是prefit,所以此处传入的是已经训练好的模型。
  13. 问题/疑问:在训练集和测试集上分别计算重要性,差别较大(特征未处理,可能存在相关性、类别特征),是什么原因呢?应该用哪个数据集来做呢?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    from xgboost import XGBClassifier    
    from sklearn.model_selection import train_test_split
    import eli5 # python计算permutation importance工具包
    from eli5.sklearn import PermutationImportance

    path = 'data.csv'
    data = pd.read_csv(path)
    #...省略数据预处理过程
    X_train, X_test, y_train, y_test = train_test_split(df, y, test_size=0.2, random_state = 400)

    # 训练XGBoost模型
    model = xgb.XGBClassifier(
    learning_rate =0.05,
    n_estimators=100,
    max_depth=3,
    min_child_weight=1,
    gamma=0.3,
    subsample=0.8,
    colsample_bytree=0.8,
    objective= 'multi:softprob',
    nthread=4,
    scale_pos_weight=1,
    num_class=2,
    seed=27
    ).fit(X_train, y_train)
    ## 默认是prefit,所以此处传入的是已经训练好的模型。
    perm = PermutationImportance(model, random_state = 1).fit(X_test, y_test)
    ## 可视化:这个现在好像不能用。建议自己实现。
    eli5.show_weights(perm, feature_names = X_test.columns.tolist())

源码

https://github.com/TeamHG-Memex/eli5/blob/master/eli5/sklearn/permutation_importance.py#L202