-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathph.jl
111 lines (80 loc) · 2.63 KB
/
ph.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using Distributions
using SplineHazard
using SplineHazard.Spline
function ph_data(n=200, beta=0.0, tmax=36.0)
z = rand(Binomial(1, 0.5), n) .- 0.5
## 25 patients per month
max_entry = n / 25
entry = rand(Uniform(0, max_entry), n)
U = -log.(1 .-rand(Uniform(0, 1), n))
## 12 months median survival time
T = U.*exp.(-beta*z)./(log(2)/12)
## approx: 10% admin cens, 10% drop-out
C = min.(rand(Uniform(0, 3*36), n), tmax)
time = min.(T, C)
status = T .< C
id = 1:n
(id=id, entry=entry, time=time, status=status, z=z)
end
function ph_data_llog(n=200, beta=0.0, tmax=36.0)
z = rand(Binomial(1, 0.5), n) .- 0.5
## 25 patients per month
max_entry = n / 25
entry = rand(Uniform(0, max_entry), n)
U = 1 .- rand(Uniform(0, 1), n)
T = Vector{Float64}(undef, n)
for i in 1:n
##T[i] = exp(quantile(Logistic(log(12), 1/6), 1 - exp(log(U[i])*exp(-beta*z[i]))))
end
C = min.(rand(Uniform(0, 3*36), n), tmax)
time = min.(T, C)
status = T .< C
id = 1:n
(id=id, entry=entry, time=time, status=status, z=z)
end
function llog_hazard(time, a, b)
d = Logistic(a, b)
DataFrame(time=time, hazard=pdf.(d, time) ./ (1 .- cdf.(d, time)))
end
function ph_loglik(s, beta, data)
h = hazard(data.time[data.status], s)
ch = cumhaz(data.time, s)
sum(log.(h) .+ beta.*data.z[data.status]) - sum(ch.*exp.(beta.*data.z))
end
function sample_beta(beta::Float64, s::Sampler, data, prior::UnivariateDistribution)
X = data.z
time = data.time
status = data.status
ch = extract_cumhaz(s, time, s.t)
function log_target(x::Float64)
logpdf(prior, x) + sum(status.*x.*X - ch.*exp.(x.*X))
end
prop = rand(Normal(beta, 1.0), 1)[1]
r = log_target(prop) - log_target(beta)
if log(rand()) < r
return prop, true
else
return beta, false
end
end
function ph(data, M=10000)
s = setup_sampler(M, data.time[data.status], (sp, beta) -> ph_loglik(sp, beta, data))
beta = Vector{Float64}(undef, M+1)
beta[1] = 0.0
beta_ac = 0
prior_beta = Normal(0, 10)
for t in 1:M
beta[t+1], ac = sample_beta(beta[t], s, data, prior_beta)
beta_ac += ac
update!(s, beta[t+1])
end
println("Acceptance rate for beta: $(beta_ac/M)")
println("Posterior mean: $(mean(beta[(s.warmup+1):end]))")
println("Posterior variance: $(var(beta[(s.warmup+1):end]))")
##summary(s, data.time)
beta[(s.warmup+1):end], beta_ac, s
end
function ph_example()
data = ph_data(200, log(0.67))
ph(data, 10000)
end