Есть ли способ получить частичную вероятность модели Кокса PH с новыми данными и фиксированными коэффициентами?

Я выполняю перекрестную проверку модели пропорциональных рисков конкурирующих рисков. С помощью mstate pacakge я подготовил свои данные и подгоняю их с survival::coxph. Я получаю подобранный объект модели Кокса для моих обучающих данных, но я хочу оценить частичную вероятность моих обученных коэффициентов с моими тестовыми данными.

Если мне нужно, я сам напишу функцию частичного правдоподобия, но я бы предпочел этого не делать (хотя, вероятно, это было бы хорошо для меня). Пакет выживания вычисляет в этом коде C, но расчет вероятности встроена в функцию подгонки. Может быть, есть способ исправить параметры или какие-то другие инструменты, чтобы легко получить частичную вероятность?

Минимальный рабочий пример

# Adapted from examples in the mstate vignette
# http://cran.r-project.org/web/packages/mstate/vignettes/Tutorial.pdf
# beginning at the bottom of page 28

library(mstate)
library(survival)

# Get data. I add a second explanatory variable (badx) for illustration
# Also divide the data by subject into training and test sets.
data(aidssi)
si <- aidssi # Just a shorter name
si$badx <- sample(c("A", "B"), size = nrow(si), replace = TRUE)
si$fold <- sample(c("train", "test"), size = nrow(si), replace = TRUE, prob = c(0.7, 0.3))
tmat <- trans.comprisk(2, names = c("event-free", "AIDS", "SI"))
si$stat1 <- as.numeric(si$status == 1)
si$stat2 <- as.numeric(si$status == 2)

# Convert the data to a long competing risks format
silong <- msprep(time = c(NA, "time", "time"), 
                 status = c(NA,"stat1", "stat2"),
                 data = si, keep = c("ccr5", "badx", "fold"), trans = tmat)
silong <- na.omit(silong)
silong <- expand.covs(silong, c("ccr5", "badx"))
train.dat <- subset(silong, fold == "train")
test.dat <- subset(silong, fold == "test")

Данные выглядят так:

> head(silong)
An object of class 'msdata'

Data:
  id from to trans Tstart  Tstop   time status ccr5 badx  fold ccr5WM.1 ccr5WM.2 badxB.1 badxB.2
1  1    1  2     1      0  9.106  9.106      1   WW    A train        0        0       0       0
2  1    1  3     2      0  9.106  9.106      0   WW    A train        0        0       0       0
3  2    1  2     1      0 11.039 11.039      0   WM    B train        1        0       1       0
4  2    1  3     2      0 11.039 11.039      0   WM    B train        0        1       0       1
5  3    1  2     1      0  2.234  2.234      1   WW    B train        0        0       1       0
6  3    1  3     2      0  2.234  2.234      0   WW    B train        0        0       0       1

Теперь переменная ccr5 может быть смоделирована как специфическая для перехода или как имеющая равный пропорциональный эффект для всех переходов. Модели бывают:

train.mod.equal <- coxph(Surv(time, status) ~ ccr5 + badx + strata(trans),
                         data = train.dat)
train.mod.specific <- coxph(Surv(time, status) ~ ccr5WM.1 + ccr5WM.2 + badx + strata(trans),
                            data = train.dat)

Теперь я хотел бы использовать тестовые данные, чтобы оценить выбор переменной относительно того, должен ли ccr5 зависеть от перехода или нет. У меня большой набор данных и множество переменных - в основном, но не все категориальных, - которые могут быть одинаковыми. Оценка - вот где я застрял.

# We can fit the same models to the test data,
# this yields new parameter estimates of course,
# but the model matrices might be useful
test.mod.equal <- coxph(Surv(time, status) ~ ccr5 + badx + strata(trans),
                         data = test.dat)
test.mod.specific <- coxph(Surv(time, status) ~ ccr5WM.1 + ccr5WM.2 + badx + strata(trans),
                            data = test.dat)
