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.3
和 x1 > 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
我正在使用 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.3
和 x1 > 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