xgboost
的新版本(0.8)中,已无需生成
fmap
来获取列名。
xgboost画图时遇到如下若干坑
xgboost
的新版本(0.8)对pandas
的DataFrame
支持已经很完善了,我们可以使用xgboost
的sklearn
接口,直接训练DataFrame
数据,同时也可以将列名直接作为特征名而无需再生成fmap
文件。(也可以手动修改xgb.Booster.feature_names = ['col1','col2',]
)
【注意!】因为xgboost内部会根据columns自动生成fmap
,而fmap文件是以空格分隔每一项的,因此, 列名中不能出现空格!
在jupyter notebook
中也可以使用xgb.to_graph
方法来通过graphviz
绘制后直接显示出来,该方法可显示矢量图,并可配置图字体的大小。
这里我们使用breast_cancer
数据集来测试:
import xgboost as xgb
import pandas as pd
from sklearn.datasets import load_breast_cancer
data =load_breast_cancer()
查看发现列名中含有空格
In [2]: data['feature_names'][0]
Out[2]: 'mean radius'
替换空格
# columns name can not have blank if you want to draw tree with feature name
data['feature_names'] = [ ''.join([character if character!=' ' else '_' for character in featureName ]) for featureName in data['feature_names']]
In [4]: data['feature_names'][0]
Out[4]: 'mean_radius'
df = pd.DataFrame(data['data'],columns=data['feature_names'])
clf = xgb.XGBClassifier()
clf.fit(df,data['target'])
xgb.to_graphviz(clf)
xgboost提供的绘图函数,节点shape为circle,画出来的图奇丑无比,我们对节点参数进行修改。
在xgboost源代码的ploting.py文件中修改以下几行:
# line 166
def to_graphviz(booster, fmap='', num_trees=0, rankdir='UT',
yes_color='#0000FF', no_color='#FF0000',conditionNodeParams={},leafNodeParams={}, **kwargs):
# line 215
node = _parse_node(graph, text,conditionNodeParams=conditionNodeParams,leafNodeParams= leafNodeParams)
# line 127
def _parse_node(graph, text,conditionNodeParams,leafNodeParams):
# line 132
graph.node(node, label=match.group(2), **conditionNodeParams)
# line 137
graph.node(node, label=match.group(2),**leafNodeParams)
修改条件节点的参数如下
cNodeParams = {'shape':'box',
'style':'filled,rounded',
'fillcolor':'#78bceb'
}
lNodeParams = {'shape':'box',
'style':'filled',
'fillcolor':'#e48038'
}
graphParams = {
'graph_attr':{}
}
x = plotting.to_graphviz(clf,conditionNodeParams=cNodeParams,leafNodeParams=lNodeParams,**{'size':str(15)})
在使用xgboost训练出模型xgbClf后:
import xgboost as xgb
from xgboost.sklearn import XGBClassifier
xgbClf = XGBClassifier()
xgbClf.fit(xTrain,yTrain)
可使用xgboost自带的plot_tree
函数绘制决策树
xgb.plot_tree(xgbClf)
然而绘制出来的图形不显示特征名,只是显示特征序号
查看原函数plot_tree(booster, fmap='', num_trees=0, rankdir='UT', ax=None, **kwargs)
发现一参数fmap不知何意。
几经尝试,最后发现kaggle大神已给出解决方案:kaggle解决方案
def ceate_feature_map(features):
outfile = open('xgb.fmap', 'w')
i = 0
for feat in features:
outfile.write('{0}\t{1}\tq\n'.format(i, feat))
i = i + 1
outfile.close()
ceate_feature_map(train_data.columns)#特征名列表
该函数生成一fmap文件名为xgb.fmap,那么我们可调用该fmap文件添加特征名。
xgb.plot_tree(xgbClf,fmap='xgb.fmap')
plot_tree
未提供修改图像大小的参数,这里直接通过在新建的Figure,Axes对象,调整Figure大小,再在其上画决策树图的方法实现调整大小
fig,ax = plt.subplots()
fig.set_size_inches(60,30)
xgb.plot_tree(xgbClf,ax = ax,fmap='xgb.fmap')
后续若想再次显示图像,直接在jupyter notebook的新建cell里输入:
fig
通过fig的savefig方法来保存图像
fig.savefig('xgb_tree.jpg')
The End