test.eq.mm <- model.matrix(test.mod.equal)
test.sp.mm <- model.matrix(test.mod.specific)

# We can use these to get the first part of the sum of the partial likelihood:
xbeta.eq <- test.eq.mm[test.dat$status == 1, ] %*% coef(train.mod.equal)
xbeta.sp <- test.sp.mm[test.dat$status == 1, ] %*% coef(train.mod.specific)

# We can also get linear predictors
lp.eq <- predict(train.mod.equal, newdata = test.dat, type = "lp")
lp.sp <- predict(train.mod.specific, newdata = test.dat, type = "lp")

Я надеюсь вычислить частичное правдоподобие для каждой из моделей на тестовых данных с оценками коэффициентов обучения. Возможно, мне стоит переместить вопрос в раздел «Перекрестная проверка» и спросить, достаточно ли близка сумма линейных предикторов (или сумма линейных предикторов, исключая цензурированные случаи) к эквивалентной мере.


person Gregor Thomas    schedule 03.11.2014    source источник
comment
Проблема в том, что частичные вероятности меняются с течением времени по мере уменьшения набора рисков. Если вы объясните, что вы на самом деле пытаетесь, предпочтительно с помощью небольшого набора примеров, подробности могут стать доступными.   -  person IRTFM    schedule 03.11.2014
comment
@BondedDust Я работаю над примером. Я понимаю, что вклад в вероятность из-за каждого наблюдения зависит от того, какие другие переменные все еще находятся в наборе рисков, но сумма частичного логарифмического правдоподобия по-прежнему является просто функцией параметров модели с учетом данных. У меня есть как параметры модели (из подгонки для обучения), так и данные (из набора тестов), мне просто не хватает функции для вычисления вероятности частичного журнала.   -  person Gregor Thomas    schedule 04.11.2014
comment
Итак, вы хотите вычислить, насколько далеко прогноз (mdl, type = lp) (по логарифмической шкале правдоподобия) находится от набора данных с цензурой и переменными результата. Можете ли вы рассчитать неомодель по формуле, которая включает смещение, которое использует бета-оценки, а затем использовать сводку (mdl), чтобы сделать за вас тяжелую работу? Возможно, вы даже сможете рассчитать смещение с помощью predict.coxph.   -  person IRTFM    schedule 04.11.2014
comment
Хммм, мне надо над этим подумать. Мне нравится идея новой модели. Меня вытаскивают на собрание, но я вернусь сегодня вечером с MWE (который, если мне действительно повезет, я отправлю его в качестве ответа).   -  person Gregor Thomas    schedule 04.11.2014
comment
MWE добавил, что не повезло с неомодельным подходом, по крайней мере, мне самому.   -  person Gregor Thomas    schedule 05.11.2014
comment
Моя стратегия, кажется, дает разумные результаты, но, возможно, вам стоит пересмотреть. У вас есть правильный ответ для сравнения?   -  person IRTFM    schedule 05.11.2014
comment
Я обязательно сделаю обзор - вы меня убедили примерно на 80%. Мой правильный ответ для приведенного выше примера будет заключаться в том, что переменная ccr5 превосходит переменную, специфичную для перехода, тогда как переменная badx - нет (игнорируя тот факт, что badx достаточно плох, чтобы ее вообще выбросить). И я счастлив наказать модели, относящиеся к конкретному переходу, за установку дополнительного параметра.   -  person Gregor Thomas    schedule 05.11.2014
comment
Я собираюсь начать тестирование сейчас, чтобы увидеть, будет ли разумно использовать logLik() для получения логарифмической вероятности неомодели, а затем добавить к этому статистику теста LRT. Тогда я смогу напрямую сравнить модели test.eq и test.sp. Или, может быть, мне просто нужно запустить нулевые модели с каждым из offsets ...   -  person Gregor Thomas    schedule 05.11.2014


Ответы (1)


