【问题标题】:Model-based partitioning with "two-layer interaction" (segmented models)具有“两层交互”的基于模型的分区(分段模型)
【发布时间】:2018-04-09 08:06:19
【问题描述】:

我正在尝试构建具有“双层交互”类型的基于模型的树,其中树的节点中的模型再次被分割。

我正在使用mob() 函数来达到这个目的,但我无法使fit 函数的参数与lmtree() 函数一起工作。

在以下示例中,a 是 b 的函数,a 和 b 之间的关系取决于 d 和 b | d。

library("partykit")
set.seed(321)

b <- runif(200)
d <- sample(1:2, 200, replace = TRUE)
a <- jitter(ifelse(d == 1, 2 * b - 1, 4 * b - 1.2), amount = .1)
a[b < .5 & d == 1] <- jitter(rep(0, length(a[b < .5 & d == 1])))
a[b < .3 & d == 2] <- jitter(rep(0, length(a[b < .3 & d == 2])))

fit <- function(y, x, start = NULL, weights = NULL, offset = NULL, ..., estfun = FALSE, object = FALSE)
{   
  x <- x[, 2]
  l <- lmtree(y ~ x | b)
  return(l)
}   

m <- mob(a ~ b | d, fit = fit) # not working

当然,通过这个简单的示例,我可以使用lmtree(a ~ b | d + b) 来查找每个交互,但是有没有办法将mob() 的fit 函数用作lmtree()?

【问题讨论】:

    标签: r tree partitioning party


    【解决方案1】:

    没有,但有;-)

    否,lmtree() 不能轻易用作mob() 的装配工。

    1. 内层树(lmtree())的维度不是固定的,也就是说,你可能会得到一棵没有任何分区或有很多子组的树,这会混淆外层树(mob()) .

    2. 1234563如果给定断点(例如,对于二元因子)或必须估计断点(例如对于您的数字变量b),则收敛速度(以及因此推断)是不同的。
    3. 你设置fit()函数的方式,内部的lmtree()不知道去哪里找b。它只有一个数字向量y 和一个数字矩阵x,但没有原始数据。

    但是是的,我认为如果将视图从拟合“两层”树更改为在树中拟合“分段”模型,所有这些问题都可以解决。我的印象是,您想要拟合一个模型y ~ x(或您的示例中的a ~ b),其中使用分段线性函数和x 中的附加断点。如果分段线性函数在x 中应该是连续的,那么segmented 包可以很容易地使用。如果没有,那么可以利用strucchange。假设您想要前者(因为您已经像这样模拟了您的数据),我在下面包含了一个有效的 segmented 示例(并且还稍微修改了您的问题以反映这一点)。

    稍微更改名称和代码,您的数据d 具有y ~ x 的分段分段线性关系,其系数取决于组变量g。

    set.seed(321)
    d <- data.frame(
      x = runif(200),
      g = factor(sample(1:2, 200, replace = TRUE))
    )
    d$y <- jitter(ifelse(d$g == "1",
      pmax(0, 2 * d$x - 1),
      pmax(0, 4 * d$x - 1.2)
    ), amount = 0.1)
    

    然后,我可以在树的每个节点中拟合一个模型 segmented(lm(y ~ x)),它带有适用于 coef()、logLik()、estfun() 等的提取器。因此,mobster 函数很简单:

    segfit <- function(y, x, start = NULL, weights = NULL, offset = NULL, ...)
    {
      x <- as.numeric(x[, 2])
      segmented::segmented(lm(y ~ x))
    }
    

    (注意:我还没有尝试过segmented() 是否也支持带有weights 和offset 的lm() 对象。)

    有了这个我们可以得到完整的树,在这个基本的例子中简单地分裂成g:

    library("partykit")
    segtree <- mob(y ~ x | g, data = d, fit = segfit)
    plot(segtree, terminal_panel = node_bivplot, tnex = 2)
    

    segmented 的实践介绍可在:Muggeo VMR (2008) 中找到。 “segmented:用于拟合具有断线关系的回归模型的 R 包。” R 新闻,8(1),20-25。 https://CRAN.R-project.org/doc/Rnews/

    有关基本方法背景,请参阅:Muggeo VMR (2003)。 “估计具有未知断点的回归模型。” 医学统计学,22(19),3055-3071。 doi:10.1002/sim.1545

    【讨论】:

    • 谢谢 :-) 我真的很惊讶把它放在一起是多么容易!但是 Vito 的segmented 非常友好,可以提供我们所需的所有构建块。现在我很想知道它在真实数据中的表现如何......
    • 谢谢@AchimZeileis。实际上,我一开始就使用了这种方法(适合的分段函数)。但我放弃了我的真实数据,因为它需要几天时间才能运行......无论如何,再次感谢您的帮助。
    • @MassCorr mob(y ~ x | ..., fit = segtree) 与 lmtree(y ~ x | ...) 的时间问题是否完全不同?如果后者也需要很长时间,那么可能需要粗化一些回归量或因子以减轻分裂点搜索、增加最小分段大小、限制树深度等。
    • @AchimZeileis mob + segmented 比 lmtree 花费更多时间
    • 好的,我明白了。大约是多少?可能有人可以使用起始值等。也许可以进行一些加速。询问 Vito 也可能会有所帮助...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 2014-08-05
    • 2019-10-13
    • 2018-09-11
    • 2013-08-21
    相关资源
    最近更新 更多