我试图使用R中的“rpart”包来构建生存树,并希望使用此树来预测其他观测值。我知道有很多关于rpart和预测的SO问题,但是我没有找到任何一个解决使用“Surv”对象与rpart一起使用时(我认为)特定的问题。
我的特定问题涉及解释“predict”函数的结果。以下是一个示例:
到目前为止一切都很好。我对这里正在发生的事情的理解是rpart试图将指数生存曲线拟合到我的数据子集上。基于这个理解,我认为当我调用
这似乎正是我想要的。对于每个观察值(或任何新的观察值),我可以获得在给定时间点预测该观察值存活/死亡的概率。(编辑:我意识到这可能是一个误解——这些曲线并不给出存活/死亡的概率,而是在一段时间间隔内生存下来的概率。不过,这并不影响下面描述的问题。) 然而,当我尝试使用指数公式时...
我的特定问题涉及解释“predict”函数的结果。以下是一个示例:
library(rpart)
library(OIsurv)
# Make Data:
set.seed(4)
dat = data.frame(X1 = sample(x = c(1,2,3,4,5), size = 1000, replace=T))
dat$t = rexp(1000, rate=dat$X1)
dat$t = dat$t / max(dat$t)
dat$e = rbinom(n = 1000, size = 1, prob = 1-dat$t )
# Survival Fit:
sfit = survfit(Surv(t, event = e) ~ 1, data=dat)
plot(sfit)
# Tree Fit:
tfit = rpart(formula = Surv(t, event = e) ~ X1 , data = dat, control=rpart.control(minsplit=30, cp=0.01))
plot(tfit); text(tfit)
# Survival Fit, Broken by Node in Tree:
dat$node = as.factor(tfit$where)
plot( survfit(Surv(dat$t, event = dat$e)~dat$node) )
到目前为止一切都很好。我对这里正在发生的事情的理解是rpart试图将指数生存曲线拟合到我的数据子集上。基于这个理解,我认为当我调用
predict(tfit)
时,对于每个观察值,我会得到一个与该观察值的指数曲线相关的参数。例如,如果predict(fit)[1]
是0.46,则这意味着对于原始数据集中的第一个观测值,曲线由方程P(s) = exp(−λt)
给出,其中λ=0.46
。这似乎正是我想要的。对于每个观察值(或任何新的观察值),我可以获得在给定时间点预测该观察值存活/死亡的概率。(编辑:我意识到这可能是一个误解——这些曲线并不给出存活/死亡的概率,而是在一段时间间隔内生存下来的概率。不过,这并不影响下面描述的问题。) 然而,当我尝试使用指数公式时...
# Predict:
# an attempt to use the rates extracted from the tree to
# capture the survival curve formula in each tree node.
rates = unique(predict(tfit))
for (rate in rates) {
grid= seq(0,1,length.out = 100)
lines(x= grid, y= exp(-rate*(grid)), col=2)
}
我所做的是按照生存树的方式将数据集分割,然后使用survfit
为每个分区绘制非参数曲线。这就是黑色线条。我还画了对应于将“速率”参数(我认为)插入到(我认为)生存指数公式中的结果的线条。
我知道非参数拟合和参数拟合不一定相同,但这似乎不仅如此:我似乎需要缩放我的X变量或其他操作。
基本上,我似乎不理解rpart/survival在内部使用的公式。有谁能帮我从(1)rpart模型转换到(2)任意观测值的生存方程?
survfit()
和基于$where
的因子进行计算 - 或者通过type =“prob”
使用partykit来计算。如果您想在每个叶子中拟合参数模型(例如指数或Weibull),则可以使用survreg()
而不是survfit()
。 - Achim Zeileispredict(tfit2, type = "prob")[[1]]
提取了第一个观测值的拟合survfit
对象。从中,您可以提取所有您喜欢的“通常”数量。例如,查看对象的summary()
,它会向您显示完整的Kaplan-Meier曲线坐标以及其他几个附加信息。 - Achim Zeileissurvfit
和survival
的问题,对此有很多有用的书籍、教程等。但是我认为,如果您执行以下操作:km1 <- predict(tfit2, type = "prob")[[1]]
,然后summary(km1)
,您应该会看到您需要的一切。您可以轻松地从中获取分位数,例如quantile(km1, c(0.2, 0.5, 0.8))
,它会给出S(t)分别为0.8、0.5和0.2的时间。或者,如果您想要一个函数,您可以执行km1f <- approxfun(km1$time, km1$surv)
,然后执行km1f(c(0.011, 0.037, 0.094))
等。 - Achim Zeileis