带有partykit的自定义拆分规则
以下是这个问题: 我非常感兴趣的工具,可以处理树生长与定制的标准,这样我可以测试不同的模型 我尝试使用partykit R软件包来生长一棵树,其拆分规则由Cox模型的负对数似然(在Cox模型的情况下为对数准似然)给出,并且在每个叶中拟合一个Cox模型 正如我在阅读关于MOB函数的小插曲时所理解的,有两种方法可以实现我自己的分割标准,即获取fit函数返回列表或模型对象 出于我的目的,我尝试了这两种解决方案,但都失败了 解决方案1:返回列表对象: 我以“暴民”小插曲中的“乳腺癌数据集”为例 我试过这个:带有partykit的自定义拆分规则,r,split,tree,party,R,Split,Tree,Party,以下是这个问题: 我非常感兴趣的工具,可以处理树生长与定制的标准,这样我可以测试不同的模型 我尝试使用partykit R软件包来生长一棵树,其拆分规则由Cox模型的负对数似然(在Cox模型的情况下为对数准似然)给出,并且在每个叶中拟合一个Cox模型 正如我在阅读关于MOB函数的小插曲时所理解的,有两种方法可以实现我自己的分割标准,即获取fit函数返回列表或模型对象 出于我的目的,我尝试了这两种解决方案,但都失败了 解决方案1:返回列表对象: 我以“暴民”小插曲中的“乳腺癌数据集”为例 我试过这
cox1 = function(y,x, start = NULL, weights = NULL, offset = NULL, ...,
estfun = FALSE, object = TRUE){
res_cox = coxph(formula = y ~ x )
list(
coefficients = res_cox$coefficients,
objfun = - res_cox$loglik[2],
object = res_cox)
}
mob(formula = Surv(time, cens) ~ horTh + pnodes - 1 | age + tsize + tgrade + progrec +
estrec + menostat ,
data = GBSG2 ,
fit = cox1,
control = mob_control(alpha = 0.0001) )
cox2 = function(y,x, start = NULL, weights = NULL, offset = NULL, ... ){
res_cox = coxph(formula = y ~ x )
}
logLik.cox2 <- function(object, ...)
structure( - object$loglik[2], class = "logLik")
mob(formula = Surv(time, cens) ~ horTh + pnodes - 1 | age + tsize + tgrade + progrec +
estrec + menostat ,
data = GBSG2 ,
fit = cox2,
control = mob_control(alpha = 0.0001 ) )
有一个关于X矩阵奇异性的警告,mob函数是一个只有一个节点的树(即使alpha值较小)
请注意,运行coxph函数时,X矩阵没有奇异性问题:
res_cox = coxph( formula = Surv(time, cens) ~ horTh + pnodes ,
data = GBSG2 )
解决方案2:返回一个coxph.object:
我试过这个:
cox1 = function(y,x, start = NULL, weights = NULL, offset = NULL, ...,
estfun = FALSE, object = TRUE){
res_cox = coxph(formula = y ~ x )
list(
coefficients = res_cox$coefficients,
objfun = - res_cox$loglik[2],
object = res_cox)
}
mob(formula = Surv(time, cens) ~ horTh + pnodes - 1 | age + tsize + tgrade + progrec +
estrec + menostat ,
data = GBSG2 ,
fit = cox1,
control = mob_control(alpha = 0.0001) )
cox2 = function(y,x, start = NULL, weights = NULL, offset = NULL, ... ){
res_cox = coxph(formula = y ~ x )
}
logLik.cox2 <- function(object, ...)
structure( - object$loglik[2], class = "logLik")
mob(formula = Surv(time, cens) ~ horTh + pnodes - 1 | age + tsize + tgrade + progrec +
estrec + menostat ,
data = GBSG2 ,
fit = cox2,
control = mob_control(alpha = 0.0001 ) )
cox2=函数(y,x,start=NULL,weights=NULL,offset=NULL,…){
res_cox=coxph(公式=y~x)
}
logLik.cox2您设置的cox1()
和linear\u reg()
函数的问题在于您没有提供估算函数。由于这些是选择分割变量的推理的基础,如果不提供这些参数,则算法根本不会分割。有关此问题的一些讨论,请参阅最近的文章
但是对于coxph()。因此,您的cox2()
方法更容易实现
后者不能正常工作的原因是coxph()
中对截取的特殊处理。在内部,这总是强制截距进入模型,但随后从设计矩阵中忽略第一列。当通过mob()
与此接口时,您需要小心不要弄糟它,因为mob()
设置了自己的模型矩阵。由于排除了拦截,mob()
认为它可以估计horTh
的两个级别。但事实并非如此,因为在Cox-PH模型中未确定截距
在这种情况下(IMO)的最佳解决方案是:让mob()
设置一个截取,但在将模型矩阵传递给coxph()
时再次排除它。由于生成的对象有coef()
、logLik()
和estfun()
方法,因此可以使用cox2()
函数的简单设置
软件包和数据:
library("partykit")
library("survival")
data("GBSG2", package = "TH.data")
拟合函数:
cox <- function(y, x, start = NULL, weights = NULL, offset = NULL, ... ) {
x <- x[, -1]
coxph(formula = y ~ 0 + x)
}
谢谢你的帮助,我一直在用它,我也去了你去过的地方。我的问题是该函数没有提供任何分割:就像你的例子一样,我通过不分割得到一个内部节点。在cox()的规范中是否有我遗漏的东西?或者我需要调整分区控件吗?可能没有检测到明显的分割。这是基于Cox的树经常遇到的问题。原因似乎是Cox模型中(未指定)的基线风险可以吸收如此多的异质性。即使检测到分裂,也会使用两个完全不确定/灵活的独立基线危险,这在许多情况下是致命的。相反,我通常更喜欢使用参数生存模型,其中一些参数用于基线风险,例如威布尔模型。关于一个有效的示例,请参见《小插曲》(“mob”,package=“partykit”)
中的第4.5节。是的,这就是问题所在。我没有意识到模型中包含了默认的Bonferroni校正,所以当一个像mob(Surv(t,e)~x|a+b)
这样的模型找到了结果,但是mob(Surv(t,e)~x|a+b+c+d)
我不认为有问题,但当我关闭校正时,我得到了可复制的结果(c和d被作为变量吸进)。谢谢
mb <- mob(formula = Surv(time, cens) ~ horTh + pnodes | age + tsize + tgrade + progrec + estrec + menostat,
data = GBSG2, fit = cox)
mb
## Model-based recursive partitioning (cox)
##
## Model formula:
## Surv(time, cens) ~ horTh + pnodes | age + tsize + tgrade + progrec +
## estrec + menostat
##
## Fitted party:
## [1] root: n = 686
## xhorThyes xpnodes
## -0.35701115 0.05768026
##
## Number of inner nodes: 0
## Number of terminal nodes: 1
## Number of parameters per node: 2
## Objective function: 1758.86