【问题标题】:xgb.plot.tree layout in rr中的xgb.plot.tree布局
【发布时间】:2017-08-06 08:38:49
【问题描述】:

我正在阅读 xgb notebook,示例中的 xgb.plot.tree 命令会生成如下图片:

但是,当我做同样的事情时,我得到了一张这样的照片,它是两个独立的图表,颜色也不同。

这正常吗?这两个图是两棵树吗?

【问题讨论】:

    标签: r xgboost ensemble-learning


    【解决方案1】:

    我也有同样的问题。 根据 xgboost github 存储库上的一个问题案例,这可能是由于 xgboost 用于渲染树的 DiagrammeR 库发生了变化。 https://github.com/dmlc/xgboost/issues/2640

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

        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)
    }
    

    【讨论】:

    • 干得好!一年过去了,原来的功能还是不稳定..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 2019-03-24
    • 2022-10-14
    • 2017-04-17
    • 2021-12-23
    相关资源
    最近更新 更多