我正在尝试构建一个基于模型的树,其类型为“两层交互”,其中树的节点中的模型再次被分段。
我正在使用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)
来找到每个交互,但有没有办法用fit
mob()
的lmtree()
函数?
不,但是;-)
不,lmtree()
不能轻易用作mob()
的装配工。
lmtree()
)的维度不固定,即,你可能得到一棵没有任何分区或有许多子组的树,这对于外树(mob()
)来说会令人困惑。b
),推理)是不同的。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()
等的提取器。因此,流氓功能很简单:
segfit <- function(y, x, start = NULL, weights = NULL, offset = NULL, ...)
{
x <- as.numeric(x[, 2])
segmented::segmented(lm(y ~ x))
}
(注意:我还没有尝试过,segmented()
是否也支持使用lm()
和weights
的offset
对象。)
有了这个,我们可以获得在这个基本示例中简单地在g
中拆分的完整树:
library("partykit")
segtree <- mob(y ~ x | g, data = d, fit = segfit)
plot(segtree, terminal_panel = node_bivplot, tnex = 2)
有关segmented
的实用介绍可参见:Muggeo VMR(2008)。 “分段:适合具有折线关系的回归模型的R包。” R News,8(1),20-25。 https://CRAN.R-project.org/doc/Rnews/
对于基础方法背景,请参阅:Muggeo VMR(2003)。 “估算具有未知断点的回归模型。”医学统计,22(19),3055-3071。 doi:10.1002/sim.1545