将 mob() 树(partykit 包)与 logistic() 模型一起使用

Using mob() trees (partykit package) with logistic() model

我正在尝试将基于模型的递归分区 (MOB) 与 mob() 函数(来自 partykit 包)结合使用,以根据使用 logistic( ) 回归(glm-二项式)函数。我必须定义我的模型。

按照第 7 页上的这个示例:https://cran.r-project.org/web/packages/partykit/vignettes/mob.pdf 我创建了一个估计值的 logit 函数,并将 return logistic() 函数的估计值等。 不过函数的定义好像不太对。

library(partykit)
logit_func <- function(y, x, start = NULL, weights = NULL, offset = NULL, ...) {
  glm(y ~ 0 + x, family = binomial, start = start, ...)
}

p <- mob(future~., data=sample, fit = logit_func)

...并出现以下错误

Error in model.frame.default(formula = y ~ 0 + x, drop.unused.levels = TRUE) : 
  invalid type (NULL) for variable 'x' 

样本数据框如下:

sample <- structure(list(future = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L), .Label = c("0", "1"), class = "factor"), HHk = c(0.412585987717856, 
1, 1, 1, 1, 1, 1, 1, 0.865684350743137, 0.685221125225357), HHd = c(0.529970735028671, 
1, 1, 1, 0.611295754192343, 0.171910197073699, 0.722887386610618, 
0.457585763978574, 0.517888089662373, 0.401285262785306), via_4 = structure(c(1L, 
2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("0", "1"), class = "factor"), 
    region_5 = structure(c(1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L), .Label = c("0", "1"), class = "factor")), row.names = c(NA, 
10L), class = "data.frame")

有线索吗?

谢谢:)

显然,问题与 partykit::mob 中的选项 formula 有关。我不知道您想要哪种模型,但您没有指定任何分区变量 (Z)。以下工作,但没有发现任何中断。我认为这是因为数据集太小了。

拟合模型假设您正在拟合一个模型,其中 HHk 是您的回归量并且 HHd 被用作分区变量。

p <- mob(formula = future ~ HHk  | HHd ,
         data=sample,
         fit = logit_func)

# Model-based recursive partitioning (logit_func)
# 
# Model formula:
#   future ~ HHk | HHd
# 
# Fitted party:
#   [1] root: n = 10
# x(Intercept)         xHHk 
# -1.386266     2.006611  
# 
# Number of inner nodes:    0
# Number of terminal nodes: 1
# Number of parameters per node: 2
# Objective function: 6.557608

在您的 mob() 调用中,您的 formula 只有一个右侧类型 y ~ z - 而不是右侧有一个两部分模型类型 y ~ x | zz 变量是树中用于 splitting/partitioning 的变量,x 变量是模型中用作回归量的变量。 (正如 Álvaro 在回复中所指出的那样。)

原则上,没有任何回归器是可以的,你可以简单地使用常量拟合(即截距模型)。但是,您定义的 logit_func() 没有捕捉到这种情况。可以通过三种方法解决此问题:

  1. 抓住logit_func()里面的if(is.null(x))然后用glm(y ~ 1, ...).

  2. 保持 logit_func() 不变,并明确指定截距的回归:mob(future ~ 1 | ., data=sample, fit = logit_func).

  3. 使用专用的glmtree()函数而不是一般的mob()加手工logit_func():glmtree(future ~ ., data = sample, family = binomial).

这三者都将导致同一棵树,但强烈推荐策略 3,原因有很多:(a) 它很容易获得,不需要创建自定义代码。 (b) 内部使用的拟合函数在计算上更有效(例如,避免重复的公式解析等)。 (c) 有更好的方法可用于结果树,例如,更好的 plot()predict() 方法中的更多选项。

此外,将一些解释变量视为回归变量,将其他解释变量视为分裂变量可能是有意义的(正如 Álvaro 所建议的)。但这取决于数据和应用案例,没有进一步的背景很难提出建议。

您的 sample 数据的结果如下所示。当然,在这个小数据集上没有发现分割,但在完整数据集上它应该按预期工作。

p <- glmtree(future ~ ., data = sample, family = binomial)
p
## Generalized linear model tree (family: binomial)
## 
## Model formula:
## future ~ 1 | .
## 
## Fitted party:
## [1] root: n = 10
##     (Intercept) 
##       0.4054651  
## 
## Number of inner nodes:    0
## Number of terminal nodes: 1
## Number of parameters per node: 1
## Objective function (negative log-likelihood): 6.730117