我使用lmtree()
中的partykit
函数来使用线性回归对数据进行分区。回归使用权重,我想确保每个分支具有最小总权重,我使用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
我还有一些真实的数据,遗憾的是这些数据是保密的,但导致了一些我不理解的行为。当我不指定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
答案 0 :(得分:1)
在mob()
(基础架构lmtree()
)中应用的两个规则在此背景下非常重要,可能会受益于更明确的讨论:
如果mob()
在任何阶段选择一个分割变量,然后不会导致单个可允许的分割(就最小节点大小而言),那么分割会在该点停止。这与ctree()
形成对比,weights
如果检测到重要测试则总是执行拆分 - 即使第二个最佳变量不重要。对此提供更细粒度的控制可能会更好 - 我们已将其列入即将修订的软件包的愿望清单。
默认情况下,mob()
被解释为案例权重,即w
认为有partykit
个独立观察与给定观察相同。因此,观察的数量是权重的总和。但请注意,这也会影响样本量增加的显着性检验!
至于你的主要问题:如果没有任何可重复的例子,很难提出解释。我同意mob()
应该按照你描述的方式行事 - 但是也许有一个重要但不那么明显的细节,你还没有注意到......如果你想出来的话会很好一个小/简单的人工数据集,可以复制问题。
正如评论中已经指出的那样:感谢您在更新的问题中提供可重复的示例。这有助于我在处理案例权重时追踪partykit
中的错误。在存在案例权重的情况下计算测试统计量时出现错误,从而导致错误的拆分变量选择和停止标准。我刚刚修复了这个错误,新的type = "source"
开发版本可以从https://r-forge.r-project.org/R/?group_id=261的R-Forge获得。 (但请注意,目前R-Forge仅为R 3.3.x构建Windows二进制文件。如果使用更新的Windows版本,请使用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))
)
安装源程序包 - 并确保您拥有安装必要的Rtools。)
在您的示例中,我只是设置一个随机种子以获得精确的重现性。加权数据设置为:
library("partykit")
tr1 <- lmtree(y ~ TT | x1, data = X, weights = weight)
plot(tr1)
然后可以像以前一样拟合加权树。在此特定示例中,树结构保持不受影响,但每个节点中参数不稳定性测试的测试统计信息和p值会发生变化:
minsize = 150
现在添加tr2 <- lmtree(y ~ TT | x1, data = X, weights = weight, minsize = 150)
plot(tr2)
参数具有避免节点3中的拆分的预期效果。
Xw <- X[rep(1:nrow(X), X$weight), ]
tr3 <- lmtree(y ~ TT | x1, data = Xw, minsize = 150)
要检查后者是否确实做了正确的事情,我们将它与明确扩展数据的树进行比较。因此,由于这里的数据被视为案例权重,我们可以通过重复权重大于1的观察来扩充数据集。
all.equal(coef(tr2), coef(tr3))
## [1] TRUE
得到的系数是相同的(直到非常小的数值差异):
library("strucchange")
all.equal(sctest(tr2), sctest(tr3))
## [1] TRUE
更重要的是,节点中的所有测试统计信息和p值也是相同的:
prompt=login