dat <- data.frame(
id = 1:30,
group = c(
rep("Thường", 15),
rep("LED", 15)
),
voltage = c(
213.3, 231.1, 210.0, 220.6, 233.7,
215.2, 216.2, 214.9, 217.7, 221.1,
229.8, 213.6, 211.4, 218.7, 211.4,
218.9, 215.2, 202.5, 221.9, 217.9,
227.2, 227.5, 231.7, 225.7, 226.6,
217.7, 231.3, 232.0, 214.7, 213.2
),
time = c(
1060, 1615, 380, 17, 11,
233, 230, 2000, 130, 289,
184, 735, 2000, 308, 2000,
352, 2000, 2000, 2000, 2000,
172, 527, 2000, 2000, 2000,
2000, 66, 530, 2000, 2000
),
status = c(
1, 1, 1, 1, 1,
1, 1, 0, 1, 1,
1, 1, 0, 1, 0,
1, 0, 0, 0, 0,
1, 1, 0, 0, 0,
0, 1, 1, 0, 0
)
)
dim(dat)
## [1] 30 5
head(dat)
## id group voltage time status
## 1 1 Thường 213.3 1060 1
## 2 2 Thường 231.1 1615 1
## 3 3 Thường 210.0 380 1
## 4 4 Thường 220.6 17 1
## 5 5 Thường 233.7 11 1
## 6 6 Thường 215.2 233 1
Dữ liệu gồm 30 bóng đèn thuộc hai nhóm là bóng đèn thường và bóng đèn
LED.
Biến time thể hiện thời gian hoạt động và
status cho biết bóng đèn đã hỏng hay bị kiểm duyệt.
library(survival)
library(survminer)
km <- survfit(
Surv(time, status) ~ group,
data = dat
)
summary(km)
## Call: survfit(formula = Surv(time, status) ~ group, data = dat)
##
## group=LED
## time n.risk n.event survival std.err lower 95% CI upper 95% CI
## 66 15 1 0.933 0.0644 0.815 1.000
## 172 14 1 0.867 0.0878 0.711 1.000
## 352 13 1 0.800 0.1033 0.621 1.000
## 527 12 1 0.733 0.1142 0.540 0.995
## 530 11 1 0.667 0.1217 0.466 0.953
##
## group=Thường
## time n.risk n.event survival std.err lower 95% CI upper 95% CI
## 11 15 1 0.933 0.0644 0.8153 1.000
## 17 14 1 0.867 0.0878 0.7106 1.000
## 130 13 1 0.800 0.1033 0.6212 1.000
## 184 12 1 0.733 0.1142 0.5405 0.995
## 230 11 1 0.667 0.1217 0.4661 0.953
## 233 10 1 0.600 0.1265 0.3969 0.907
## 289 9 1 0.533 0.1288 0.3322 0.856
## 308 8 1 0.467 0.1288 0.2717 0.802
## 380 7 1 0.400 0.1265 0.2152 0.743
## 735 6 1 0.333 0.1217 0.1630 0.682
## 1060 5 1 0.267 0.1142 0.1152 0.617
## 1615 4 1 0.200 0.1033 0.0727 0.550
ggsurvplot(
km,
data = dat,
risk.table = TRUE,
pval = TRUE,
xlab = "Thời gian",
ylab = "Xác suất sống còn",
title = "Kaplan-Meier theo loại bóng đèn",
ggtheme = theme_minimal()
)
survdiff(
Surv(time, status) ~ group,
data = dat
)
## Call:
## survdiff(formula = Surv(time, status) ~ group, data = dat)
##
## N Observed Expected (O-E)^2/E (O-E)^2/V
## group=LED 15 5 10.05 2.54 6.31
## group=Thường 15 12 6.95 3.67 6.31
##
## Chisq= 6.3 on 1 degrees of freedom, p= 0.01
Kiểm định Log-rank được sử dụng để đánh giá sự khác biệt giữa hai đường sống còn.
modelCox_lightBulb <- coxph(
Surv(time, status) ~ group,
data = dat
)
summary(modelCox_lightBulb)
## Call:
## coxph(formula = Surv(time, status) ~ group, data = dat)
##
## n= 30, number of events= 17
##
## coef exp(coef) se(coef) z Pr(>|z|)
## groupThường 1.2655 3.5448 0.5364 2.359 0.0183 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## exp(coef) exp(-coef) lower .95 upper .95
## groupThường 3.545 0.2821 1.239 10.14
##
## Concordance= 0.65 (se = 0.059 )
## Likelihood ratio test= 6.23 on 1 df, p=0.01
## Wald test = 5.57 on 1 df, p=0.02
## Score (logrank) test = 6.31 on 1 df, p=0.01
Mô hình Cox được sử dụng để đánh giá mối liên quan giữa loại bóng đèn và nguy cơ bóng đèn bị hỏng theo thời gian.
library(carData)
data("Rossi")
names(Rossi)
## [1] "week" "arrest" "fin" "age" "race" "wexp" "mar" "paro"
## [9] "prio" "educ" "emp1" "emp2" "emp3" "emp4" "emp5" "emp6"
## [17] "emp7" "emp8" "emp9" "emp10" "emp11" "emp12" "emp13" "emp14"
## [25] "emp15" "emp16" "emp17" "emp18" "emp19" "emp20" "emp21" "emp22"
## [33] "emp23" "emp24" "emp25" "emp26" "emp27" "emp28" "emp29" "emp30"
## [41] "emp31" "emp32" "emp33" "emp34" "emp35" "emp36" "emp37" "emp38"
## [49] "emp39" "emp40" "emp41" "emp42" "emp43" "emp44" "emp45" "emp46"
## [57] "emp47" "emp48" "emp49" "emp50" "emp51" "emp52"
dat_Rossi <- Rossi[
c(
"week",
"arrest",
"fin",
"age",
"race",
"wexp",
"mar",
"paro",
"prio",
"educ"
)
]
head(dat_Rossi)
## week arrest fin age race wexp mar paro prio educ
## 1 20 1 no 27 black no not married yes 3 3
## 2 17 1 no 18 black no not married yes 8 4
## 3 25 1 no 19 other yes not married yes 13 3
## 4 52 0 yes 23 black yes married yes 1 5
## 5 52 0 no 19 other yes not married yes 3 3
## 6 52 0 no 24 black yes not married no 2 4
nrow(dat_Rossi)
## [1] 432
ncol(dat_Rossi)
## [1] 10
library(table1)
table1(
~ arrest + week + fin + age + race +
wexp + mar + paro + prio + educ,
data = dat_Rossi
)
| Overall (N=432) |
|
|---|---|
| arrest | |
| Mean (SD) | 0.264 (0.441) |
| Median [Min, Max] | 0 [0, 1.00] |
| week | |
| Mean (SD) | 45.9 (12.7) |
| Median [Min, Max] | 52.0 [1.00, 52.0] |
| fin | |
| no | 216 (50.0%) |
| yes | 216 (50.0%) |
| age | |
| Mean (SD) | 24.6 (6.11) |
| Median [Min, Max] | 23.0 [17.0, 44.0] |
| race | |
| black | 379 (87.7%) |
| other | 53 (12.3%) |
| wexp | |
| no | 185 (42.8%) |
| yes | 247 (57.2%) |
| mar | |
| married | 53 (12.3%) |
| not married | 379 (87.7%) |
| paro | |
| no | 165 (38.2%) |
| yes | 267 (61.8%) |
| prio | |
| Mean (SD) | 2.98 (2.90) |
| Median [Min, Max] | 2.00 [0, 18.0] |
| educ | |
| Mean (SD) | 3.48 (0.834) |
| Median [Min, Max] | 3.00 [2.00, 6.00] |
dat_Rossi <- na.omit(dat_Rossi)
km_Rossi <- survfit(
Surv(week, arrest) ~ 1,
data = dat_Rossi
)
summary(km_Rossi)
## Call: survfit(formula = Surv(week, arrest) ~ 1, data = dat_Rossi)
##
## time n.risk n.event survival std.err lower 95% CI upper 95% CI
## 1 432 1 0.998 0.00231 0.993 1.000
## 2 431 1 0.995 0.00327 0.989 1.000
## 3 430 1 0.993 0.00400 0.985 1.000
## 4 429 1 0.991 0.00461 0.982 1.000
## 5 428 1 0.988 0.00515 0.978 0.999
## 6 427 1 0.986 0.00563 0.975 0.997
## 7 426 1 0.984 0.00607 0.972 0.996
## 8 425 5 0.972 0.00791 0.957 0.988
## 9 420 2 0.968 0.00852 0.951 0.984
## 10 418 1 0.965 0.00881 0.948 0.983
## 11 417 2 0.961 0.00935 0.942 0.979
## 12 415 2 0.956 0.00987 0.937 0.976
## 13 413 1 0.954 0.01011 0.934 0.974
## 14 412 3 0.947 0.01080 0.926 0.968
## 15 409 2 0.942 0.01123 0.920 0.964
## 16 407 2 0.937 0.01165 0.915 0.961
## 17 405 3 0.931 0.01223 0.907 0.955
## 18 402 3 0.924 0.01278 0.899 0.949
## 19 399 2 0.919 0.01313 0.894 0.945
## 20 397 5 0.907 0.01395 0.880 0.935
## 21 392 2 0.903 0.01425 0.875 0.931
## 22 390 1 0.900 0.01440 0.873 0.929
## 23 389 1 0.898 0.01455 0.870 0.927
## 24 388 4 0.889 0.01512 0.860 0.919
## 25 384 3 0.882 0.01552 0.852 0.913
## 26 381 3 0.875 0.01591 0.844 0.907
## 27 378 2 0.870 0.01616 0.839 0.903
## 28 376 2 0.866 0.01640 0.834 0.898
## 30 374 2 0.861 0.01664 0.829 0.894
## 31 372 1 0.859 0.01675 0.827 0.892
## 32 371 2 0.854 0.01698 0.822 0.888
## 33 369 2 0.850 0.01720 0.816 0.884
## 34 367 2 0.845 0.01742 0.811 0.880
## 35 365 4 0.836 0.01783 0.801 0.871
## 36 361 3 0.829 0.01813 0.794 0.865
## 37 358 4 0.819 0.01851 0.784 0.857
## 38 354 1 0.817 0.01860 0.781 0.854
## 39 353 2 0.812 0.01878 0.777 0.850
## 40 351 4 0.803 0.01913 0.767 0.842
## 42 347 2 0.799 0.01929 0.762 0.837
## 43 345 4 0.789 0.01962 0.752 0.829
## 44 341 2 0.785 0.01977 0.747 0.824
## 45 339 2 0.780 0.01993 0.742 0.820
## 46 337 4 0.771 0.02022 0.732 0.812
## 47 333 1 0.769 0.02029 0.730 0.809
## 48 332 2 0.764 0.02043 0.725 0.805
## 49 330 5 0.752 0.02077 0.713 0.794
## 50 325 3 0.745 0.02096 0.705 0.788
## 52 322 4 0.736 0.02121 0.696 0.779
ggsurvplot(
km_Rossi,
data = dat_Rossi,
risk.table = TRUE,
risk.table.height = 0.22,
risk.table.y.text.col = TRUE,
risk.table.y.text = FALSE,
conf.int = TRUE,
censor = TRUE,
xlab = "Thời gian theo dõi (tuần)",
ylab = "Xác suất chưa bị bắt lại",
title = "Kaplan-Meier của mẫu nghiên cứu",
break.time.by = 10,
xlim = c(0, 52),
ylim = c(0, 1),
ggtheme = theme_minimal(),
font.title = c(16, "bold"),
font.x = 13,
font.y = 13,
font.tickslab = 11
)
km_Rossi_finance <- survfit(
Surv(week, arrest) ~ fin,
data = dat_Rossi
)
summary(km_Rossi_finance)
## Call: survfit(formula = Surv(week, arrest) ~ fin, data = dat_Rossi)
##
## fin=no
## time n.risk n.event survival std.err lower 95% CI upper 95% CI
## 1 216 1 0.995 0.00462 0.986 1.000
## 2 215 1 0.991 0.00652 0.978 1.000
## 3 214 1 0.986 0.00796 0.971 1.000
## 4 213 1 0.981 0.00917 0.964 1.000
## 5 212 1 0.977 0.01023 0.957 0.997
## 6 211 1 0.972 0.01118 0.951 0.994
## 8 210 2 0.963 0.01285 0.938 0.988
## 10 208 1 0.958 0.01360 0.932 0.985
## 11 207 1 0.954 0.01430 0.926 0.982
## 13 206 1 0.949 0.01496 0.920 0.979
## 14 205 2 0.940 0.01618 0.909 0.972
## 16 203 1 0.935 0.01675 0.903 0.969
## 17 202 3 0.921 0.01832 0.886 0.958
## 18 199 2 0.912 0.01927 0.875 0.951
## 19 197 1 0.907 0.01972 0.870 0.947
## 20 196 1 0.903 0.02016 0.864 0.943
## 21 195 2 0.894 0.02099 0.853 0.936
## 23 193 1 0.889 0.02138 0.848 0.932
## 24 192 2 0.880 0.02214 0.837 0.924
## 25 190 3 0.866 0.02320 0.821 0.912
## 26 187 3 0.852 0.02417 0.806 0.901
## 27 184 2 0.843 0.02478 0.795 0.893
## 28 182 2 0.833 0.02536 0.785 0.885
## 30 180 1 0.829 0.02564 0.780 0.881
## 31 179 1 0.824 0.02591 0.775 0.876
## 32 178 1 0.819 0.02617 0.770 0.872
## 33 177 2 0.810 0.02668 0.760 0.864
## 35 175 1 0.806 0.02693 0.754 0.860
## 37 174 2 0.796 0.02740 0.744 0.852
## 38 172 1 0.792 0.02763 0.739 0.848
## 39 171 1 0.787 0.02786 0.734 0.844
## 40 170 3 0.773 0.02850 0.719 0.831
## 43 167 4 0.755 0.02928 0.699 0.814
## 44 163 2 0.745 0.02964 0.689 0.806
## 45 161 1 0.741 0.02982 0.685 0.802
## 46 160 1 0.736 0.02999 0.680 0.797
## 47 159 1 0.731 0.03016 0.675 0.793
## 48 158 1 0.727 0.03032 0.670 0.789
## 49 157 2 0.718 0.03063 0.660 0.780
## 50 155 1 0.713 0.03078 0.655 0.776
## 52 154 4 0.694 0.03134 0.636 0.759
##
## fin=yes
## time n.risk n.event survival std.err lower 95% CI upper 95% CI
## 7 216 1 0.995 0.00462 0.986 1.000
## 8 215 3 0.981 0.00917 0.964 1.000
## 9 212 2 0.972 0.01118 0.951 0.994
## 11 210 1 0.968 0.01205 0.944 0.991
## 12 209 2 0.958 0.01360 0.932 0.985
## 14 207 1 0.954 0.01430 0.926 0.982
## 15 206 2 0.944 0.01559 0.914 0.975
## 16 204 1 0.940 0.01618 0.909 0.972
## 18 203 1 0.935 0.01675 0.903 0.969
## 19 202 1 0.931 0.01730 0.897 0.965
## 20 201 4 0.912 0.01927 0.875 0.951
## 22 197 1 0.907 0.01972 0.870 0.947
## 24 196 2 0.898 0.02058 0.859 0.939
## 30 194 1 0.894 0.02099 0.853 0.936
## 32 193 1 0.889 0.02138 0.848 0.932
## 34 192 2 0.880 0.02214 0.837 0.924
## 35 190 3 0.866 0.02320 0.821 0.912
## 36 187 3 0.852 0.02417 0.806 0.901
## 37 184 2 0.843 0.02478 0.795 0.893
## 39 182 1 0.838 0.02507 0.790 0.889
## 40 181 1 0.833 0.02536 0.785 0.885
## 42 180 2 0.824 0.02591 0.775 0.876
## 45 178 1 0.819 0.02617 0.770 0.872
## 46 177 3 0.806 0.02693 0.754 0.860
## 48 174 1 0.801 0.02717 0.749 0.856
## 49 173 3 0.787 0.02786 0.734 0.844
## 50 170 2 0.778 0.02829 0.724 0.835
ggsurvplot(
km_Rossi_finance,
data = dat_Rossi,
risk.table = TRUE,
risk.table.height = 0.25,
risk.table.y.text.col = TRUE,
risk.table.y.text = TRUE,
pval = TRUE,
pval.coord = c(3, 0.18),
conf.int = TRUE,
censor = TRUE,
xlab = "Thời gian theo dõi (tuần)",
ylab = "Xác suất chưa bị bắt lại",
title = "Kaplan-Meier theo tình trạng hỗ trợ tài chính",
legend.title = "Hỗ trợ tài chính",
legend.labs = c("Không hỗ trợ", "Có hỗ trợ"),
break.time.by = 10,
xlim = c(0, 52),
ylim = c(0, 1),
ggtheme = theme_minimal(),
font.title = c(16, "bold"),
font.x = 13,
font.y = 13,
font.tickslab = 11
)
km_Rossi_fin_10 <- survfit(
Surv(week, arrest) ~ fin,
data = dat_Rossi
)
summary_10 <- summary(
km_Rossi_fin_10,
times = 10
)
km_rossi_prob <- data.frame(
group = summary_10$strata,
survival_prob = summary_10$surv,
arrest_prob = 1 - summary_10$surv
)
km_rossi_prob$arrest_percent <-
km_rossi_prob$arrest_prob * 100
km_rossi_prob
## group survival_prob arrest_prob arrest_percent
## 1 fin=no 0.9583333 0.04166667 4.166667
## 2 fin=yes 0.9722222 0.02777778 2.777778
Xác suất bị bắt lại được tính theo:
\[ P(T \leq 10) = 1 - S(10) \]
modelCox_RossiFin <- coxph(
Surv(week, arrest) ~ fin,
data = dat_Rossi
)
summary(modelCox_RossiFin)
## Call:
## coxph(formula = Surv(week, arrest) ~ fin, data = dat_Rossi)
##
## n= 432, number of events= 114
##
## coef exp(coef) se(coef) z Pr(>|z|)
## finyes -0.3691 0.6914 0.1897 -1.945 0.0517 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## exp(coef) exp(-coef) lower .95 upper .95
## finyes 0.6914 1.446 0.4767 1.003
##
## Concordance= 0.546 (se = 0.023 )
## Likelihood ratio test= 3.84 on 1 df, p=0.05
## Wald test = 3.78 on 1 df, p=0.05
## Score (logrank) test = 3.83 on 1 df, p=0.05
exp(coef(modelCox_RossiFin))
## finyes
## 0.6913776
exp(confint(modelCox_RossiFin))
## 2.5 % 97.5 %
## finyes 0.476676 1.002784
exp(coef) là Hazard Ratio (HR). HR nhỏ hơn 1 cho thấy
yếu tố liên quan đến giảm hazard bị bắt lại, trong khi HR lớn hơn 1 cho
thấy hazard tăng.
modelCox_adjusted <- coxph(
Surv(week, arrest) ~
fin + age + race + prio + educ,
data = dat_Rossi
)
summary(modelCox_adjusted)
## Call:
## coxph(formula = Surv(week, arrest) ~ fin + age + race + prio +
## educ, data = dat_Rossi)
##
## n= 432, number of events= 114
##
## coef exp(coef) se(coef) z Pr(>|z|)
## finyes -0.34523 0.70806 0.19107 -1.807 0.07079 .
## age -0.06625 0.93590 0.02072 -3.198 0.00138 **
## raceother -0.39697 0.67235 0.30763 -1.290 0.19690
## prio 0.09119 1.09548 0.02794 3.263 0.00110 **
## educ -0.20090 0.81800 0.13106 -1.533 0.12530
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## exp(coef) exp(-coef) lower .95 upper .95
## finyes 0.7081 1.4123 0.4869 1.0297
## age 0.9359 1.0685 0.8987 0.9747
## raceother 0.6724 1.4873 0.3679 1.2287
## prio 1.0955 0.9128 1.0371 1.1571
## educ 0.8180 1.2225 0.6327 1.0576
##
## Concordance= 0.648 (se = 0.027 )
## Likelihood ratio test= 33.04 on 5 df, p=4e-06
## Wald test = 31.44 on 5 df, p=8e-06
## Score (logrank) test = 32.42 on 5 df, p=5e-06
coef(modelCox_adjusted)
## finyes age raceother prio educ
## -0.34522629 -0.06624708 -0.39697417 0.09118848 -0.20089618
exp(coef(modelCox_adjusted))
## finyes age raceother prio educ
## 0.7080601 0.9358996 0.6723514 1.0954755 0.8179974
exp(confint(modelCox_adjusted))
## 2.5 % 97.5 %
## finyes 0.4868945 1.0296874
## age 0.8986600 0.9746823
## raceother 0.3679100 1.2287145
## prio 1.0370926 1.1571449
## educ 0.6326966 1.0575680
Mô hình đánh giá mối liên quan giữa hỗ trợ tài chính và thời gian bị bắt lại sau khi hiệu chỉnh cho tuổi, chủng tộc, số lần kết án trước và trình độ học vấn.
df_Rossi <- Rossi[
c(
"arrest",
"fin",
"age",
"race",
"wexp",
"mar",
"paro",
"prio",
"educ"
)
]
df_Rossi <- na.omit(df_Rossi)
summary(df_Rossi)
## arrest fin age race wexp
## Min. :0.0000 no :216 Min. :17.0 black:379 no :185
## 1st Qu.:0.0000 yes:216 1st Qu.:20.0 other: 53 yes:247
## Median :0.0000 Median :23.0
## Mean :0.2639 Mean :24.6
## 3rd Qu.:1.0000 3rd Qu.:27.0
## Max. :1.0000 Max. :44.0
## mar paro prio educ
## married : 53 no :165 Min. : 0.000 Min. :2.000
## not married:379 yes:267 1st Qu.: 1.000 1st Qu.:3.000
## Median : 2.000 Median :3.000
## Mean : 2.984 Mean :3.477
## 3rd Qu.: 4.000 3rd Qu.:4.000
## Max. :18.000 Max. :6.000
library(BMA)
model_BMA_Rossi <- bic.glm(
arrest ~ .,
data = df_Rossi,
glm.family = "binomial"
)
summary(model_BMA_Rossi)
##
## Call:
## bic.glm.formula(f = arrest ~ ., data = df_Rossi, glm.family = "binomial")
##
##
## 12 models were selected
## Best 5 models (cumulative posterior probability = 0.7985 ):
##
## p!=0 EV SD model 1 model 2 model 3
## Intercept 100 0.817350 0.81303 5.022e-01 9.561e-01 1.466e+00
## fin 14.6
## .yes -0.058569 0.16599 . . .
## age 100.0 -0.078012 0.02328 -7.796e-02 -8.305e-02 -7.692e-02
## race 3.1
## .other -0.010614 0.08693 . . .
## wexp 4.9
## .yes -0.014130 0.08348 . . .
## mar 5.0
## .not married 0.027326 0.15084 . . .
## paro 2.1
## .yes -0.002227 0.03709 . . .
## prio 75.0 0.077046 0.05457 1.046e-01 . 9.433e-02
## educ 20.8 -0.062332 0.14083 . . -2.802e-01
##
## nVar 2 1 3
## BIC -2.129e+03 -2.127e+03 -2.126e+03
## post prob 0.395 0.122 0.107
## model 4 model 5
## Intercept 6.565e-01 2.054e+00
## fin
## .yes -4.057e-01 .
## age -7.648e-02 -8.108e-02
## race
## .other . .
## wexp
## .yes . .
## mar
## .not married . .
## paro
## .yes . .
## prio 1.056e-01 .
## educ . -3.351e-01
##
## nVar 3 2
## BIC -2.126e+03 -2.126e+03
## post prob 0.095 0.079
##
## 1 observations deleted due to missingness.
par(
mfrow = c(1, 1),
mar = c(5, 5, 4, 2)
)
imageplot.bma(model_BMA_Rossi)
BMA đánh giá nhiều mô hình ứng viên thay vì phụ thuộc hoàn toàn vào một mô hình duy nhất. Các biến có xác suất hậu nghiệm cao hơn có bằng chứng mạnh hơn về vai trò dự báo.
Xét hai người:
prio = 0).prio = 1).modelCox_predict <- coxph(
Surv(week, arrest) ~ age + prio,
data = Rossi
)
summary(modelCox_predict)
## Call:
## coxph(formula = Surv(week, arrest) ~ age + prio, data = Rossi)
##
## n= 432, number of events= 114
##
## coef exp(coef) se(coef) z Pr(>|z|)
## age -0.06934 0.93301 0.02079 -3.335 0.000854 ***
## prio 0.09466 1.09928 0.02711 3.492 0.000479 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## exp(coef) exp(-coef) lower .95 upper .95
## age 0.933 1.0718 0.8958 0.9718
## prio 1.099 0.9097 1.0424 1.1593
##
## Concordance= 0.633 (se = 0.028 )
## Likelihood ratio test= 25.68 on 2 df, p=3e-06
## Wald test = 24.51 on 2 df, p=5e-06
## Score (logrank) test = 25.63 on 2 df, p=3e-06
people_con <- data.frame(
age = c(30, 35),
prio = c(0, 1)
)
people_con
## age prio
## 1 30 0
## 2 35 1
pred_cox <- survfit(
modelCox_predict,
newdata = people_con
)
pred_30 <- summary(
pred_cox,
times = 30
)
surv_30 <- as.vector(
pred_30$surv
)
pre_arrested <- 1 - surv_30
result_30 <- data.frame(
Nguoi = c("Người 1", "Người 2"),
age = c(30, 35),
prior = c(0, 1),
Xac_suat_chua_bi_bat_lai = surv_30,
Xac_suat_bi_bat_lai = pre_arrested
)
result_30
## Nguoi age prior Xac_suat_chua_bi_bat_lai Xac_suat_bi_bat_lai
## 1 Người 1 30 0 0.9329806 0.06701942
## 2 Người 2 35 1 0.9475105 0.05248945
Xác suất bị bắt lại đến tuần 30 được tính:
\[ P(T \leq 30) = 1 - S(30) \]
Theo kết quả dự báo:
## Người 1 (30 tuổi, prior = 0): 6.7%
## Người 2 (35 tuổi, prior = 1): 5.25%
library(rms)
dd <- datadist(Rossi)
options(datadist = "dd")
model_boot <- lrm(
arrest ~ fin + age + race + wexp +
mar + paro + prio + educ,
data = Rossi,
x = TRUE,
y = TRUE
)
validate_boot <- validate(
model_boot,
method = "boot",
B = 100
)
validate_boot
## index.orig training test optimism index.corrected Lower Upper
## Dxy 0.3671 0.4043 0.3316 0.0727 0.2944 0.1765 0.3952
## R2 0.1113 0.1413 0.0922 0.0491 0.0623 -0.0186 0.1281
## Intercept 0.0000 0.0000 -0.1956 0.1956 -0.1956 -0.5346 0.2311
## Slope 1.0000 1.0000 0.7876 0.2124 0.7876 0.4847 1.1701
## Emax 0.0000 0.0000 0.1019 -0.1019 0.1019 -0.0248 0.2545
## D 0.0770 0.1000 0.0629 0.0370 0.0400 -0.0225 0.0911
## U -0.0046 -0.0046 0.0047 -0.0093 0.0047 -0.0093 0.0306
## Q 0.0816 0.1046 0.0583 0.0463 0.0353 -0.0529 0.0965
## B 0.1786 0.1742 0.1825 -0.0083 0.1869 0.1672 0.2074
## g 0.7922 0.9216 0.7090 0.2125 0.5796 0.2427 0.8731
## gp 0.1376 0.1536 0.1244 0.0292 0.1083 0.0631 0.1529
## n
## Dxy 100
## R2 100
## Intercept 100
## Slope 100
## Emax 100
## D 100
## U 100
## Q 100
## B 100
## g 100
## gp 100
Bootstrap được sử dụng để đánh giá nội bộ mức độ ổn định và khả năng dự báo của mô hình thông qua việc lấy mẫu lặp lại từ dữ liệu ban đầu.
cal_boot <- calibrate(
model_boot,
method = "boot",
B = 100
)
plot(
cal_boot,
xlab = "Xác suất dự báo",
ylab = "Xác suất quan sát",
main = "Calibration Plot - Bootstrap"
)
##
## n=432 Mean absolute error=0.011 Mean squared error=0.00028
## 0.9 Quantile of absolute error=0.032
abline(
0,
1,
lty = 2,
lwd = 2
)
Đường calibration càng gần đường chéo 45 độ thì xác suất mô hình dự báo càng gần xác suất thực tế quan sát được.
db_Rossi <- Rossi[
c(
"arrest",
"fin",
"age",
"race",
"wexp",
"mar",
"paro",
"prio",
"educ"
)
]
df_model <- na.omit(db_Rossi)
summary(df_model)
## arrest fin age race wexp
## Min. :0.0000 no :216 Min. :17.0 black:379 no :185
## 1st Qu.:0.0000 yes:216 1st Qu.:20.0 other: 53 yes:247
## Median :0.0000 Median :23.0
## Mean :0.2639 Mean :24.6
## 3rd Qu.:1.0000 3rd Qu.:27.0
## Max. :1.0000 Max. :44.0
## mar paro prio educ
## married : 53 no :165 Min. : 0.000 Min. :2.000
## not married:379 yes:267 1st Qu.: 1.000 1st Qu.:3.000
## Median : 2.000 Median :3.000
## Mean : 2.984 Mean :3.477
## 3rd Qu.: 4.000 3rd Qu.:4.000
## Max. :18.000 Max. :6.000
modelBMA_testing <- bic.glm(
arrest ~
fin + age + race + wexp +
mar + paro + prio + educ,
data = df_model,
glm.family = "binomial"
)
summary(modelBMA_testing)
##
## Call:
## bic.glm.formula(f = arrest ~ fin + age + race + wexp + mar + paro + prio + educ, data = df_model, glm.family = "binomial")
##
##
## 12 models were selected
## Best 5 models (cumulative posterior probability = 0.7985 ):
##
## p!=0 EV SD model 1 model 2 model 3
## Intercept 100 0.817350 0.81303 5.022e-01 9.561e-01 1.466e+00
## fin 14.6
## .yes -0.058569 0.16599 . . .
## age 100.0 -0.078012 0.02328 -7.796e-02 -8.305e-02 -7.692e-02
## race 3.1
## .other -0.010614 0.08693 . . .
## wexp 4.9
## .yes -0.014130 0.08348 . . .
## mar 5.0
## .not married 0.027326 0.15084 . . .
## paro 2.1
## .yes -0.002227 0.03709 . . .
## prio 75.0 0.077046 0.05457 1.046e-01 . 9.433e-02
## educ 20.8 -0.062332 0.14083 . . -2.802e-01
##
## nVar 2 1 3
## BIC -2.129e+03 -2.127e+03 -2.126e+03
## post prob 0.395 0.122 0.107
## model 4 model 5
## Intercept 6.565e-01 2.054e+00
## fin
## .yes -4.057e-01 .
## age -7.648e-02 -8.108e-02
## race
## .other . .
## wexp
## .yes . .
## mar
## .not married . .
## paro
## .yes . .
## prio 1.056e-01 .
## educ . -3.351e-01
##
## nVar 3 2
## BIC -2.126e+03 -2.126e+03
## post prob 0.095 0.079
##
## 1 observations deleted due to missingness.
BMA đánh giá tầm quan trọng dựa trên mức độ hỗ trợ hậu nghiệm của các biến trong tập hợp các mô hình ứng viên.
library(glmnet)
X <- model.matrix(
arrest ~
fin + age + race + wexp +
mar + paro + prio + educ,
data = df_model
)[, -1]
Y <- df_model$arrest
modelLASSO_testing <- cv.glmnet(
x = X,
y = Y,
family = "binomial",
alpha = 1
)
modelLASSO_testing$lambda.min
## [1] 0.009327493
coef_LASSO <- coef(
modelLASSO_testing,
s = "lambda.min"
)
coef_LASSO
## 9 x 1 sparse Matrix of class "dgCMatrix"
## lambda.min
## (Intercept) 0.69196727
## finyes -0.30560446
## age -0.05763655
## raceother -0.20255291
## wexpyes -0.08735927
## marnot married 0.33353467
## paroyes .
## prio 0.08227426
## educ -0.19695614
coef_table <- data.frame(
Variable = rownames(as.matrix(coef_LASSO)),
Coefficient = as.vector(coef_LASSO)
)
coef_table <- coef_table[
coef_table$Variable != "(Intercept)",
]
coef_table$Importance <-
abs(coef_table$Coefficient)
coef_table <- coef_table[
order(
coef_table$Importance,
decreasing = TRUE
),
]
coef_table
## Variable Coefficient Importance
## 6 marnot married 0.33353467 0.33353467
## 2 finyes -0.30560446 0.30560446
## 4 raceother -0.20255291 0.20255291
## 9 educ -0.19695614 0.19695614
## 5 wexpyes -0.08735927 0.08735927
## 8 prio 0.08227426 0.08227426
## 3 age -0.05763655 0.05763655
## 7 paroyes 0.00000000 0.00000000
imageplot.bma(
modelBMA_testing
)
barplot(
rev(coef_table$Importance),
names.arg = rev(coef_table$Variable),
horiz = TRUE,
las = 1,
main = "Variable Importance - LASSO",
xlab = "|LASSO coefficient|"
)
Các biến có hệ số LASSO khác 0 được giữ lại trong mô hình. Biến có trị tuyệt đối hệ số lớn hơn có ảnh hưởng mạnh hơn trong mô hình LASSO, trong khi các biến có hệ số bằng 0 bị loại bỏ.
Việc kết hợp kết quả BMA và LASSO giúp đánh giá mức độ nhất quán trong việc xác định các yếu tố dự báo quan trọng.
Biểu đồ dưới đây thể hiện:
library(plotly)
pred_all <- summary(
pred_cox,
times = 1:30
)
risk_all <- 1 - pred_all$surv
week_values <- 1:30
risk_person1 <-
risk_all[, 1] * 100
risk_person2 <-
risk_all[, 2] * 100
plot_3D <- plot_ly()
plot_3D <- plot_3D %>%
add_trace(
x = week_values,
y = rep(1, 30),
z = risk_person1,
type = "scatter3d",
mode = "lines+markers",
name = "Người 1: age 30, prio 0",
text = paste0(
"Người 1",
"<br>Age = 30",
"<br>Prio = 0",
"<br>Tuần = ", week_values,
"<br>Xác suất = ",
round(risk_person1, 2),
"%"
),
hoverinfo = "text",
line = list(width = 5),
marker = list(size = 3)
)
plot_3D <- plot_3D %>%
add_trace(
x = week_values,
y = rep(2, 30),
z = risk_person2,
type = "scatter3d",
mode = "lines+markers",
name = "Người 2: age 35, prio 1",
text = paste0(
"Người 2",
"<br>Age = 35",
"<br>Prio = 1",
"<br>Tuần = ", week_values,
"<br>Xác suất = ",
round(risk_person2, 2),
"%"
),
hoverinfo = "text",
line = list(width = 5),
marker = list(size = 3)
)
plot_3D <- plot_3D %>%
add_markers(
x = c(30, 30),
y = c(1, 2),
z = pre_arrested * 100,
type = "scatter3d",
mode = "markers",
text = c(
paste0(
"Người 1 - Tuần 30",
"<br>Age = 30",
"<br>Prio = 0",
"<br>Xác suất bị bắt lại = ",
round(pre_arrested[1] * 100, 2),
"%"
),
paste0(
"Người 2 - Tuần 30",
"<br>Age = 35",
"<br>Prio = 1",
"<br>Xác suất bị bắt lại = ",
round(pre_arrested[2] * 100, 2),
"%"
)
),
hoverinfo = "text",
marker = list(size = 8),
name = "Kết quả tuần 30"
)
plot_3D <- plot_3D %>%
layout(
title = list(
text = "Dự báo xác suất bị bắt lại đến tuần 30",
x = 0.5
),
scene = list(
xaxis = list(
title = "Tuần",
range = c(1, 30),
dtick = 5
),
yaxis = list(
title = "Đối tượng",
tickvals = c(1, 2),
ticktext = c(
"Người 1: 30 tuổi, prio 0",
"Người 2: 35 tuổi, prio 1"
)
),
zaxis = list(
title = "Xác suất bị bắt lại (%)",
ticksuffix = "%"
),
camera = list(
eye = list(
x = 1.5,
y = 1.5,
z = 1.1
)
)
)
)
plot_3D
Phân tích dữ liệu sống còn cho phép đánh giá không chỉ việc một biến cố có xảy ra hay không mà còn xét đến thời gian xảy ra biến cố.
Kaplan-Meier và hồi quy Cox được sử dụng để mô tả và đánh giá nguy cơ theo thời gian. BMA và LASSO hỗ trợ lựa chọn và đánh giá vai trò của các biến dự báo. Bootstrap và calibration được sử dụng để đánh giá nội bộ khả năng dự báo của mô hình.
Ngoài ra, trực quan hóa 3D cho phép quan sát sự thay đổi của xác suất bị bắt lại theo thời gian đối với hai đối tượng cụ thể trong bài toán dự báo.