You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于模型的两层交互分段树构建:mob()与lmtree()适配问题

我来帮你搞定这个带“两层交互”的模型树问题!你遇到的参数兼容问题,核心是mob()和lmtree()的定位差异——lmtree()是专门为线性模型打造的模型树工具,而mob()是通用框架,需要自定义拟合函数适配它的接口。下面我用可复现的例子一步步给你解决:

先补全可复现的数据集

首先我把你没写完的数据集补全,模拟a和b的关系依赖d以及b的分段情况:

library("partykit")
set.seed(321)
b <- runif(200)
d <- sample(1:2, 200, replace = TRUE)
# 构造a:d=1时a和b正相关;d=2时,b<0.5则负相关,b>=0.5则正相关
a <- ifelse(d == 1,
            2*b + rnorm(200, sd=0.1),
            ifelse(b < 0.5,
                   -3*b + rnorm(200, sd=0.1),
                   3*(b - 0.5) + rnorm(200, sd=0.1)))
dat <- data.frame(a, b, d)

方案1:用lmtree()直接实现两层交互(推荐)

因为你是线性模型场景,lmtree()是mob()的线性模型专用封装,完全能满足你的“两层交互”需求,而且不需要自定义函数。

比如你想先按d分裂树,再在每个节点内对b进行分段拟合,直接用公式语法就能实现:

# 公式含义:以d作为树的分裂变量,每个节点内拟合a~b的线性模型
tree1 <- lmtree(a ~ b | d, data = dat)
plot(tree1)
summary(tree1)

如果想让树自动选择分裂变量(比如先分裂b再分裂d,或者反过来),只需要调整公式里的分裂变量部分:

# 让树自动在b和d中选择分裂变量,实现多层交互
tree2 <- lmtree(a ~ b + d | b + d, data = dat)
plot(tree2)
summary(tree2)

方案2:自定义拟合函数适配mob()

如果你必须用mob()(比如要适配非线性模型),需要给它一个符合要求的拟合函数——这个函数要返回包含对数似然、系数、协方差矩阵的模型对象,还要支持logLik()、coef()、vcov()这些方法。

针对线性模型,我写一个适配的函数:

# 自定义线性模型拟合函数,给mob用
lm_mob <- function(formula, data, ...) {
  mod <- lm(formula, data = data, ...)
  # mob需要模型有明确的loglik属性,所以手动加上
  attr(mod, "loglik") <- as.numeric(logLik(mod))
  return(mod)
}

# 用mob构建模型树,指定拟合函数为我们写的lm_mob
tree3 <- mob(a ~ b | d, data = dat, fit = lm_mob)
plot(tree3)
summary(tree3)

关键提醒

  • 线性模型场景优先用lmtree(),它已经帮你封装好了所有适配mob()的细节,不用自己写函数。
  • 如果用mob(),自定义拟合函数必须满足:能接收formula和data参数,返回的模型对象能被logLik()、coef()、vcov()提取信息——这是mob()计算分裂准则的核心依据。

内容的提问来源于stack exchange,提问作者MassCorr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:13:12