XGBClassifier 的特征重要性
Feature Importance with XGBClassifier
希望我读错了,但在 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_
您似乎可以通过调用 get_fscore
属性使用 Booster
对象计算特征重要性。我在 Booster
上使用 XGBClassifier
的唯一原因是因为它能够被包装在 sklearn 管道中。关于特征提取的任何想法?还有其他人遇到这种情况吗?
如评论所示,我怀疑您的问题是版本问题。但是,如果您不想 to/can 不更新,那么以下功能应该适合您。
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}
我找到了答案。版本 0.4a30
似乎没有 feature_importance_
属性。因此,如果您使用 pip install xgboost
安装 xgboost 包,您将无法从 XGBClassifier
对象中进行特征提取,如果您需要解决方法,可以参考@David 的回答。
但是,我所做的是通过克隆 repo 和 运行 . ./build.sh
从源代码构建它,这将安装版本 0.4
,其中 feature_importance_
属性有效。
希望这对其他人有帮助!
获取作为排序数据框的特征重要性
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)
对于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, )
对于与Luís Bianchin, "TypeError: 'str' object is not callable", I found a solution (that works for me at least) here有相同问题的人。
简而言之,我发现修改 David 的代码来自
imp_vals = xgb.booster().get_fscore()
到
imp_vals = xgb.get_fscore()
对我有用。
有关更多详细信息,我建议访问上面的 link。
非常感谢 David 和 ianozsvald
已接受答案的更新,因为它不再有效:
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()}
似乎 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()}
您还可以使用built-inplot_importance函数:
from xgboost import XGBClassifier, plot_importance
fit = XGBClassifier().fit(X,Y)
plot_importance(fit)
built-in 特征重要性的替代方法可以是:
- permutation-based 来自
scikit-learn
的重要性(permutation_importance
method
- Shapley 值的重要性 (
shap
package)
我非常喜欢shap
包,因为它提供了额外的情节。示例:
重要性图
剧情概要
依赖图
您可以在我的 blog post 中阅读 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_
您似乎可以通过调用 get_fscore
属性使用 Booster
对象计算特征重要性。我在 Booster
上使用 XGBClassifier
的唯一原因是因为它能够被包装在 sklearn 管道中。关于特征提取的任何想法?还有其他人遇到这种情况吗?
如评论所示,我怀疑您的问题是版本问题。但是,如果您不想 to/can 不更新,那么以下功能应该适合您。
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}
我找到了答案。版本 0.4a30
似乎没有 feature_importance_
属性。因此,如果您使用 pip install xgboost
安装 xgboost 包,您将无法从 XGBClassifier
对象中进行特征提取,如果您需要解决方法,可以参考@David 的回答。
但是,我所做的是通过克隆 repo 和 运行 . ./build.sh
从源代码构建它,这将安装版本 0.4
,其中 feature_importance_
属性有效。
希望这对其他人有帮助!
获取作为排序数据框的特征重要性
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)
对于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, )
对于与Luís Bianchin, "TypeError: 'str' object is not callable", I found a solution (that works for me at least) here有相同问题的人。
简而言之,我发现修改 David 的代码来自
imp_vals = xgb.booster().get_fscore()
到
imp_vals = xgb.get_fscore()
对我有用。
有关更多详细信息,我建议访问上面的 link。
非常感谢 David 和 ianozsvald
已接受答案的更新,因为它不再有效:
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()}
似乎 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()}
您还可以使用built-inplot_importance函数:
from xgboost import XGBClassifier, plot_importance
fit = XGBClassifier().fit(X,Y)
plot_importance(fit)
built-in 特征重要性的替代方法可以是:
- permutation-based 来自
scikit-learn
的重要性(permutation_importance
method - Shapley 值的重要性 (
shap
package)
我非常喜欢shap
包,因为它提供了额外的情节。示例:
重要性图
剧情概要
依赖图
您可以在我的 blog post 中阅读 Xgboost 中计算特征重要性的替代方法。