如何在终端节点中设置不同类型的条形图?
How to set different kind of bar plot in terminal nodes?
我正在运行在数据集上创建 MOB 树,我想修改终端节点中的图。我将使用 MOB 在每个节点中拟合的模型系数的条形图作为我的终端节点。
例如,我 运行 "PimaIndiansDiabetes" 数据集上的 MOB 树 "mlbench" 包。这是代码:
pid_formula <- diabetes ~ glucose | pregnant + pressure + triceps +
insulin + mass + pedigree + age
logit <- function(y, x, start = NULL, weights = NULL, offset = NULL, ...) {
glm(y ~ 0 + x, family = binomial, start = start, ...)
}
pid_tree <- mob(pid_formula, data = PimaIndiansDiabetes, fit = logit)
然后我有每个节点的模型。例如,节点号 2 为 "mass=-9.95+0.058*glucose"。我想根据这些系数制作条形图(例如:节点号 2 为 -9.95 和 0.058),并将这些条形图用作最终树图中的终端节点。知道怎么做吗?提前致谢。
要在 partykit
中实现这样的图形,您必须为 plot()
方法编写一个新的面板函数(或者更确切地说是面板生成函数)。起点可以是 partykit::node_barplot
,它首先提取分类树的拟合概率,然后使用 grid
包绘制它们。相反,您可以使用 coef()
提取估计参数,然后使用 grid
绘制这些参数。有点技术性,但不是很复杂。
但是,我不建议实现这样的功能。原因是这最适合比较同一节点内的不同系数。但由于斜率和截距在完全不同的尺度上,这不容易解释。相反,人们应该更加强调跨节点的 same 系数的差异。这样做的基础也是:
coef(pid_tree)
## x(Intercept) xglucose
## 2 -9.951510 0.05870786
## 4 -6.705586 0.04683748
## 5 -2.770954 0.02353582
另外,可以考虑置信区间的相应标准误差。 (但请记住,这些必须与一粒盐一起使用:它们不会针对估计树进行调整,而是假装终端组是外生给定的。它们仍然可以用作粗略的标准。)我包括一个小的便利功能为此:
confintplot <- function(object, ylim = NULL,
xlab = "Parameter per node", ylab = "Estimate",
main = "", index = NULL, ...)
{
## point estimates and interval
cf <- coef(object)
node <- nodeids(object, terminal = TRUE)
ci <- nodeapply(object, ids = node, FUN = function(n)
confint(info_node(n)$object, ...))
if (!is.null(index)) {
cf <- cf[, index, drop = FALSE]
ci <- lapply(ci, "[", index, , drop = FALSE)
}
cfnm <- rownames(ci[[1L]])
nodenm <- rownames(cf)
## set up dimensions
n <- length(ci)
k <- nrow(ci[[1L]])
at <- t(outer(1:k, seq(-0.15, 0.15, length.out = n), "+"))
## empty plot
if(is.null(ylim)) ylim <- range(unlist(ci))
plot(0, 0, type = "n", xlim = range(at), ylim = ylim,
xlab = xlab, ylab = ylab, main = main, axes = FALSE)
## draw every parameter
for(i in 1L:k) {
arrows(at[,i], sapply(ci, "[", i, 1L), at[,i], sapply(ci, "[", i, 2L),
code = 3, angle = 90, length = 0.05)
points(at[, i], cf[, cfnm[i]], pch = 19, col = "white", cex=1.15)
points(at[, i], cf[, cfnm[i]], pch = nodenm, cex = 0.65)
}
axis(1, at = 1:k, labels = cfnm)
axis(2)
box()
}
使用它我们可以分别为每个参数(截距与斜率)创建一个图。这表明截距在节点间增加,而斜率在减少。
par(mfrow = c(1, 2))
confintplot(pid_tree, index = 1)
confintplot(pid_tree, index = 2)
也可以在公共 y 轴上显示这些。然而,这完全掩盖了坡度因尺度不同而发生的变化:
confintplot(pid_tree)
最后评论:我建议对这种特殊类型的模型使用 glmtree()
而不是 mob()
"by hand"。前者速度更快,并提供一些额外的功能,尤其是易于预测。
我正在运行在数据集上创建 MOB 树,我想修改终端节点中的图。我将使用 MOB 在每个节点中拟合的模型系数的条形图作为我的终端节点。
例如,我 运行 "PimaIndiansDiabetes" 数据集上的 MOB 树 "mlbench" 包。这是代码:
pid_formula <- diabetes ~ glucose | pregnant + pressure + triceps +
insulin + mass + pedigree + age
logit <- function(y, x, start = NULL, weights = NULL, offset = NULL, ...) {
glm(y ~ 0 + x, family = binomial, start = start, ...)
}
pid_tree <- mob(pid_formula, data = PimaIndiansDiabetes, fit = logit)
然后我有每个节点的模型。例如,节点号 2 为 "mass=-9.95+0.058*glucose"。我想根据这些系数制作条形图(例如:节点号 2 为 -9.95 和 0.058),并将这些条形图用作最终树图中的终端节点。知道怎么做吗?提前致谢。
要在 partykit
中实现这样的图形,您必须为 plot()
方法编写一个新的面板函数(或者更确切地说是面板生成函数)。起点可以是 partykit::node_barplot
,它首先提取分类树的拟合概率,然后使用 grid
包绘制它们。相反,您可以使用 coef()
提取估计参数,然后使用 grid
绘制这些参数。有点技术性,但不是很复杂。
但是,我不建议实现这样的功能。原因是这最适合比较同一节点内的不同系数。但由于斜率和截距在完全不同的尺度上,这不容易解释。相反,人们应该更加强调跨节点的 same 系数的差异。这样做的基础也是:
coef(pid_tree)
## x(Intercept) xglucose
## 2 -9.951510 0.05870786
## 4 -6.705586 0.04683748
## 5 -2.770954 0.02353582
另外,可以考虑置信区间的相应标准误差。 (但请记住,这些必须与一粒盐一起使用:它们不会针对估计树进行调整,而是假装终端组是外生给定的。它们仍然可以用作粗略的标准。)我包括一个小的便利功能为此:
confintplot <- function(object, ylim = NULL,
xlab = "Parameter per node", ylab = "Estimate",
main = "", index = NULL, ...)
{
## point estimates and interval
cf <- coef(object)
node <- nodeids(object, terminal = TRUE)
ci <- nodeapply(object, ids = node, FUN = function(n)
confint(info_node(n)$object, ...))
if (!is.null(index)) {
cf <- cf[, index, drop = FALSE]
ci <- lapply(ci, "[", index, , drop = FALSE)
}
cfnm <- rownames(ci[[1L]])
nodenm <- rownames(cf)
## set up dimensions
n <- length(ci)
k <- nrow(ci[[1L]])
at <- t(outer(1:k, seq(-0.15, 0.15, length.out = n), "+"))
## empty plot
if(is.null(ylim)) ylim <- range(unlist(ci))
plot(0, 0, type = "n", xlim = range(at), ylim = ylim,
xlab = xlab, ylab = ylab, main = main, axes = FALSE)
## draw every parameter
for(i in 1L:k) {
arrows(at[,i], sapply(ci, "[", i, 1L), at[,i], sapply(ci, "[", i, 2L),
code = 3, angle = 90, length = 0.05)
points(at[, i], cf[, cfnm[i]], pch = 19, col = "white", cex=1.15)
points(at[, i], cf[, cfnm[i]], pch = nodenm, cex = 0.65)
}
axis(1, at = 1:k, labels = cfnm)
axis(2)
box()
}
使用它我们可以分别为每个参数(截距与斜率)创建一个图。这表明截距在节点间增加,而斜率在减少。
par(mfrow = c(1, 2))
confintplot(pid_tree, index = 1)
confintplot(pid_tree, index = 2)
也可以在公共 y 轴上显示这些。然而,这完全掩盖了坡度因尺度不同而发生的变化:
confintplot(pid_tree)
最后评论:我建议对这种特殊类型的模型使用 glmtree()
而不是 mob()
"by hand"。前者速度更快,并提供一些额外的功能,尤其是易于预测。