r中的xgb.plot.tree布局

问题描述 投票:3回答:1

我正在读取一个xgb notebook和xgb.plot.tree命令,例如结果如下:enter image description here

然而,当我做同样的事情时,我得到了这样的图片,这是两个单独的图形和不同的颜色。

enter image description here

这是正常的吗?两张图是两棵树吗?

r xgboost ensemble-learning
1个回答
4
投票

我有同样的问题。根据xgboost github存储库中的一个问题案例,这可能是由于xgboost用于渲染树的DiagrammeR库的更改。 https://github.com/dmlc/xgboost/issues/2640

我没有使用diagrammeR命令修改dgr_graph对象,而是选择创建一个新版本的函数xgb.plot.tree,它直接定义节点的字体颜色。在fontcolor="black"线中添加参数nodes <- DiagrammeR::create_node_df就足够了

    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模型的第一个树。

    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)
}
© www.soinside.com 2019 - 2024. All rights reserved.