Модель логістичної регресії передбачає, що відповідь є випробуванням Бернуллі (або загалом двочленним, але для простоти збережемо його 0-1). Модель виживання передбачає, що реакція, як правило, час події (знову ж, є узагальнення цього, які ми пропустимо). Ще один спосіб сказати, що одиниці проходять через ряд значень, поки не відбудеться подія. Справа не в тому, що монета насправді дискретно перевертається в кожній точці. (Це , звичайно, може статися, але тоді вам знадобиться модель для повторних заходів - можливо, ГЛМ.)
Ваша логістична регресійна модель сприймає кожну смерть як монету, яка відбулася в цьому віці, і з'явилася хвостиком. Аналогічно, він розглядає кожну цензуровану дату як єдину перевернуту монету, яка сталася у вказаний вік і придумала голови. Проблема тут полягає в тому, що це не відповідає тому, що є насправді даними.
Ось кілька графіків даних та результатів моделей. (Зверніть увагу, що я перевертаю прогнози з логістичної регресійної моделі на передбачення живої, щоб лінія відповідала графіку умовної щільності.)
library(survival)
data(lung)
s = with(lung, Surv(time=time, event=status-1))
summary(sm <- coxph(s~age, data=lung))
# Call:
# coxph(formula = s ~ age, data = lung)
#
# n= 228, number of events= 165
#
# coef exp(coef) se(coef) z Pr(>|z|)
# age 0.018720 1.018897 0.009199 2.035 0.0419 *
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# exp(coef) exp(-coef) lower .95 upper .95
# age 1.019 0.9815 1.001 1.037
#
# Concordance= 0.55 (se = 0.026 )
# Rsquare= 0.018 (max possible= 0.999 )
# Likelihood ratio test= 4.24 on 1 df, p=0.03946
# Wald test = 4.14 on 1 df, p=0.04185
# Score (logrank) test = 4.15 on 1 df, p=0.04154
lung$died = factor(ifelse(lung$status==2, "died", "alive"), levels=c("died","alive"))
summary(lrm <- glm(status-1~age, data=lung, family="binomial"))
# Call:
# glm(formula = status - 1 ~ age, family = "binomial", data = lung)
#
# Deviance Residuals:
# Min 1Q Median 3Q Max
# -1.8543 -1.3109 0.7169 0.8272 1.1097
#
# Coefficients:
# Estimate Std. Error z value Pr(>|z|)
# (Intercept) -1.30949 1.01743 -1.287 0.1981
# age 0.03677 0.01645 2.235 0.0254 *
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# (Dispersion parameter for binomial family taken to be 1)
#
# Null deviance: 268.78 on 227 degrees of freedom
# Residual deviance: 263.71 on 226 degrees of freedom
# AIC: 267.71
#
# Number of Fisher Scoring iterations: 4
windows()
plot(survfit(s~1))
windows()
par(mfrow=c(2,1))
with(lung, spineplot(age, as.factor(status)))
with(lung, cdplot(age, as.factor(status)))
lines(40:80, 1-predict(lrm, newdata=data.frame(age=40:80), type="response"),
col="red")
Може бути корисним розглянути ситуацію, в якій дані були придатні або для аналізу виживання, або для логістичної регресії. Уявіть собі дослідження, щоб визначити ймовірність того, що пацієнта буде повернено до лікарні протягом 30 днів після виписки за новим протоколом або стандартом догляду. Однак усі пацієнти дотримуються реадмісії, і цензури немає (це не дуже реально), тому точний час до реадмісії можна було б проаналізувати за допомогою аналізу виживання (а саме тут пропорційна модель Кокса). Щоб імітувати цю ситуацію, я буду використовувати експоненціальні розподіли зі швидкістю .5 та 1, а значення 1 використовуватимемо як відсіч, щоб представити 30 днів:
set.seed(0775) # this makes the example exactly reproducible
t1 = rexp(50, rate=.5)
t2 = rexp(50, rate=1)
d = data.frame(time=c(t1,t2),
group=rep(c("g1","g2"), each=50),
event=ifelse(c(t1,t2)<1, "yes", "no"))
windows()
plot(with(d, survfit(Surv(time)~group)), col=1:2, mark.time=TRUE)
legend("topright", legend=c("Group 1", "Group 2"), lty=1, col=1:2)
abline(v=1, col="gray")
with(d, table(event, group))
# group
# event g1 g2
# no 29 22
# yes 21 28
summary(glm(event~group, d, family=binomial))$coefficients
# Estimate Std. Error z value Pr(>|z|)
# (Intercept) -0.3227734 0.2865341 -1.126475 0.2599647
# groupg2 0.5639354 0.4040676 1.395646 0.1628210
summary(coxph(Surv(time)~group, d))$coefficients
# coef exp(coef) se(coef) z Pr(>|z|)
# groupg2 0.5841386 1.793445 0.2093571 2.790154 0.005268299
У цьому випадку ми бачимо, що p-значення з логістичної регресійної моделі ( 0.163
) було вище, ніж значення p від аналізу виживання ( 0.005
). Для подальшого вивчення цієї ідеї ми можемо розширити моделювання, щоб оцінити потужність логістичного регресійного аналізу порівняно з аналізом виживання та ймовірність того, що значення p від моделі Кокса буде нижчим, ніж значення p від логістичної регресії . Я також буду використовувати 1,4 як поріг, так що я не перешкоджаю логістичній регресії за допомогою субоптимального відсікання:
xs = seq(.1,5,.1)
xs[which.max(pexp(xs,1)-pexp(xs,.5))] # 1.4
set.seed(7458)
plr = vector(length=10000)
psv = vector(length=10000)
for(i in 1:10000){
t1 = rexp(50, rate=.5)
t2 = rexp(50, rate=1)
d = data.frame(time=c(t1,t2), group=rep(c("g1", "g2"), each=50),
event=ifelse(c(t1,t2)<1.4, "yes", "no"))
plr[i] = summary(glm(event~group, d, family=binomial))$coefficients[2,4]
psv[i] = summary(coxph(Surv(time)~group, d))$coefficients[1,5]
}
## estimated power:
mean(plr<.05) # [1] 0.753
mean(psv<.05) # [1] 0.9253
## probability that p-value from survival analysis < logistic regression:
mean(psv<plr) # [1] 0.8977
Таким чином, потужність логістичної регресії є нижче (близько 75%) , ніж аналіз виживаності (близько 93%), і 90% р-значень з аналізу виживаності були нижче , ніж відповідні р-значення з логістичної регресії. Враховуючи часові відставання, замість того, щоб бути меншим або більшим, ніж деякий поріг, можна отримати більше статистичної потужності, як ви зрозуміли.