1

我已经训练了一个 XGBoost 模型并使用 plot_importance() 来绘制在训练模型中哪些特征是最重要的。虽然,情节中的数字有几个十进制值,这会淹没情节并且不适合情节。

我已经搜索了绘图格式化选项,但我只找到了如何格式化轴(尝试格式化 X 轴,希望它也会格式化相应的轴)

我在 Jupyter Notebook 中工作(如果这有什么不同的话)。代码如下:

xg_reg = xgb.XGBClassifier(
                objective = 'binary:logistic',
                colsample_bytree = 0.4,
                learning_rate = 0.01,
                max_depth = 15, 
                alpha = 0.1, 
                n_estimators = 5,
                subsample = 0.5,
                scale_pos_weight = 4
                )
xg_reg.fit(X_train, y_train) 
preds = xg_reg.predict(X_test)

ax = xgb.plot_importance(xg_reg, max_num_features=3, importance_type='gain', show_values=True) 

fig = ax.figure
fig.set_size_inches(10, 3)

有什么我想念的吗?是否有要传递的格式化函数或参数?

我希望能够格式化特征重要性分数,或者至少去掉小数部分(例如“25”而不是“25.66521”)。在下面附上当前的图。

xgboost_feature_importance_scores

4

3 回答 3

2

无需编辑 xgboost 绘图函数即可获得您想要的结果。绘图函数可以将重要性字典作为其第一个参数,您可以直接从 xgboost 模型创建它,然后进行编辑。如果您想为特征名称制作更友好的标签,这也很方便。

# Get the booster from the xgbmodel
booster = xg_reg.get_booster()

# Get the importance dictionary (by gain) from the booster
importance = booster.get_score(importance_type="gain")

# make your changes
for key in importance.keys():
    importance[key] = round(importance[key],2)

# provide the importance dictionary to the plotting function
ax = plot_importance(importance, max_num_features=3, importance_type='gain', show_values=True)
于 2020-02-21T20:27:03.130 回答
1

编辑 xgboost 包中 plotting.py 的代码:

86 ylocs = np.arange(len(values))
87 values=tuple([round(x,4) for x in values])
88 ax.barh(ylocs, values, align='center', height=height, **kwargs)

在此处输入图像描述

于 2019-07-09T13:58:29.687 回答
1

我在这里遇到了刚刚解决的同样的麻烦。

它发生只是因为对于“增益”或“覆盖”,数字包含太多与“权重”选项相反的浮动数字。不幸的是,据我所知,没有指定位数的选项。因此,我自己修改了函数以指定允许的最大位数。以下是在xgboost 包的 plotting.py 文件中执行的修改。如果您正在使用蜘蛛控制台,您可以通过指定错误的选项(我是一个懒惰的人)找到并打开文件,例如:

xgb.plot_importance(xg_reg, potato=False)

然后从控制台的错误中单击文件。下一步是修改函数本身,如下所示:

def plot_importance(booster, ax=None, height=0.2,
                    xlim=None, ylim=None, title='Feature importance',
                    xlabel='F score', ylabel='Features',
                    importance_type='weight', max_num_features=None,
                    grid=True, show_values=True, max_digits=3, **kwargs): 

然后您还应该在 show_values 条件之前添加:

if max_digits is not None:
    t = values
    lst = list(t)
    if len(str(lst[0]).split('.')[-1])>max_digits:
        values_displayed = tuple([('{:.'+str(max_digits)+'f}').format(x) for x in lst])
    else:
        values_displayed = values

if show_values is True:
    for x, x2, y in zip(values, values_displayed, ylocs):
        ax.text(x + 1, y, x2, va='center')

我执行了一个条件来仅格式化数字,后者比指定的位数长。例如,它避免了importance_type='weight' 选项产生不需要的数字。

请注意,对于 'cover' 和 'gain' 文本对我来说也不好定位,因此我也修改了 shift 并将上面的 1 替换为:

if show_values is True:
    for x, x2, y in zip(values, values_displayed, ylocs):
         dx = np.max(values)/100
         ax.text(x + dx, y, x2, va='center')

希望对你有帮助!

于 2019-05-19T09:24:31.973 回答