基于模型的分区"two-layer interaction"(分段模型)

Model-based partitioning with "two-layer interaction" (segmented models)

我正在尝试构建一个类型为 "two-layer interaction" 的基于模型的树,其中树节点中的模型再次被分割。

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

在下面的示例中,ab 的函数,ab 之间的关系取决于 db | 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()lmtree()fit 函数?

不是,但是是 ;-)

lmtree() 不能轻易用作 mob().

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

  2. 即使解决维度问题或通过总是强制中断来解决它,也需要更多工作来设置正确的系数向量、估计函数矩阵等。这也是并不简单,因为如果给定断点(例如,对于二进制因子)或必须估计(例如对于您的数字变量 b)。

    ,收敛速度(以及推理)是不同的
  3. 你设置你的fit()函数的方式,里面的lmtree()不知道去哪里找b。它只有一个数字向量 y 和一个数字矩阵 x 但不是原始数据。

但是是的,我认为如果将视图从拟合 "two-layer" 树更改为拟合 "segmented" 模型,所有这些问题都可以得到解决一棵树里面。我的印象是您想拟合一个模型 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() 等的提取器。因此,流氓功能很简单:

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

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

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

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

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

有关基本方法论背景,请参阅:Muggeo VMR (2003)。 "Estimating Regression Models with Unknown Break-Points." 医学统计学, 22(19), 3055-3071。 doi:10.1002/sim.1545