R中的xgb.plot.tree布局 [英] xgb.plot.tree layout in r
问题描述
我正在阅读一本xgb 笔记本,示例中的xgb.plot.tree命令产生如下图片:
I was reading a xgb notebook and the xgb.plot.tree command in example result in a pic like this:
但是,当我做同样的事情时,却得到了一张这样的图片,它是两个单独的图形,并且颜色也不同.
However when i do the same thing I got a pic like this which are two separate graphs and in different colors too.
那正常吗?这两个图是两棵树吗?
Is that normal? are the two graphs two trees?
推荐答案
我遇到了同样的问题. 根据xgboost github存储库上的一个问题案例,这可能是由于xgboost用于渲染树的DiagrammeR库发生了变化. https://github.com/dmlc/xgboost/issues/2640
I have the same issue. According to an issue case on the xgboost github repository, this could be due to a change in the DiagrammeR library used by xgboost for rendering trees. https://github.com/dmlc/xgboost/issues/2640
我选择创建一个新版本的函数xgb.plot.tree
来直接定义节点字体的颜色,而不是使用diagrammeR命令修改dgr_graph
对象.在nodes <- DiagrammeR::create_node_df
行中添加参数fontcolor="black"
就足够了
Instead of modifying the dgr_graph
object with diagrammeR commands, I chose to create a new version of the function xgb.plot.tree
that defines the color of font of nodes directly. It was sufficient to add the parameter fontcolor="black"
in the nodes <- DiagrammeR::create_node_df
line
xgb.plot.tree <- function (feature_names = NULL, model = NULL, n_first_tree = NULL,
plot_width = NULL, plot_height = NULL, ...)
{
if (class(model) != "xgb.Booster") {
stop("model: Has to be an object of class xgb.Booster model generaged by the xgb.train function.")
}
if (!requireNamespace("DiagrammeR", quietly = TRUE)) {
stop("DiagrammeR package is required for xgb.plot.tree",
call. = FALSE)
}
allTrees <- xgb.model.dt.tree(feature_names = feature_names,
model = model, n_first_tree = n_first_tree)
allTrees[, `:=`(label, paste0(Feature, "\\nCover: ", Cover,
"\\nGain: ", Quality))]
allTrees[, `:=`(shape, "rectangle")][Feature == "Leaf", `:=`(shape,
"oval")]
allTrees[, `:=`(filledcolor, "Beige")][Feature == "Leaf",
`:=`(filledcolor, "Khaki")]
nodes <- DiagrammeR::create_node_df(n = length(allTrees[,
ID] %>% rev), label = allTrees[, label] %>% rev, style = "filled",
color = "DimGray", fillcolor = allTrees[, filledcolor] %>%
rev, shape = allTrees[, shape] %>% rev, data = allTrees[,
Feature] %>% rev, fontname = "Helvetica", fontcolor="black")
edges <- DiagrammeR::create_edge_df(from = match(allTrees[Feature !=
"Leaf", c(ID)] %>% rep(2), allTrees[, ID] %>% rev), to = match(allTrees[Feature !=
"Leaf", c(Yes, No)], allTrees[, ID] %>% rev), label = allTrees[Feature !=
"Leaf", paste("<", Split)] %>% c(rep("", nrow(allTrees[Feature !=
"Leaf"]))), color = "DimGray", arrowsize = "1.5", arrowhead = "vee",
fontname = "Helvetica", rel = "leading_to")
graph <- DiagrammeR::create_graph(nodes_df = nodes, edges_df = edges)
DiagrammeR::render_graph(graph, width = plot_width, height = plot_height)
}
然后,仍然需要更改一些参数以提高图形的可读性.在下面,我添加了一个示例代码,用于显示xgboost模型的第一棵树.
Then, it remains to change some parameters to improve the readibility of the graph. Below I add an example of the code I use to display the first tree of my xgboost model.
xgb.plot.tree <- function (feature_names = NULL, model = NULL, n_first_tree = NULL,
plot_width = NULL, plot_height = NULL, ...)
{
if (class(model) != "xgb.Booster") {
stop("model: Has to be an object of class xgb.Booster model generaged by the xgb.train function.")
}
if (!requireNamespace("DiagrammeR", quietly = TRUE)) {
stop("DiagrammeR package is required for xgb.plot.tree",
call. = FALSE)
}
allTrees <- xgb.model.dt.tree(feature_names = feature_names,
model = model, n_first_tree = n_first_tree)
allTrees$Quality <- round(allTrees$Quality, 3)
allTrees$Cover <- round(allTrees$Cover, 3)
allTrees[, `:=`(label, paste0(Feature, "\\nCover: ", Cover,
"\\nGain: ", Quality))]
allTrees[, `:=`(shape, "rectangle")][Feature == "Leaf", `:=`(shape,
"egg")]
allTrees[, `:=`(filledcolor, "Beige")][Feature == "Leaf",
`:=`(filledcolor, "Khaki")]
nodes <- DiagrammeR::create_node_df(n = length(allTrees[,
ID] %>% rev), label = allTrees[, label] %>% rev, style = "filled", width=1.5,
color = "DimGray", fillcolor = allTrees[, filledcolor] %>%
rev, shape = allTrees[, shape] %>% rev, data = allTrees[,
Feature] %>% rev, fontname = "Helvetica", fontcolor="black")
edges <- DiagrammeR::create_edge_df(from = match(allTrees[Feature !=
"Leaf", c(ID)] %>% rep(2), allTrees[, ID] %>% rev), to = match(allTrees[Feature !=
"Leaf", c(Yes, No)], allTrees[, ID] %>% rev), label = allTrees[Feature !=
"Leaf", paste("<", Split)] %>% c(rep("", nrow(allTrees[Feature !=
"Leaf"]))), color = "DimGray", arrowsize = 1, arrowhead = "vee", minlen="5",
fontname = "Helvetica", rel = "leading_to", fontsize="15")
graph <- DiagrammeR::create_graph(nodes_df = nodes, edges_df = edges, attr_theme=NULL)
DiagrammeR::render_graph(graph, width = plot_width, height = plot_height)
return(graph)
}
这篇关于R中的xgb.plot.tree布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!