使用XGBClassifier进行功能重要性

时间:2016-07-05 21:00:31

标签: python scikit-learn xgboost

希望我读错了,但在XGBoost库documentation中,注意使用feature_importances_提取特征重要性属性,就像sklearn的随机森林一样。

但是,出于某种原因,我不断收到此错误:AttributeError: 'XGBClassifier' object has no attribute 'feature_importances_'

我的代码段如下:

from sklearn import datasets
import xgboost as xg
iris = datasets.load_iris()
X = iris.data
Y = iris.target
Y = iris.target[ Y < 2] # arbitrarily removing class 2 so it can be 0 and 1
X = X[range(1,len(Y)+1)] # cutting the dataframe to match the rows in Y
xgb = xg.XGBClassifier()
fit = xgb.fit(X, Y)
fit.feature_importances_

您似乎可以通过调用Booster属性使用get_fscore对象来计算要素重要性。我使用XGBClassifier而非Booster的唯一原因是因为它可以包含在sklearn管道中。有关功能提取的任何想法?还有其他人遇到过这种情况吗?

9 个答案:

答案 0 :(得分:17)

正如评论所示,我怀疑你的问题是版本问题。但是,如果您不想/不能更新,那么以下功能应该适合您。

def get_xgb_imp(xgb, feat_names):
    from numpy import array
    imp_vals = xgb.booster().get_fscore()
    imp_dict = {feat_names[i]:float(imp_vals.get('f'+str(i),0.)) for i in range(len(feat_names))}
    total = array(imp_dict.values()).sum()
    return {k:v/total for k,v in imp_dict.items()}


>>> import numpy as np
>>> from xgboost import XGBClassifier
>>> 
>>> feat_names = ['var1','var2','var3','var4','var5']
>>> np.random.seed(1)
>>> X = np.random.rand(100,5)
>>> y = np.random.rand(100).round()
>>> xgb = XGBClassifier(n_estimators=10)
>>> xgb = xgb.fit(X,y)
>>> 
>>> get_xgb_imp(xgb,feat_names)
{'var5': 0.0, 'var4': 0.20408163265306123, 'var1': 0.34693877551020408, 'var3': 0.22448979591836735, 'var2': 0.22448979591836735}

答案 1 :(得分:6)

我找到了答案。版本0.4a30似乎没有feature_importance_属性。因此,如果您使用pip install xgboost安装xgboost软件包,则无法从XGBClassifier对象进行功能提取,如果您需要解决方法,可以参考@ David的答案。

但是,我所做的是通过克隆存储库并运行. ./build.sh从源代码构建它,这将安装0.4属性工作的版本feature_importance_

希望这有助于他人!

答案 2 :(得分:2)

对于xgboost,如果您使用xgb.fit(),则可以使用以下方法来获取功能重要性。

import pandas as pd
xgb_model=xgb.fit(x,y)
xgb_fea_imp=pd.DataFrame(list(xgb_model.get_booster().get_fscore().items()),
columns=['feature','importance']).sort_values('importance', ascending=False)
print('',xgb_fea_imp)
xgb_fea_imp.to_csv('xgb_fea_imp.csv')

from xgboost import plot_importance
plot_importance(xgb_model, )

答案 3 :(得分:1)

将要素重要性作为已排序的数据框

import pandas as pd
import numpy as np
def get_xgb_imp(xgb, feat_names):
    imp_vals = xgb.booster().get_fscore()
    feats_imp = pd.DataFrame(imp_vals,index=np.arange(2)).T
    feats_imp.iloc[:,0]= feats_imp.index    
    feats_imp.columns=['feature','importance']
    feats_imp.sort_values('importance',inplace=True,ascending=False)
    feats_imp.reset_index(drop=True,inplace=True)
    return feats_imp

feature_importance_df = get_xgb_imp(xgb, feat_names)

答案 4 :(得分:1)

对于那些与Luís Bianchin有相同问题的人,“ TypeError:'str'对象不可调用”,我找到了一种解决方案(至少对我有用)here

简而言之,我发现从

修改David的代码
imp_vals = xgb.booster().get_fscore()

imp_vals = xgb.get_fscore()

为我工作。

有关更多详细信息,我建议您访问上面的链接。

非常感谢Davidianozsvald

答案 5 :(得分:0)

已接受答案的更新,因为它不再起作用:

def get_xgb_imp(xgb_model, feat_names):
    imp_vals = xgb_model.get_fscore()
    imp_dict = {feat: float(imp_vals.get(feat, 0.)) for feat in feat_names}
    total = sum(list(imp_dict.values()))
    return {k: round(v/total, 5) for k,v in imp_dict.items()}

答案 6 :(得分:0)

似乎api一直在变化。对于xgboost版本 1.0.2 ,只需将 @David 的答案中的imp_vals = xgb.booster().get_fscore()更改为imp_vals = xgb.get_booster().get_fscore()即可。更新的代码是-

from numpy import array

def get_xgb_imp(xgb, feat_names):
    imp_vals = xgb.get_booster().get_fscore()
    imp_dict = {feat_names[i]:float(imp_vals.get('f'+str(i),0.)) for i in range(len(feat_names))}
    total = array(imp_dict.values()).sum()
    return {k:v/total for k,v in imp_dict.items()}

答案 7 :(得分:0)

您还可以使用内置的plot_importance函数:

from xgboost import XGBClassifier, plot_importance
fit = XGBClassifier().fit(X,Y)
plot_importance(fit)

enter image description here

答案 8 :(得分:0)

内置功能重要性的替代方法可以是:

我非常喜欢shap软件包,因为它提供了更多的情节。示例:

重要图

xgboost shap importance

摘要图

xgboost shap summary

依赖图

xgboost shap dependence

您可以在此blog post中阅读有关在Xgboost中计算功能重要性的替代方法。