coxph 用完了迭代并且没有收敛

机器算法验证 r 生存 cox模型
2022-04-05 02:58:51

是的,我已经检查过以前对“用完迭代......”问题的回答并不能解决我的问题。

我有 Firefox 的故障数据,899 个故障和 1395 个(估计的)审查故障。审查都发生在六个开始日和六个结束日(一个版本的初始/最终版本)中的一个。

library(survival)

ff_usage=read.csv("http://www.coding-guidelines.com/R_code/ff_usage.csv", as.is=TRUE)

f_sur=Surv(ff_usage$start, ff_usage$end, event=ff_usage$event)
plot(survfit(f_sur ~ 1))
f_cox=coxph(f_sur ~ total_usage+cluster(fault_id), data=ff_usage)

Kaplan-Meier 曲线看起来是正确的。

total_usage是在报告故障之前对 Firefox 用户数量的估计。这是非常依赖时间的,因此每个故障时间线都被分解为 7 天的时间间隔fault_id未拆分原件

对(或其日志)的依赖total_usage可能接近 1(我希望是其中一个)。

我试过设置init和增加iter.maxstrata(src_id)和子集 on src_id

大多数开始/结束时间都是估计的,并且有一个固定的时间间隔,我尝试添加一些随机化,例如runif(n, -3, 3). 没变。

我所看到的只是:

Warning message:
In fitter(X, Y, strats, offset, init, control, weights = weights,  :
  Ran out of iterations and did not converge

欢迎提出尝试的建议。

2个回答

这可能是一种情况,正如coxph() 文档页面所说,“系数的实际 MLE 估计是无穷大”,因此“相关系数以稳定的速度增长,并且拟合例程中将存在竞争条件。” 特别是,开始/结束时间与total_usage变量的密切相关性可能是这里的问题。

当我在生存分析中遇到像您这样的连续预测变量问题时total_usage,我会检查连续变量在中位数处的拆分。total_usage根据中值的拆分从数据中查看生存曲线5866.2coxph()对于这个简单的分析也没有收敛):

plot(survfit(f_sur~(total_usage > 5866.2),data=ff_usage))

看起来几乎所有低total_usage案例的审查时间和事件都在类似之前time=700,而几乎所有高子集的事件和审查时间total_usage都大于那个时间。此外,检查:

summary(survfit(f_sur~(total_usage > 5866.2),data=ff_usage))

可能会提供一些见解。我的数据集通常比这小得多,但我在 Cox 分析中遇到了相关问题,即“其中一个组没有事件的二分变量”,因此风险比定义不明确。

希望这有助于为您指明正确的方向。

结果:

f_cox
Call:
coxph(formula = f_sur ~ total_usage + cluster(fault_id), data = ff_usage)


                coef exp(coef) se(coef) robust se    z p
total_usage -0.00407     0.996        0         0 -Inf 0

这是警告信息。请注意,这不是收敛失败:

Warning message:
In fitter(X, Y, strats, offset, init, control, weights = weights,  :
  Loglik converged before variable  1 ; beta may be infinite. 

在考虑估计值爆炸的生存分析问题时,查看表格显示通常很有用。(在这种情况下,“爆炸”是偏小而不是偏高。)考虑查看与您的聚类变量交叉的事件:

 with(ff_usage, table(event, fault_id))

每个集群(全部 2294 个)的事件计数为 0 或 1,因此该算法最终对 sd.coef 进行了简单的制表和零估计。这很明显是假数据,至少在计数方面没有太多努力插入随机性。有风险的数字与“fault_id”一起以整数序列递增。

with(ff_usage, table(event, fault_id))
     fault_id
event   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23
    0   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  15  16  17  18  19  20  21
    1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
     fault_id
event  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46
    0  22  23  24  25  26  27  28  29  30  31  31  32  33  34  35  36  37  38  39  40  41  42  43
    1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
     fault_id
event  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69
    0  44  45  46  47  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  63  64
    1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
     fault_id
event  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92
    0  65  66  67  68  69  70  71  72  73  74  33  35  36  37  39  40  42  43  45  46  47  49  50
    1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
#--- truncated output which otherwise goes on for pages since there are 2294 "clusters".

在 2018 年运行此程序会产生略有不同的结果,尽管此问题的原因仍然是集群内的计数不足:

Call:
coxph(formula = f_sur ~ total_usage + cluster(fault_id), data = ff_usage)

                 coef exp(coef)  se(coef) robust se     z      p
total_usage -1.67e-03  9.98e-01  3.84e-05  1.05e-04 -15.9 <2e-16

Likelihood ratio test=6641  on 1 df, p=<2e-16
n= 174353, number of events= 899