精华内容
下载资源
问答
  • 特征重要性评估

    2020-07-07 09:37:11
    1、gbdt、xgb 特征重要性源码解释:https://zhuanlan.zhihu.com/p/64759172 2、shap对xgboost特征重要性评估 https://zhuanlan.zhihu.com/p/64799119

    1、分类树特征重要性

    参考:gbdt、xgb 特征重要性源码解释https://zhuanlan.zhihu.com/p/64759172

    importance_type指importance的计算类型;可取值有5个:

    • weight
      权重(某特征在整个树群节点中出现的次数,出现越多,价值就越高)
    • gain
      (某特征在整个树群作为分裂节点的信息增益之和再除以某特征出现的频次)
    • total_gain
      (同上,代码中有介绍,这里total_gain就是gain)
    • cover和total_cover
      cover比较复杂,是指某特征节点样本的二阶导数和再除以某特征出现的频次

    原始的get_score()方法只是输出按照weight、gain、cover计算的统计值,为了得到百分比形式,将feature_importance_中特征归一化,分母为所有特征的重要性统计量之和。

    注意:xgboost sklearn API在计算特征重要性的时候默认importance_type=“gain”,而原始的get_score方法默认importance_type=“weight”

    2、回归树 特征重要性

    gbdt是根据分裂前后节点的impurity减少量来评估特征重要性;impurity计算和节点的分裂标准是MSE或MAE
    步骤:
    i 遍历每个节点,该节点对应分裂特征重要性统计量=分裂前impurity减去分裂后左右二叉树impurity之和
    ii 计算impurity的差值时,每个impurity都乘以对应权重(分支的样本数)
    iii 一个特征在树中可以被用来多次分裂,基于上一步的数据,等同于这里按照特征groupby后对其重要性统计量求和

    3、利用SHAP解释Xgboost模型

    https://zhuanlan.zhihu.com/p/64799119

    展开全文
  • # 基于模型的特征重要性评估 # 得到特征重要性 importances = list(model_name.feature_importances_) # model_name为已经训练好的模型。 # 转换格式 feature_importances = [(feature, round(importance, 2)) for ...

    基于Tree的集成机器学习算法已经成为机器学习领域的主流算法。我们在做任何一个机器学习任务时,大部分的精力都会放在特征工程上(Feature Engineering)。我们通常会采用前向或后向策略,根据模型的结果进行特征选择。然而,在使用Tree ensemble算法时,有一个更有用的模型属性(feature importance),我们经常用它来进行特征选择。所以,有必要介绍一下feature importance的计算公式,便于大家更好理解特征和模型。 
    Friedman在GBM[1]的论文中提出的方法: 
    特征xjxj在整个模型中的重要程度为:

     其中,M是模型中树的数量。

    特征xjxj在单独一个树上的特征重要度为:

    其中,L−1L−1是树中非叶子节点数量,vtvt表示在内部节点t进行分裂时选择的特征,I2t^It2^是内部节点t分裂后平方损失的减少量。 
     
     J. H. Friedman. 2001. Greedy Function Approximation: A  Gradient Boosting Machine. Annals of Statistics 29(5):1189-  1232.

     

     

    # 基于模型的特征重要性评估
    # 得到特征重要性
    importances = list(model_name.feature_importances_)  # model_name为已经训练好的模型。
    # 转换格式
    feature_importances = [(feature, round(importance, 2)) for feature, importance in zip(list(X.columns), importances)]  # X为特征数据(相对与Y是标签值)
    # 排序
    feature_importances = sorted(feature_importances, key = lambda x: x[1], reverse = True)
    # 输出展示
    [print('Variable: {:20} Importance: {}'.format(*pair)) for pair in feature_importances]
    # 得到特征重要性后,按照相关论文经验,选择特征到特征重要性累加值达到95%

     

    展开全文
  • 特征重要性评估及筛选

    千次阅读 2020-03-04 17:55:21
    sklearn中特征重要性的计算方法, 基于重要性来进行特征选择
    
    
    feature_results = pd.DataFrame({'feature': list(train_features.columns),
                                   'importance': model.feature_importances_})
    feature_results = feature_results.sort_values('importance',ascending=False).reset_index(drop=True)
    
    from IPython.core.pylabtools import figsize
    figsize(12, 10)
    plt.style.use('ggplot')
    
    feature_results.loc[:9, :].plot(x = 'feature', y = 'importance', edgecolor = 'k',
                                   kind = 'barh', color = 'blue')
    plt.xlabel('Relative Importance', fontsize = 18); plt.ylabel('')
    plt.title('Feature Importances from Random Forest', size = 26)
    

    在这里插入图片描述

    cumulative_importances = np.cumsum(feature_results['importance'])
    plt.figure(figsize = (20, 6))
    plt.plot(list(range(feature_results.shape[0])), cumulative_importances.values, 'b-')
    plt.hlines(y=0.95, xmin=0, xmax=feature_results.shape[0], color='r', linestyles='dashed')
    # plt.xticks(list(range(feature_results.shape[0])), feature_results.feature, rotation=60)
    plt.xlabel('Feature', fontsize = 18)
    plt.ylabel('Cumulative importance', fontsize = 18)
    plt.title('Cumulative Importances', fontsize = 26)
    

    在这里插入图片描述

    most_num_importances = np.where(cumulative_importances > 0.95)[0][0] + 1
    print('Number of features for 95% importance: ', most_num_importances)
    

    Number of features for 95% importance: 13

    • 基于重要性来进行特征选择
    most_important_features = feature_results['feature'][:13]
    indices = [list(train_features.columns).index(x) for x in most_important_features]
    X_reduced = X[:, indices]
    X_test_reduced = X_test[:, indices]
    print('Most import training features shape: ', X_reduced.shape)
    print('Most import testing features shape: ', X_test_reduced.shape)
    

    Most import training features shape: (6622, 13)
    Most import testing features shape: (2839, 13)

    展开全文
  • 树模型特征重要性评估方法

    千次阅读 2018-05-07 21:28:33
    前言 在特征的选择过程中,如果学习器...各种模型的特征重要性计算 Random Forests 袋外数据错误率评估 RF的数据是boostrap的有放回采样,形成了袋外数据。因此可以采用袋外数据(OOB)错误率进行特征重要...

    前言

    在特征的选择过程中,如果学习器(基学习器)是树模型的话,可以根据特征的重要性来筛选有效的特征。本文是对Random Forest、GBDT、XGBoost如何用在特征选择上做一个简单的介绍。

    各种模型的特征重要性计算

    Random Forests

    • 袋外数据错误率评估
      RF的数据是boostrap的有放回采样,形成了袋外数据。因此可以采用袋外数据(OOB)错误率进行特征重要性的评估。
      袋外数据错误率定义为:袋外数据自变量值发生轻微扰动后的分类正确率与扰动前分类正确率的平均减少量。
      (1)对于每棵决策树,利用袋外数据进行预测,将袋外数据的预测误差记录下来,其每棵树的误差为vote1,vote2,…,voteb
      (2)随机变换每个预测变量,从而形成新的袋外数据,再利用袋外数据进行验证,其每个变量的误差是votel1,votel2,…votelb

    • Gini系数评价指标 (和GBDT的方法相同)

    GBDT

    在sklearn中,GBDT和RF的特征重要性计算方法是相同的,都是基于单棵树计算每个特征的重要性,探究每个特征在每棵树上做了多少的贡献,再取个平均值。
    利用随机森林对特征重要性进行评估写的比较清楚了,但是还是有一点小的问题,比较ensemble模型 零碎记录中对源代码的解析可以看出,前者计算中丢失了weighted_n_node_samples。

    • 利用Gini计算特征的重要性
      单棵树上特征的重要性定义为:特征在所有非叶节在分裂时加权不纯度的减少,减少的越多说明特征越重要。
      沿用参考博客里的符号,我们将变量重要性评分(variable importance measures)用VIM来表示,将Gini指数用GI来表示
      节点m的Gini指数的计算公式为:
      GIm=1k=1|K|pmk2

      其中,K表示有K个类别,pmk表示节点m中类别k所占的比例。直观地说,就是随便从节点m中随机抽取两个样本,其类别标记不一致的概率。
      特征Xj在节点m的重要性可以表示为加权不纯度的减少
      VIMjmGini=Nm×GImNl×GIlNr×GIr

      其中,GIlGIr分别表示分枝后两个新节点的Gini指数。NmNlNr表示节点m、左孩子节点l和右孩子节点r的样本数。
      如果,特征Xj在决策树i中出现的节点在集合M中,那么Xj在第i颗树的重要性为
      VIMij=mMVIMjm

    ~~如果这样还不是很清晰的话,我们来举个例子(李航统计学习方法表5.1)

    import numpy as np
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.externals.six import StringIO
    from sklearn import tree
    import pydotplus
    
    clf = DecisionTreeClassifier()
    x = [[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3],
         [1,1,2,2,1,1,1,2,1,1,1,1,2,2,1],
         [1,1,1,2,1,1,1,2,2,2,2,2,1,1,1],
         [1,2,2,1,1,1,2,2,3,3,3,2,2,3,1]
         ]
    y =  [1,1,2,2,1,1,1,2,2,2,2,2,2,2,1]
    x = np.array(x)
    x = np.transpose(x)
    clf.fit(x,y)
    print clf.feature_importances_
    feature_name = ['A1','A2','A3','A4']
    target_name = ['1','2']
    dot_data = StringIO()
    tree.export_graphviz(clf,out_file = dot_data,feature_names=feature_name,
                         class_names=target_name,filled=True,rounded=True,
                         special_characters=True)
    graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
    graph.write_pdf("WineTree.pdf")
    print('Visible tree plot saved as pdf.')

    可以得到树的划分过程图
    这里写图片描述
    特征A3的重要性为 0.48×150.4444×90=3.2004
    特征A2的重要性为 0.4444×900=3.9996
    特征A1和A4的重要性都为0
    所以该棵树上所有节点总的加权不纯度减少量为 3.2004+3.9996=7.3
    对其进行归一化操作可以得到A1、A2、A3、A4的特征重要性为

    [ 0. 0.55555556 0.44444444 0. ]

    这是单棵树上特征的计算方法,推广到n棵树

    VIMj=i=1nVIMij

    最后,把所有求得的重要性评分做一个归一化处理即可。
    VIMj=VIMji=1cVIMi

    其中c为特征的总个数

    XGBoost

    关于XGBoost中特征重要性计算相关代码出现在xgboost/core.py L1203

        def get_score(self, fmap='', importance_type='weight'):
            """Get feature importance of each feature.
            Importance type can be defined as:
                'weight' - the number of times a feature is used to split the data across all trees.
                'gain' - the average gain of the feature when it is used in trees
                'cover' - the average coverage of the feature when it is used in trees
            Parameters
            ----------
            fmap: str (optional)
               The name of feature map file
            """
    
            if importance_type not in ['weight', 'gain', 'cover']:
                msg = "importance_type mismatch, got '{}', expected 'weight', 'gain', or 'cover'"
                raise ValueError(msg.format(importance_type))
    
            # if it's weight, then omap stores the number of missing values
            if importance_type == 'weight':
                # do a simpler tree dump to save time
                trees = self.get_dump(fmap, with_stats=False)
    
                fmap = {}
                for tree in trees:
                    for line in tree.split('\n'):
                        # look for the opening square bracket
                        arr = line.split('[')
                        # if no opening bracket (leaf node), ignore this line
                        if len(arr) == 1:
                            continue
    
                        # extract feature name from string between []
                        fid = arr[1].split(']')[0].split('<')[0]
    
                        if fid not in fmap:
                            # if the feature hasn't been seen yet
                            fmap[fid] = 1
                        else:
                            fmap[fid] += 1
    
                return fmap
    
            else:
                trees = self.get_dump(fmap, with_stats=True)
    
                importance_type += '='
                fmap = {}
                gmap = {}
                for tree in trees:
                    for line in tree.split('\n'):
                        # look for the opening square bracket
                        arr = line.split('[')
                        # if no opening bracket (leaf node), ignore this line
                        if len(arr) == 1:
                            continue
    
                        # look for the closing bracket, extract only info within that bracket
                        fid = arr[1].split(']')
    
                        # extract gain or cover from string after closing bracket
                        g = float(fid[1].split(importance_type)[1].split(',')[0])
    
                        # extract feature name from string before closing bracket
                        fid = fid[0].split('<')[0]
    
                        if fid not in fmap:
                            # if the feature hasn't been seen yet
                            fmap[fid] = 1
                            gmap[fid] = g
                        else:
                            fmap[fid] += 1
                            gmap[fid] += g
    
                # calculate average value (gain/cover) for each feature
                for fid in gmap:
                    gmap[fid] = gmap[fid] / fmap[fid]
                return gmap

    在XGBoost中提供了三种特征重要性的计算方法:

    ‘weight’ - the number of times a feature is used to split the data across all trees.
    ‘gain’ - the average gain of the feature when it is used in trees
    ‘cover’ - the average coverage of the feature when it is used in trees

    简单来说
    weight就是在所有树中特征用来分割的节点个数总和;
    gain就是特征用于分割的平均增益
    cover 的解释有点晦涩,在[R-package/man/xgb.plot.tree.Rd]有比较详尽的解释:(https://github.com/dmlc/xgboost/blob/f5659e17d5200bd7471a2e735177a81cb8d3012b/R-package/man/xgb.plot.tree.Rd):the sum of second order gradient of training data classified to the leaf, if it is square loss, this simply corresponds to the number of instances in that branch. Deeper in the tree a node is, lower this metric will be。实际上coverage可以理解为被分到该节点的样本的二阶导数之和,而特征度量的标准就是平均的coverage值。

    还是举李航书上那个例子,我们用不同颜色来表示不同的特征,绘制下图
    这里写图片描述

    import xgboost as xgb
    import numpy as np
    x = [[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3],
         [1,1,2,2,1,1,1,2,1,1,1,1,2,2,1],
         [1,1,1,2,1,1,1,2,2,2,2,2,1,1,1],
         [1,2,2,1,1,1,2,2,3,3,3,2,2,3,1]
         ]
    y =  [0,0,1,1,0,0,0,1,1,1,1,1,1,1,0]
    x = np.array(x)
    x = np.transpose(x)
    
    params = {
        'max_depth': 10,
        'subsample': 1,
        'verbose_eval': True,
        'seed': 12,
        'objective':'binary:logistic'
    }
    xgtrain = xgb.DMatrix(x, label=y)
    bst = xgb.train(params, xgtrain, num_boost_round=10)
    fmap = 'weight'
    importance = bst.get_score(fmap = '',importance_type=fmap)
    print importance
    print bst.get_dump(with_stats=False)
    fmap = 'gain'
    importance = bst.get_score(fmap = '',importance_type=fmap)
    print importance
    print bst.get_dump(with_stats=True)
    fmap = 'cover'
    importance = bst.get_score(fmap = '',importance_type=fmap)
    print importance
    print bst.get_dump(with_stats=True)

    logs :

    0:[f2<1.5] yes=1,no=2,missing=1,gain=3.81862,cover=3.75
        1:[f3<1.5] yes=3,no=4,missing=3,gain=1.4188,cover=2.25
            3:leaf=-0.3,cover=1
            4:leaf=0.0666667,cover=1.25
        2:leaf=0.36,cover=1.5
    
    0:[f2<1.5] yes=1,no=2,missing=1,gain=2.69365,cover=3.67888
        1:leaf=-0.119531,cover=2.22645
        2:leaf=0.30163,cover=1.45243
    
    0:[f1<1.5] yes=1,no=2,missing=1,gain=2.4414,cover=3.5535
        1:leaf=-0.107177,cover=2.35499
        2:leaf=0.302984,cover=1.19851
    
    0:[f2<1.5] yes=1,no=2,missing=1,gain=1.92691,cover=3.49546
        1:leaf=-0.10337,cover=2.16893
        2:leaf=0.259344,cover=1.32653
    
    0:[f1<1.5] yes=1,no=2,missing=1,gain=1.79698,cover=3.3467
        1:leaf=-0.095155,cover=2.24952
        2:leaf=0.263871,cover=1.09718
    
    0:[f3<1.5] yes=1,no=2,missing=1,gain=1.56711,cover=3.26459
        1:leaf=-0.165662,cover=1.02953
        2:[f2<1.5] yes=3,no=4,missing=3,gain=0.084128,cover=2.23506
            3:leaf=0.0508745,cover=1.20352
            4:leaf=0.220771,cover=1.03154
    
    0:[f1<1.5] yes=1,no=2,missing=1,gain=1.31036,cover=3.12913
        1:leaf=-0.0852405,cover=2.12169
        2:leaf=0.227708,cover=1.00744
    
    0:[f2<1.5] yes=1,no=2,missing=1,gain=1.25432,cover=3.0361
        1:leaf=-0.0915171,cover=1.94381
        2:leaf=0.214414,cover=1.09229
    
    0:[f0<2.5] yes=1,no=2,missing=1,gain=0.440551,cover=2.89962
        1:leaf=-0.0431823,cover=1.87075
        2:leaf=0.142726,cover=1.02887
    
    0:leaf=0.0379022,cover=2.86568

    使用weight的结果为

    {‘f0’: 1, ‘f1’: 3, ‘f2’: 5, ‘f3’: 2}

    使用gain的结果为

    {‘f0’: 0.440551, ‘f1’: 1.8495799999999998, ‘f2’: 1.9555256, ‘f3’: 1.492955}

    使用cover的结果为

    {‘f0’: 2.89962, ‘f1’: 3.34311, ‘f2’: 3.2390999999999996, ‘f3’: 2.757295}

    可以看出,不同的特征重要性度量方法得出的结果也是不尽相同的。
    这里有个疑惑,究竟哪种度量方法更为合理呢?

    To do list : LightGBM

    展开全文
  •  L1正则方法具有稀疏解的特性,因此天然具备特征选择的特性,但是要注意,L1没有选到的特征不代表不重要,原因是两个具有高相关性的特征可能只保留了一个,如果要确定哪个特征重要应再通过L2正则方法交叉检验。...
  • scaled, y_test)) # 模型分数应该采用测试集进行计算 # ============================================================================= # 特征重要性评估:通过RFC内的属性值调出 import seaborn as sns import ...
  • 利用随机森林对特征重要性进行评估

    万次阅读 多人点赞 2017-08-18 16:22:48
    随机森林是以决策树为基学习器的集成学习算法。随机森林非常简单,易于实现,计算开销也很小,更令人惊奇的是它在分类和回归上表现出了十分惊人的性能,因此,...本文是对随机森林如何用在特征选择上做一个简单的介绍。
  • 随机森林如何评估特征重要性

    千次阅读 2019-03-11 11:56:33
    随机森林中进行特征重要性评估思想为: 判断每个特征在随机森林中的每颗树上做了多大的贡献,然后取个平均值,最后比一比特征之间的贡献大小。其中关于贡献的计算方式可以是基尼指数或袋外数据错误率。 RF评估...
  • 特征筛选:重要性评估

    千次阅读 2020-07-22 21:50:09
    特征筛选的目的: ...有区分(Informative) 特征之间相互独立(Independent) 简单易于理解(Simple) sklearn中包含feature_select模块,基本都可以实现特征选择的功能。通常复杂模型有 fe
  • 基于 UCI 葡萄酒数据,使用随机森林进行特征重要性分析,这些数据是对意大利同一地区种植的三种不同品种葡萄酒的化学分析结果,分析确定了三种葡萄酒中13种成分的含量,数据的第一列是葡萄酒的类别
  • 随机森林评估特征重要性

    千次阅读 2019-11-01 10:24:00
    随机森林(RF)简介 只要了解决策树的算法,那么随机森林是相当容易理解的。...2)利用这d个特征分别对样本集进行划分,找到最佳的划分特征(可用基尼系数、增益率或者信息增益判别) 3、重复步骤1...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 747
精华内容 298
关键字:

特征重要性评估