【问题标题】:Using mob() trees (partykit package) with logistic() model将 mob() 树(partykit 包)与logistic() 模型一起使用
【发布时间】:2021-04-14 03:22:18
【问题描述】:

我正在尝试将基于模型的递归分区 (MOB) 与 mob() 函数(来自 partykit 包)一起使用,以根据使用logistic() 回归找到的最佳分区来获取与每个功能相关的不同参数(glm-二项式)函数。我必须定义我的模型。

按照第 7 页上的示例:https://cran.r-project.org/web/packages/partykit/vignettes/mob.pdf 我创建了一个 logit 函数来估计值并返回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")

有什么线索吗?

谢谢你:)

【问题讨论】:

    标签: r machine-learning tree regression party


    【解决方案1】:

    显然,问题与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 参数的描述和“详细信息”部分。
    • 感谢您的提示,@AchimZeileis!我不知道,这是一个非常有用的功能。
    【解决方案2】:

    在您的mob() 调用中,您的formula 仅右侧有一个y ~ z 类型 - 而不是在y ~ x | z 类型的右侧有一个两部分模型。 z 变量是用于树中拆分/分区的变量,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
    

    【讨论】:

      猜你喜欢
      • 2016-08-30
      • 2020-12-15
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-28
      • 2012-10-30
      • 1970-01-01
      相关资源
      最近更新 更多