Можно ли запустить модель Кокса-Пропорционально-Опасных Опасностей с экспоненциальным распределением базовой опасности в "линиях жизни" или другом пакете?
Я считаю использование lifelines
пакет, чтобы соответствовать модели Кокса-Пропорционально-Опасности. Я читал, что линии жизни используют непараметрический подход, чтобы соответствовать базовой опасности, что приводит к различным baseline_hazards для некоторых моментов времени (см. Пример кода ниже). Для моего приложения мне нужно экспоненциальное распределение, приводящее к базовой опасности h0(t) = lambda, которая постоянна во времени.
Таким образом, мой вопрос: возможно ли (в то же время) запустить модель Кокса-Пропорционально-Опасности-опасности с экспоненциальным распределением для базовой опасности в lifelines
или другой пакет Python?
Пример кода:
from lifelines import CoxPHFitter
import pandas as pd
df = pd.DataFrame({'duration': [4, 6, 5, 5, 4, 6],
'event': [0, 0, 0, 1, 1, 1],
'cat': [0, 1, 0, 1, 0, 1]})
cph = CoxPHFitter()
cph.fit(df, duration_col='duration', event_col='event', show_progress=True)
cph.baseline_hazard_
дает
baseline hazard
T
4.0 0.160573
5.0 0.278119
6.0 0.658032
1 ответ
Автор спасательных кругов здесь.
Таким образом, эта модель изначально не существует, но вы можете легко реализовать ее самостоятельно (и, возможно, что-то, что я сделаю для будущего выпуска). Эта идея опирается на пересечение моделей пропорциональной опасности и моделей AFT (ускоренное время отказа). В модели cox-ph с экспоненциальной опасностью (то есть постоянной базовой опасностью) опасность выглядит следующим образом:
h(t|x) = lambda_0(t) * exp(beta * x) = lambda_0 * exp(beta * x)
В спецификации AFT для экспоненциального распределения опасность выглядит следующим образом:
h(t|x) = exp(-beta * x - beta_0) = exp(-beta * x) * exp(-beta_0) = exp(-beta * x) * lambda_0
Обратите внимание на разницу отрицательных знаков!
Таким образом, вместо того, чтобы делать CoxPH, мы можем сделать экспоненциальную подборку AFT (и перевернуть знаки, если мы хотим получить ту же интерпретацию, что и CoxPH). Мы можем использовать синтаксис пользовательской модели регулярности для этого:
from lifelines.fitters import ParametricRegressionFitter
from autograd import numpy as np
class ExponentialAFTFitter(ParametricRegressionFitter):
# this is necessary, and should always be a non-empty list of strings.
_fitted_parameter_names = ['lambda_']
def _cumulative_hazard(self, params, T, Xs):
# params is a dictionary that maps unknown parameters to a numpy vector.
# Xs is a dictionary that maps unknown parameters to a numpy 2d array
lambda_ = np.exp(np.dot(Xs['lambda_'], params['lambda_']))
return T / lambda_
Проверяя это,
from lifelines.datasets import load_rossi
from lifelines import CoxPHFitter
rossi = load_rossi()
rossi['intercept'] = 1
regressors = {'lambda_': rossi.columns}
eaf = ExponentialAFTFitter().fit(rossi, "week", "arrest", regressors=regressors)
eaf.print_summary()
"""
<lifelines.ExponentialAFTFitter: fitted with 432 observations, 318 censored>
event col = 'arrest'
number of subjects = 432
number of events = 114
log-likelihood = -686.37
time fit was run = 2019-06-27 15:13:18 UTC
---
coef exp(coef) se(coef) z p -log2(p) lower 0.95 upper 0.95
lambda_ fin 0.37 1.44 0.19 1.92 0.06 4.18 -0.01 0.74
age 0.06 1.06 0.02 2.55 0.01 6.52 0.01 0.10
race -0.30 0.74 0.31 -0.99 0.32 1.63 -0.91 0.30
wexp 0.15 1.16 0.21 0.69 0.49 1.03 -0.27 0.56
mar 0.43 1.53 0.38 1.12 0.26 1.93 -0.32 1.17
paro 0.08 1.09 0.20 0.42 0.67 0.57 -0.30 0.47
prio -0.09 0.92 0.03 -3.03 <0.005 8.65 -0.14 -0.03
_intercept 4.05 57.44 0.59 6.91 <0.005 37.61 2.90 5.20
_fixed _intercept 0.00 1.00 0.00 nan nan nan 0.00 0.00
---
"""
CoxPHFitter().fit(load_rossi(), 'week', 'arrest').print_summary()
"""
<lifelines.CoxPHFitter: fitted with 432 observations, 318 censored>
duration col = 'week'
event col = 'arrest'
number of subjects = 432
number of events = 114
partial log-likelihood = -658.75
time fit was run = 2019-06-27 15:17:41 UTC
---
coef exp(coef) se(coef) z p -log2(p) lower 0.95 upper 0.95
fin -0.38 0.68 0.19 -1.98 0.05 4.40 -0.75 -0.00
age -0.06 0.94 0.02 -2.61 0.01 6.79 -0.10 -0.01
race 0.31 1.37 0.31 1.02 0.31 1.70 -0.29 0.92
wexp -0.15 0.86 0.21 -0.71 0.48 1.06 -0.57 0.27
mar -0.43 0.65 0.38 -1.14 0.26 1.97 -1.18 0.31
paro -0.08 0.92 0.20 -0.43 0.66 0.59 -0.47 0.30
prio 0.09 1.10 0.03 3.19 <0.005 9.48 0.04 0.15
---
Concordance = 0.64
Log-likelihood ratio test = 33.27 on 7 df, -log2(p)=15.37
"""
Обратите внимание на изменение знака! Так что если вы хотите постоянную базовую опасность в модели, это exp(-4.05)
,