Это то, что я предлагал, когда писал: «Можете ли вы рассчитать« неомодель »(используя [новые данные] с формулой, которая включает смещение [построено с] бета-оценками [от исходной подгонки], а затем использовать summary(mdl) Чтобы сделать за вас тяжелую работу? Возможно, вы даже сможете рассчитать смещение с помощью predic.coxph. »Оказывается, мне не нужно использовать summary.coxph, поскольку print.coxph дает статистику LLR.

 lp.eq <- predict(train.mod.equal, newdata = test.dat, type = "lp")
 eq.test.mod <- coxph(Surv(time, status) ~ ccr5 + badx + strata(trans)+offset(lp.eq), 
   data=test.dat )
eq.test.mod

Call:
coxph(formula = Surv(time, status) ~ ccr5 + badx + strata(trans) + 
    offset(lp.eq), data = test.dat)


           coef exp(coef) se(coef)       z    p
ccr5WM -0.20841     0.812    0.323 -0.6459 0.52
badxB  -0.00829     0.992    0.235 -0.0354 0.97

Likelihood ratio test=0.44  on 2 df, p=0.804  n= 212, number of events= 74 

Я бы интерпретировал это как означающее, что аналогичная модель, согласующаяся с прогнозами, основанными на первой модели, но с новыми данными, существенно не отличалась (от нулевой модели) и что по шкале логарифмического правдоподобия она находилась на расстоянии 0,44 дюйма. от точной посадки.

Как указывает @Gregor, можно получить доступ к узлу loglik объекта coxph, но я бы не советовал придавать слишком большое значение отдельным значениям. Чтобы получить статистику LRT, можно произвести:

> diff(eq.test.mod$loglik)
[1] 0.399137

Для интереса также посмотрите на результат без смещения:

> coxph(Surv(time, status) ~ ccr5 + badx + strata(trans), 
+       data=test.dat)
Call:
coxph(formula = Surv(time, status) ~ ccr5 + badx + strata(trans), 
    data = test.dat)


          coef exp(coef) se(coef)      z      p
ccr5WM -0.8618     0.422    0.323 -2.671 0.0076
badxB  -0.0589     0.943    0.235 -0.251 0.8000

Likelihood ratio test=8.42  on 2 df, p=0.0148  n= 212, number of events= 74 

И вы действительно получите ожидаемый результат при тестировании с исходными данными:

> lp.eq2 <- predict(train.mod.equal, newdata = train.dat, type = "lp")
> coxph(Surv(time, status) ~ ccr5 + badx + strata(trans)+offset(lp.eq2), 
+       data=train.dat)
Call:
coxph(formula = Surv(time, status) ~ ccr5 + badx + strata(trans) + 
    offset(lp.eq2), data = train.dat)


            coef exp(coef) se(coef)         z p
ccr5WM -4.67e-12         1    0.230 -2.03e-11 1
badxB   2.57e-14         1    0.168  1.53e-13 1

Likelihood ratio test=0  on 2 df, p=1  n= 436, number of events= 146 
person IRTFM    schedule 05.11.2014
comment
Думаю, я смогу еще ближе подойти к тому, что хочу изучить (новое название в вашем ответе) eq.test.mod$loglik. Если посмотреть на ?coxph.object, первый элемент в $loglik - это логарифмическая вероятность с начальными значениями. - person Gregor Thomas; 05.11.2014
comment
Спасибо за вашу помощь с этим, жаль, что у меня не было больше голосов! - person Gregor Thomas; 05.11.2014
comment
Хорошо, но помните, что вероятность логической вероятности не является точным числом. Он действителен только до константы, которая затем неявно вычитается при выполнении LRT. Только путем сравнения с вложенной моделью можно законно извлекать информацию. Я не думаю, что было бы целесообразно сравнивать значения loglik в двух разных наборах данных. - person IRTFM; 05.11.2014
comment
Хотя модели не являются строго вложенными, я буду использовать один и тот же набор данных для каждой - не для сравнения между тестом и обучением, а просто разные параметризации тестовых данных. Пока все результаты выглядят очень разумно. - person Gregor Thomas; 06.11.2014