Dalam hal ini, saya percaya jalan menuju solusi ada jika kita memakai topi analisis kelangsungan hidup kita. Perhatikan bahwa meskipun model ini tidak memiliki subjek yang disensor (dalam pengertian tradisional), kita masih dapat menggunakan analisis bertahan hidup dan berbicara tentang bahaya subjek.
Kita perlu memodelkan tiga hal dalam urutan ini: i) bahaya kumulatif, ii) bahaya, iii) kemungkinan log.
H( t )H( t ) = - logS( t )T∼ P.o i ( λ )
HT( t ) = - log( 1 - Q ( t , λ ) ) =-logP( t , λ )
Q , P
Sekarang kami ingin menambahkan "bahaya" dari asuransi yang habis. Hal yang menyenangkan tentang bahaya kumulatif adalah bahwa zat tersebut bersifat aditif, jadi kita hanya perlu menambahkan "risiko" pada waktu 7, 14, 21:
HT′( t ) = - logP( t , λ ) +a⋅ 1( t > 7 )+ b ⋅ 1( t > 14 )+ c ⋅ 1( t > 21 )
>a,bc
c
HT′(t)=−logP(t,λ)+a⋅1(t>7)+b⋅1(t>14)+∞⋅1(t>21)
h(t)
h(t)=1−exp(H(t)−H(t+1))
Memasukkan bahaya kumulatif kami, dan menyederhanakan:
hT′(t)=1−P(t+1,λ)P(t,λ)exp(−a⋅1(t=7)−b⋅1(t=14)−∞⋅1(t=21))
iii) Akhirnya, menulis kemungkinan log untuk model bertahan hidup (tanpa menyensor) sangat mudah setelah kita memiliki bahaya dan bahaya kumulatif:
ll(λ,a,b|t)=∑i=1N(logh(ti)−H(ti))
Dan itu dia!
a=−log(1−pa),b=−log(1−pa−pb)−log(1−pa),pc=1−(pa+pb)
Buktinya ada di puding. Mari kita lakukan beberapa simulasi dan inferensi dengan menggunakan semantik model khusus jalur kehidupan .
from lifelines.fitters import ParametericUnivariateFitter
from autograd_gamma import gammaincln, gammainc
from autograd import numpy as np
MAX = 1e10
class InsuranceDischargeModel(ParametericUnivariateFitter):
"""
parameters are related by
a = -log(1 - p_a)
b = -log(1 - p_a - p_b) - log(1 - p_a)
p_c = 1 - (p_a + p_b)
"""
_fitted_parameter_names = ["lbd", "a", "b"]
_bounds = [(0, None), (0, None), (0, None)]
def _hazard(self, params, t):
# from (1.64c) in http://geb.uni-giessen.de/geb/volltexte/2014/10793/pdf/RinneHorst_hazardrate_2014.pdf
return 1 - np.exp(self._cumulative_hazard(params, t) - self._cumulative_hazard(params, t+1))
def _cumulative_hazard(self, params, t):
lbd, a, b = params
return -gammaincln(t, lbd) + a * (t > 7) + b * (t > 14) + MAX * (t > 21)
def gen_data():
p_a, p_b = 0.4, 0.2
p = [p_a, p_b, 1 - p_a - p_b]
lambda_ = 18
death_without_insurance = np.random.poisson(lambda_)
insurance_covers_until = np.random.choice([7, 14, 21], p=p)
if death_without_insurance < insurance_covers_until:
return death_without_insurance
else:
return insurance_covers_until
durations = np.array([gen_data() for _ in range(40000)])
model = InsuranceDischargeModel()
model.fit(durations)
model.print_summary(5)
"""
<lifelines.InsuranceDischargeModel: fitted with 40000 observations, 0 censored>
number of subjects = 40000
number of events = 40000
log-likelihood = -78845.10392
hypothesis = lbd != 1, a != 1, b != 1
---
coef se(coef) lower 0.95 upper 0.95 p -log2(p)
lbd 18.05026 0.03353 17.98455 18.11598 <5e-06 inf
a 0.50993 0.00409 0.50191 0.51794 <5e-06 inf
b 0.40777 0.00557 0.39686 0.41868 <5e-06 inf
"""
¹ lihat Bagian 1.2 di sini