Draw a fitted LINAD model as an interactive tree: the partition as a hierarchy, each node's value on its label, and each node's linear coefficients in a table on hover.
Usage
draw_linad(
x,
n_leaves = NULL,
top = 15L,
sort_coefs = TRUE,
direction = "UD",
node_width = 180L,
node_gap = 16L,
level_separation = NULL,
font_size = 14L,
node_labels = TRUE,
show_ncases = TRUE,
show_node_value = TRUE,
show_changes = TRUE,
lo_col = sign_colors()[["negative"]],
mid_col = NULL,
hi_col = sign_colors()[["positive"]],
root_col = NULL,
node_col = NULL,
leaf_col = NULL,
hover_col = NULL,
height = "600px",
theme = NULL,
verbosity = 1L
)Arguments
- x
RegressionorClassificationobject holding a LINAD model, or a fitted LINAD model itself.- n_leaves
Optional Integer: Draw the tree at this size. NULL draws the size selected at training.
- top
Optional Integer: Show this many coefficients per node, largest in absolute value first. NULL shows every one, which on a wide model is neither readable nor quick to render.
- sort_coefs
Logical: If TRUE, order each table by absolute coefficient.
- direction
Character {"UD", "DU", "LR", "RL"}: Tree direction.
- node_width
Integer: Largest node width in pixels. Labels wrap to stay within it, which is what keeps a long feature name from widening a node past the space the layout reserves for it.
- node_gap
Integer: Clear pixels to leave between two boxes on the same level. Separation is computed per pair from the two nodes' own widths, so a narrow node sits close to its neighbor.
- level_separation
Optional Integer: Pixels between levels.
- font_size
Integer: Label font size in pixels.
- node_labels
Logical: If TRUE, label nodes with their rule.
- show_ncases
Logical: If TRUE, include the case count in node labels.
- show_node_value
Logical: If TRUE, include the node's own value in its label.
- show_changes
Logical: If TRUE, mark each coefficient in the node's table with where it came from: a global effect, shared by every leaf, is marked with an identity sign, and one this node changed with a delta. A term with neither was inherited from the parent unchanged. The root carries no marks: it has no parent to differ from.
- lo_col
Character: Color for the most negative coefficient. Defaults to the package-wide negative color, the same one
plot()andplot_manhattan()use on aMassGLM.- mid_col
Optional Character: Color at zero. NULL uses the coefficient table's own background, so a coefficient of no consequence shows as no cell at all.
- hi_col
Character: Color for the most positive coefficient. Defaults to the package-wide positive color.
- root_col
Optional Character: Root node color. NULL follows the theme.
- node_col
Optional Character: Internal node color. NULL follows the theme.
- leaf_col
Optional Character: Terminal node color. NULL follows the theme. Kept off the two ends of the coefficient scale, so a hue in this plot means a coefficient's sign and nothing else.
- hover_col
Optional Character: Border color marking the node the coefficient table belongs to. NULL uses the theme foreground.
- height
Character: CSS height, as a length: a percentage of a container with no height of its own collapses.
- theme
Optional rtemis.draw::Theme: Its background and text colors set the canvas and the foreground. Node fills, the coefficient table and the hover marker all follow them, chosen by the background's luminance so that a custom theme is handled too. NULL uses
rtemis.draw::theme_light(). The two ends of the coefficient scale do not follow it: both ends read on either background, so a sign has the same color under every theme.- verbosity
Integer: If > 0, print messages.
Details
The coefficient tables are the point. A LINAD leaf's coefficients are the accumulated sum along its path, so the same feature can carry a different slope in each region of the data – and sometimes a different sign. That is the model's central interpretive claim, and it is only visible by comparing the table at one node against the table at another. The color scale is therefore diverging and centered on zero, and computed once across every table, so a sign change reads as a color flip.
Each node's label carries node_value, what the tree alone predicts
there, while the table on hover carries what the linear model adds. The
two are separate quantities in a fitted LINAD, so the plot shows them
separately: with node_model = "constant" the tables are empty of slopes and
the node values are the entire model, which is what a plain decision tree
looks like.
The intercept is excluded from the color range. It is typically far larger than any slope and would compress every other coefficient into the middle of the scale.
This is the reference implementation for the LINAD tree plot, built on
visNetwork because a tooltip carrying a real HTML table needs a backend
whose tooltip is an HTML element. Plotly, which every other draw_* uses,
renders hover labels as SVG and cannot express a table at all.
Examples
if (FALSE) { # interactive() && requireNamespace("visNetwork", quietly = TRUE)
x <- data.frame(a = rnorm(300), b = rnorm(300))
x[["y"]] <- 2 * x[["a"]] + ifelse(x[["b"]] < 0, -3, 3) + rnorm(300)
mod <- train(x, hyperparameters = setup_LINAD(max_leaves = 5L))
draw_linad(mod)
}