partykit minsize 选项删除超过 minsize 的分支

partykit minsize option drops branches that exceed minsize

我正在使用 partykit 中的 lmtree() 函数使用线性回归对数据进行分区。回归使用权重,我想确保每个分支都有一个最小总权重,我用 minsize 选项指定。例如,在下面的示例中,树只有两个分支而不是三个分支,因为 x1=="C" 的权重太小而无法位于其自己的分支中。

n <- 100
X <- rbind(
  data.frame(TT=1:n, x1="A", weight=2, y=seq(1,l=n,by=0.2)+rnorm(n,sd=.2)),
  data.frame(TT=1:n, x1="B", weight=2, y=seq(1,l=n,by=0.4)+rnorm(n,sd=.2)),
  data.frame(TT=1:n, x1="C", weight=1, y=seq(1,l=n,by=0.6)+rnorm(n,sd=.2))
)
X$x1 <- factor(X$x1)
tr <- lmtree(y ~ TT | x1, data=X, weight=weight, minsize=150)

Fitted party:
[1] root
|   [2] x1 in A: n = 200
|       (Intercept)          TT 
|         0.7724903   0.2002023 
|   [3] x1 in B, C: n = 300
|       (Intercept)          TT 
|         0.5759213   0.4659592 

我也有一些现实世界的数据,不幸的是这些数据是机密的,但导致了一些我不理解的行为。当我做 not 指定 minsize 时,它构建了一个有 30 个分支的树,其中每个分支的总权重 n 是一个很大的数字。但是,当我指定一个 minsize 远低于第一棵树的每个分支的总重量时,结果是一棵分支更少的新树。我根本没想到树会发生变化,因为 minsize 似乎没有约束力。这个结果有什么解释吗?

更新

提供示例

n <- 100
X <- rbind(
  data.frame(TT=1:n, x1=runif(n, 0.0, 0.3), weight=2, y=seq(1,l=n,by=0.2)+rnorm(n,sd=.2)),
  data.frame(TT=1:n, x1=runif(n, 0.3, 0.7), weight=2, y=seq(1,l=n,by=0.4)+rnorm(n,sd=.2)),
  data.frame(TT=1:n, x1=runif(n, 0.7, 1.0), weight=1, y=seq(1,l=n,by=0.6)+rnorm(n,sd=.2))
)
tr <- lmtree(y ~ TT | x1, data=X, weights = weight)

Fitted party:
[1] root
|   [2] x1 <= 0.29787: n = 200
|       (Intercept)          TT 
|         0.8431985   0.1994021 
|   [3] x1 > 0.29787
|   |   [4] x1 <= 0.69515: n = 200
|   |       (Intercept)          TT 
|   |         0.6346980   0.3995678 
|   |   [5] x1 > 0.69515: n = 100
|   |       (Intercept)          TT 
|   |         0.4792462   0.5987472 

现在让我们设置minsize=150。即使 x1 <= 0.3x1 > 0.3 可以工作,树也不再有任何分裂。

tr <- lmtree(y ~ TT | x1, data=X, weights = weight, minsize=150)

Fitted party:
[1] root: n = 500
    (Intercept)          TT 
      0.6870078   0.3593374

mob()lmtree() 的基础设施)中应用的两条规则在这种情况下很重要,可以从更明确的讨论中获益:

  • 如果 mob() 在任何阶段选择一个分裂变量,然后不会导致单个可接受的分裂(根据最小节点大小),那么分裂会在该点停止。这与 ctree() 相反,如果检测到重要测试,它总是执行拆分 - 即使第二好的变量不重要。对此提供更精细的控制可能会很好 - 我们将其列入我们即将对软件包进行修订的愿望清单。

  • 默认情况下,weights 被解释为个案权重,即,mob() 认为有 w 个独立观察与给定观察相同。因此,观察的数量是权重的总和。但请注意,这也会影响样本量增加的显着性检验!

至于你的主要问题:没有任何可重现的例子很难给出解释。我同意 partykit 应该按照你描述的方式行事 - 但也许有一个重要但不是很明显的细节你还没有注意到......如果你能想出一个 small/simple 复制问题的人工数据集。

更新

正如评论中已经指出的那样:感谢您更新问题中的可重现示例。这帮助我找到了 mob() 中处理案例权重的错误。在存在案例权重的情况下,检验统计量的计算存在错误,从而导致不正确的拆分变量选择和停止标准。我刚刚修复了这个错误,新的 partykit 开发版本可以从 R-Forge https://r-forge.r-project.org/R/?group_id=261 获得。 (但是请注意,R-Forge 目前只为 R 3.3.x 构建 Windows 二进制文件。如果使用更新的 Windows 版本,请使用 type = "source"安装源码包 - 并确保安装了必要的 Rtools。)

在您的示例中,我只是设置了一个随机种子以实现精确的再现性。加权数据设置为:

set.seed(1)
n <- 100
X <- rbind(
  data.frame(TT=1:n, x1=runif(n, 0.0, 0.3), weight=2, y=seq(1,l=n,by=0.2)+rnorm(n,sd=.2)),
  data.frame(TT=1:n, x1=runif(n, 0.3, 0.7), weight=2, y=seq(1,l=n,by=0.4)+rnorm(n,sd=.2)),
  data.frame(TT=1:n, x1=runif(n, 0.7, 1.0), weight=1, y=seq(1,l=n,by=0.6)+rnorm(n,sd=.2))
)

那么加权树就可以像之前一样进行拟合了。在此特定示例中,树结构不受影响,但每个节点中参数不稳定性测试的测试统计信息和 p 值发生了一些变化:

library("partykit")
tr1 <- lmtree(y ~ TT | x1, data = X, weights = weight)
plot(tr1)

添加 minsize = 150 参数现在具有避免在节点 3 中拆分的预期效果。

tr2 <- lmtree(y ~ TT | x1, data = X, weights = weight, minsize = 150)
plot(tr2)

为了检查后者是否确实做了正确的事情,我们将其与明确扩展数据的树进行比较。因此,由于这里的数据被视为案例权重,我们可以通过重复权重大于 1 的那些观察来膨胀数据集。

Xw <- X[rep(1:nrow(X), X$weight), ]
tr3 <- lmtree(y ~ TT | x1, data = Xw, minsize = 150)

结果系数相同(直到非常小的数值差异):

all.equal(coef(tr2), coef(tr3))
## [1] TRUE

而且,更重要的是,节点中的所有测试统计数据和 p 值也相同:

library("strucchange")
all.equal(sctest(tr2), sctest(tr3))
## [1] TRUE