Data science (98)

반응형


생존분석 - 모수적 모형



Cox의 비례위험 모형


일반적으로 생존분석에 사용되는 모델인 Cox의 비례위험모형의 경우 준모수적 (Semi-parametric) 방법입니다. 이 방법은 생존함수 (Survival function)을 추정하기 위해 Hazard function에 대한 모델링을 합니다. 시간에 따라 변하는 Baseline hazard가 존재하고, Covariate 들의 effect에 따라 hazard가 달라진다고 모델링합니다. 그리고 hazard의 effect인 Hazard ratio가 시간에 따라 동일하다는 비례위험을 가정하여 Hazard function과 Survival function 을 추정하게 됩니다. 이 방법의 장점은 Survival function에 분포에 대해서 가정을하지 않기 때문에 강건하며, Covariate를 보정할 수 있다는 것입니다. 또한 Baseline hazard function이 어떤 함수인지를 알 필요가 없이 계수 추정을 통해 Hazard ratio만 구할 수 있다면 Covariate의 effect를 파악할 수 있습니다. 


모수적 모형


반면 모수적 모형은 Hazard function과 Survival function의 모양에 대해 Cox 보다 더 강한 '가정'을 합니다. 이 가정은 Hazard function과 Survival function이 어떤 분포를 따를 것이라는 믿음에서 출발합니다. 가장 많이 사용되는 모수적 모델은 Weibull 모형입니다. 


Weibull 모형의 Hazard function과 Survival function 은 다음과 같이 정의됩니다.


$$ h(t) = \lambda p t^{p-1} $$

$$ S(t) = exp(-\lambda t^p) $$ 


h(t)와 S(t)에 정의에 따라 h(t)가 저렇게 정의되면 S(t)가 저렇게 계산되는 것을 확인할 수 있습니다.


$$ \lambda = exp(\beta_0 + \beta_1 TRT) $$ 


만약 Treatment 변수에 대해 Weibull model을 만들 경우, 이 때 위와 같이 식을 놓고, beta0, beta1, p 3개의 계수를 추정하게 됩니다. 


또는 Hazard를 기준으로 계수를 추정하는 것이 아니라 Survival time을 기준으로 추정할 수 있는데, 이 경우가 모수적 방법에서 많이 사용되는 방법입니다. 이를 Acceleration Failure Time Model이라고 합니다. 


$$ S(t) = exp(-\lambda t^p) $$

$$ t = [-lnS(t)]^{1/p} \times \frac{1}{\lambda^{\frac{1}{p}}} $$

$$ \frac{1}{\lambda^{\frac{1}{p}}} = exp(\alpha_0 + \alpha_1 TRT) $$


AFT 모델에서는 위와 같이 놓고 alpha0, alpha1, p를 추정하게 됩니다. 


이렇게 두 가지 방법으로 구한 계수 beta와 alpha의 의미는 다른데, 만약 p가 고정되있다고 한다면, beta는 exponential을 취하면 Hazard ratio를 뜻하며, alpha는 exponential을 취하면 Accerleration factor가 됩니다. Acceleration factor에 대해서는 본 포스팅에서는 다루지 않을 예정이므로 자료를 참고 바랍니다. 


Strata 별로 p가 동일하다고 가정한 경우, Weibull model은 Proportional Hazard 가정과 Acceleration Failure Time 가정을 만족합니다. (https://en.wikipedia.org/wiki/Accelerated_failure_time_model)


PBC 데이터를 통한 Weibull model의 구축


pbc.dat

library(survival)

data <- read.table("pbc.dat")

# Column rename
colnames(data) <- c('id', 'futime', 'status', 'drug', 'age', 'sex', 'ascites', 'hepato', 'spiders', 'edema', 'bili', 'chol', 'albumin', 'copper', 'alk_phos', 'sgot', 'trig', 
                   'platelet', 'protime', 'stage')

head(data)
data <- data[data$drug != '.', ]
data$drug <- as.character(data$drug)
data$drug[(data$drug == 2)] = 0
data$drug <- factor(data$drug)


Drug = 0 플라시보, Drug = 1 페니실린에 대해 Death에 대한 Time to event 분석을 수행합니다.


Weibull Model Fitting

library(survival)
library(eha)

# AFT  
swei = survreg(s~drug, dist = "weibull",data = data) 

# PH  
sweiph = phreg(s~drug, dist = "weibull",data = data)

summary(swei) 
summary(sweiph)
Call:
survreg(formula = s ~ drug, data = data, dist = "weibull")
              Value Std. Error     z      p
(Intercept)  8.3167     0.1094 75.99 <2e-16
drug1       -0.0438     0.1431 -0.31  0.759
Log(scale)  -0.1532     0.0729 -2.10  0.036

Scale= 0.858 

Weibull distribution
Loglik(model)= -1348.2   Loglik(intercept only)= -1348.3
	Chisq= 0.09 on 1 degrees of freedom, p= 0.76 
Number of Newton-Raphson Iterations: 5 
n= 312 
Call:
phreg(formula = s ~ drug, data = data, dist = "weibull")

Covariate          W.mean      Coef Exp(Coef)  se(Coef)    Wald p
drug 
               0    0.491     0         1           (reference)
               1    0.509     0.051     1.052     0.167     0.759 

log(scale)                    8.317               0.109     0.000 
log(shape)                    0.153               0.073     0.036 

Events                    144 
Total time at risk        625985 
Max. log. likelihood      -1348.2 
LR test statistic         0.09 
Degrees of freedom        1 
Overall p-value           0.759387


Median Survival Time Comparison

predict(swei,newdata=data.frame(drug='0'),type=c("quantile"),se.fit=FALSE,p=0.5) predict(swei,newdata=data.frame(drug='1'),type=c("quantile"),se.fit=FALSE,p=0.5)

1: 2987.74956079141
1: 2859.63735172644



Weibull Model을 통해 구한 Survival Function과 Kaplen-Meier estimation의 비교

data$event_all=ifelse(data$status==0,0,1)
data$futime = ifelse(data$futime==0,0.1,data$futime)
s = Surv(data$futime,data$event_all)
sKM <- survfit(s ~ drug, data=data)
plot(sKM)
lines(predict(swei,newdata=list(drug='0'),type="quantile", p=seq(.01,.99,by=.01)),seq(.99,.01,by=-.01),col='red')
lines(predict(swei,newdata=list(drug='1'),type="quantile", p=seq(.01,.99,by=.01)),seq(.99,.01,by=-.01),col='red')

위 그림에서 검은색 직선이 Kaplen-Meier Survival function estimation이며, 붉은색과 파란색이 Weibull 모델로 추정한 Survival function 입니다. Weibull 모델의 S(t)의 모양에 대한 가정이 맞다면 두 직선은 가까울 것입니다. 그리고 위 직선들은 p가 같다는 가정하에 구해진 직선들입니다. 즉, PH, AFT 가정을 한 후에 그려진 직선입니다. 그렇기 때문에 Weibull 모형의 Survival function에 대한 가정, 그리고, PH, AFT 가정을 해도 될지에 대해서 체크를 해보아야합니다.



Weibull 가정의 체크 


(https://stat.ethz.ch/education/semesters/ss2011/seminar/contents/handout_9.pdf)


Weibull 모형에서 가정을 체크하는 방법은 X 축을 log(t), Y 축을 log(-log(S(t)) 로 그래프를 그려보는 것입니다. 이 때, S(t)는 Kaplen-Meier 방법으로 구한 Survival function 입니다. 이 때, 그룹간의 그래프의 모양을 보고 Weibull 생존모형 가정이 맞는지, 또한 두 그룹에서 PH, AFT 가정이 맞는지를 체크할 수 있습니다. 


먼저, 두 그룹의 직선이 평행하게 나오면 Weibull 가정을 만족합니다. 그렇지 않으면 Weibull 가정이 만족되지 못하며 AFT 가정도 만족되지 못합니다. 또한 두 그룹의 기울기의 비가 일정하면 PH 가정을 만족합니다. 


sKM <- survfit(s~ drug, data=data)
kmfit.TRT1 = summary(sKM)
kmfit.TRT2 = data.frame(kmfit.TRT1$strata, kmfit.TRT1$time, kmfit.TRT1$surv)
names(kmfit.TRT2) = c("TRT","time","survival")
TRT0=kmfit.TRT2[kmfit.TRT2$TRT=="drug=0", ]
TRT1=kmfit.TRT2[kmfit.TRT2$TRT=="drug=1", ]
plot(log(TRT0$time), log(-log(TRT0$survival)), pch=16, xlab="time in days using log-arithmic scale", ylab="log-log survival",type="p", xlim=c(3,10), ylim=c(-6,1), font=2, lwd=2, font.lab=2, col="Black",main="log-log curves by treatment")
par(new=T)
plot(log(TRT1$time), log(-log(TRT1$survival)), pch=3, col="grey50", ylab="",xlab="",  xlim=c(3,10), ylim=c(-6,1), font=2, lwd=2, font.lab=2)


이 그래프의 경우 우선 그룹에서 거의 직선이라는 것을 확인할 수 있지만, 두 그래프가 평행하지는 않습니다. (교차가 일어납니다.) 그렇기 때문에 Weibull 가정을 만족하지만 PH 가정과 AFT 가정을 만족하지 않으며, 두 그룹에서 p가 다르다는 알 수 있습니다.



반응형
반응형


Time-dependent variable의 정의 


Definition : 생존 분석에 있어서 시간에 따라 변수의 값이 바뀌는 변수를 time-dependent variable이라고한다. 


예 : 흡연 여부, 직장에서의 지위 등


Extended cox model : Time-dependent variable을 생존분석에서 사용하는 방법 


개념 : 만약 시간에 따라 변수의 값이 변화하는 변수가 있다면 extended cox model을 수행하여야한다. 


- 기존 데이터의 형태


ID
clinic
event
time
prison
dose
111428050
211275155
311262055
411183030
511259165
611714055

- Extended cox model을 위한 데이터의 형태


ID
clinic
prison
dose
ID2
start
time
event
110501070
1105017130
11050113170
11050117190
11050119260
11050126290

모든 time에 대해 데이터를 쪼개서 start와 time으로 정의한다. 하나의 row를 시간에 따라 쪼개므로 한 사람당 여러개의 row가 생기게 된다. 만약 해당 시간 내에서 event가 발생한 경우, event는 1이된다.


library(data.table)
library(survival)
data <- read.csv("addict.csv")

Extended cox model을 위한 데이터의 형태 만드는 법

data.cp <- survSplit(data, cut=data$time[data$event==1], end="time", event="event", start="start", id="ID2")

만약 아래와 같이 logdose라는 time-dependent variable이 있다고 하면 

data.cp$logdose <- data.cp$dose * log(data.cp$time)

Extended cox model 은 아래와 같이 수행할 수 있다.

Y = Surv(data.cp$start, data.cp$time, data.cp$event) coxph(Y ~ clinic + logdose +prison+ cluster(ID2), data=data.cp)


Time-dependent variable의 활용 1 : PH (proportional hazard) Assumption check


개념 : PH Assumption에 위반이 되는 것이 의심되는 변수가 있을 때, 이 변수에 대한 time-dependent variable을 정의함으로서 PH 가정을 체크할 수 있다. 


ID
clinic
event
time
prison
dose
111428050
211275155
311262055
411183030
511259165
6117140

55

만약에 위와 같은 데이터에 대해서 dose에 대해 PH Assumption 가정이 위반된다고 해보자. 즉, 이말은 시간에 따라 dose의 hazard ratio가 달라진다는 것이다. 이를 테스트하기위해 dose*g(t)라는 새로운 변수를 정의하고 이 변수의 계수가 유의한지 확인하는 방법을 통해 해당 변수에 대한 PH Assumption을 체크할 수가 있다. 


Y = Surv(data.cp$start, data.cp$time, data.cp$event)
coxph(Y ~ clinic + dose + logdose +prison+ cluster(ID2), data=data.cp)
Call:
coxph(formula = Y ~ clinic + dose + logdose + prison + cluster(ID2), 
    data = data.cp)

            coef exp(coef) se(coef) robust se     z       p
clinic  -1.01988   0.36064  0.21542   0.23637 -4.31 1.6e-05
dose    -0.08262   0.92070  0.03598   0.02960 -2.79  0.0053
logdose  0.00862   1.00865  0.00645   0.00525  1.64  0.1007
prison   0.34063   1.40584  0.16747   0.15972  2.13  0.0329

Likelihood ratio test=66.35  on 4 df, p=1e-13
n= 18708, number of events= 150 
   (1379 observations deleted due to missingness)


위 결과에서 logdose의 p-value > 0.05이므로, dose가 PH Assumption을 만족한다고 결론내릴 수 있다. 위 방법은 Wald test를 한 것이며, 다른 방법으로는 Likelihood ratio test를 통해 p-value를 구할 수도 있다. 


Likelihood ratio test

Y = Surv(data.cp$start, data.cp$time, data.cp$event)
mod1 <- coxph(Y ~ clinic + dose + logdose +prison+ cluster(ID2), data=data.cp)
mod2 <- coxph(Y ~ clinic + dose +prison+ cluster(ID2), data=data.cp)

print(mod1$loglik[2])
print(mod2$loglik[2])

LRT <- (-2) * (mod2$loglik[2]-mod1$loglik[2])
pvalue <- 1 - pchisq(LRT, 2) 

이는 logdose를 포함한 full model과 logdose를 포함하지 않은 restricted model의 likelihood ratio를 구하고 이것이 카이제곱 분포를 따른다는 것을 이용한 검정이다. p-value를 계산한 결과 0.4 정도로 위의 wald test와 마찬가지로 logdose는 의 계수는 유의하지 않았다. 


따라서 dose에 대해 PH Assumption이 어긋나지 않는다고 결론 내릴 수 있다.



Time-dependent variable의 활용 2 : PH Assumption 만족 안하는 경우, 시간에 따라 달라지는 Hazard ratio 모델링


개념 : 어떤 변수에 대하여 heavy side function을 이용한 time-dependent variable을 정의함으로서 시간에 따라 달라지는 hazard ratio를 모델링할 수 있다. 



heavy side function은 어떤 값을 기준으로 그 이상일 때는 1, 미만일 때는 0을 돌려주는 함수를 말한다. 


예제 : 만약 clinic에 대해 시간에 따라 달라지는 HR을 모델링 하고 싶다고 해보자. 


fit <- survfit(Surv(data$time, data$event)~data$clinic)
plot(fit)

이것이 clinic=1과 clinic=2일 때 각각 그린 카플란 마이어 생존함수 추정값이다. 위 그림에서 hazard ratio가 시간에 따라 바뀐다는 것이 의심스러울 수 있다. 이 때, 어떤 시점을 기준으로 heavy side function을 이용한 time-dependent variable을 정의함으로써 이를 모델링할 수 있다. 


365를 기준으로 데이터를 쪼갠다. 

data.cp365 <- survSplit(data, cut=365, end="time", event="event", start="start", id="ID2")
ID
clinic
prison
dose
ID2
start
time
event
11050103650
1105013654281
21155202751
31055302621
41030401831
51165502591
data.cp365$hv1 <- data.cp365$clinic * (data.cp365$start < 365)
data.cp365$hv2 <- data.cp365$clinic * (data.cp365$start >= 365)

위와 같이 두 개의 heavy side function을 원래 clinic의 값에 곱해준 것을 두 개의 변수로 정의한다.  


ID
clinic
prison
dose
ID2
start
time
event
hv1
hv2
1105010365010
110501365428101
2115520275110
3105530262110
4103040183110
5116550259110
6105560365010
610556365714101

Extended cox model

Y365 <- Surv(data.cp365$start, data.cp365$time, data.cp365$event)
coxph(Y365 ~ dose + hv2 + hv1 + prison + cluster(ID2), data=data.cp365)


Call:
coxph(formula = Y365 ~ dose + hv2 + hv1 + prison + cluster(ID2), 
    data = data.cp365)

           coef exp(coef) se(coef) robust se     z       p
dose   -0.03548   0.96514  0.00643   0.00652 -5.44 5.3e-08
hv2    -1.83052   0.16033  0.38595   0.39838 -4.59 4.3e-06
hv1    -0.45937   0.63168  0.25529   0.25998 -1.77   0.077
prison  0.37795   1.45929  0.16841   0.16765  2.25   0.024

Likelihood ratio test=74.25  on 4 df, p=3e-15
n= 360, number of events= 150 


이 때 결과를 보면 hv1의 HR은 0.63, hv2의 HR은 0.16이다. 이 말은 clinic 1과 clinic2의 hazard ratio가 365미만에서는 0.63이었는데, 365 이상에서는 0.16이라고 해석할 수 있다. 즉, 두 clinic에서 보이는 생존률에 대한 경향성이 시간이 지날 수록 강해지고 있는 것이다. 이는 위의 카플란 마이서 생존곡선에서도 확인할 수 있다. 


반응형
반응형


Cox 비례위험 모형의 가정 체크


개념 : Cox 비례위험 모형은 "비례위험 가정" 을한다. 


비례위험가정은 시간에 따라 어떤 변수에서의 Hazard ratio가 일정해야한다는 것이다.

비례위험가정이 어긋나면, Stratified cox regression 또는 time-dependant variable 정의를 통한 extended cox regression을 수행할 수 있다. 


비례위험 가정의 체크는 아래방식으로 할 수 있다. 


1. Log-log plot

2. Observed-expected plot

3. Goodness of fit test


본 포스팅에서는 R의 survival, survminer 패키지를 통한 실습을 통해 cox 비례 위험 모형의 가정을 체크하는 방법을 알아본다. 


addict.csv


library(data.table)
library(survival)
data <- read.csv("addict.csv")

head(data)
ID
clinic
event
time
prison
dose
111428050
211275155
311262055
411183030
511259165

먼저 데이터의 형태는 위와 같이 생겼다. 


관심변수 : clinic 에 대하여 Kaplan-Meier 플롯 그리기

# Treatment 별로 그룹지어서 KM Estimation
fit = survfit(y~clinic, data=data)
par(mai=c(1,1,1,1))
plot(fit,main="KM Curve", xlab="Time(Week)", ylab=expression(paste(hat(S),"(t)")), col=c("blue", "red"))


우리는 이것이 비례위험 가정을 만족하는지를 확인하고 싶다. 비례위험 가정을 만족하려면 모든 timepoints에서 Hazard ratio가 같아야한다. hazard란 f(t)/S(t) (참고 : https://3months.tistory.com/349?category=743476) 로 위 그림만 봐서는 가정을 만족하는지 한 눈에 알 수 없다.  


로그로그 플롯


개념 : 로그로그 플롯을 그리고 그룹간에 평행하게 나오면 비례위험가정을 만족한다. 

plot(fit, fun="cloglog", lty=1:2, col=c("Black", "Grey50"), lwd=2, font=2, ylim=c(-3,2), font.lab=2, main="log-log KM curves by Rx", ylab="log-log survival", xlab="time in weeks using logarithmic scale")
legend("bottomright",lty=1:2,legend=c("Group1","Group2"),bty="n", text.font=2, lwd=2, col=c("Black", "Grey50"))


관찰값-기댓갓 플롯


개념 : Kaplen-Meier 생존 함수와 Cox regression을 통해 구한 생존함수를 동시에 그려본다.


이 때, Expected plot은 Cox 비례위험 모형에서 나오는 생존함수로 관찰한 생존함수와 모양의 차이가 많이나면 비례위험 가정을 만족하지 않는 것이다. 

kmfit <- survfit(y~clinic, data=data)
#observed
plot(kmfit, lty="dashed", col=c("Black", "Grey50"), lwd=2, font=2, font.lab=2, main="Observed Versus Expected Plots by Clinic", ylab="Survival probability", xlab="Survival time")
par(new=T)
#expected
exp <- coxph(y~clinic, data=data)
new_df <- data.frame(clinic=c(1,2))
kmfit.exp <- survfit(exp, newdata=new_df)
plot(kmfit.exp, lty="solid", col=c("Black", "Grey50"), lwd=2, font=2, font.lab=2)



Goodness of fit test


개념 : Goodness of fit test(GoF Test) 는 관찰값-기댓값의 차이를 통계적으로 검정하는 방법이다. (카이스퀘어 분포 이용)

# Gooodness of fit test
mod1 <- coxph(y~clinic, data=data)
cox.zph(mod1, transform=rank)

plot(cox.zph(mod1, transform=rank), se=F, var="clinic")
abline(h=0, lty=3)
plot(cox.zph(mod1, transform=rank), se=F, var="prison")
abline(h=0, lty=3)


        rho chisq       p
clinic -0.255  10.5 0.00118

p-value가 0.001이므로 clinic 변수는 비례위험 가정을 만족하지 않는다. 이는 그림을 통해서도 확인할 수 있다. 위 그림에서 직선이 평행하지를 확인하면되는데, 직선은 추정된 beta값을 의미하는데 직선이 평행하지 않고 어떠한 경향성이 보이면 beta 값이 시간에 따라 바뀐다는 의미로 비례위험 가정에 어긋난다. 




참고 : https://www.r-bloggers.com/cox-model-assumptions/

반응형
반응형


Stratified Cox 비례위험모형


개념 : 비례위험 가정을 만족하지 않는 변수의 경우, 층화를 하여서 분석하여야함


비례 위험 가정이란 ? => Hazard ratio가 시간에 따라 모두 같아야한다는 것


기본적인 Cox 비례위험모형의 식은 다음과 같이 쓸 수 있다. 두 가지 변수 dose와 Sex 가 있다고 해보자. (각각 연속형, 범주형 변수이다.)


$$ h(t, X) = h_0(t)exp(\beta_1 dose + \beta_2 Sex) $$


예를 들어, 성별 (Sex)에 대해서 비례위험 가정이 만족하지 않는다고 해보자. 


$$ h_{1} (t, X) = h_{1}(t)exp(\beta_1 dose) $$

$$ h_{2} (t, X) = h_{2}(t)exp(\beta_1 dose) $$


그러면 위와 같이 Sex에 따라 따로 따로 모형을 fitting 시키는 것이 Stratified Cox regression의 기본 개념이라고 할 수 있다. 또한 두 식의 dose에 대한 beta 값이 같다는 것을 확인할 수 있다. Sex에 대해 층화를 한 후, 공통 beta 값을 추정하는 것이라고 할 수 있다. baseline hazard 인 h(t) 값만 두 식에서 다르게 추정한다. 이는 Sex의 hazard ratio를 추정하는 것이 아니라 비모수적 방법으로 각각의 Sex의 h(t)를 추정하는 것으로 이해할 수 있다. 


R에서의 구현 (survival 라이브러리)


coxph(Surv(time, event) ~ dose + strata(sex), data=data)


Stratified cox 모형의 한 가지 이슈는 층화한 변수가 다른 변수와 교호작용이 있는 경우이다. 이 경우에는 두식에서 공통된 beta를 추정하는 것이 아니라, 각각의 beta를 추정하는 것이 좋다. 이를 Interaction model이라고 한다. 


$$ h_{1} (t, X) = h_{1}(t)exp(\beta_{1} dose) $$

$$ h_{2} (t, X) = h_{2}(t)exp(\beta_{2} dose) $$


Interaction model은 R에서 다음과 같이 각각의 strata 별로 모델을 따로 만들어주면 된다. 
coxph(Surv(time, event) ~ dose, data=data[data$sex== 0,])
coxph(Surv(time, event) ~ dose, data=data[data$sex== 1,])

또는 아래와 같은 방식으로 표현할 수 있다.


$$ h_g (t, X) = h_g (t)exp(\beta_{1} dose + \beta_2(Sex*dose)) $$


위 식에서 (Sex=0 or 1) 이고, Sex=1일 때, beta2 값이 beta1 값과 더해져 dose의 beta가 된다. 이렇게 식을 쓰면 beta2를 이용하여 교호작용이 유의한지에 대한 검정을 할 수 있다. 교호작용을 검정하는 방법에는 두 가지 방법이 있다.


1. Wald test : 교호작용에 대한 beta값이 통계적으로 유의한지 검정

2. Likelihood ratio test : 두 모델의 likelihood ratio를 이용해 likelihood의 증가값이 통계적으로 유의한지 검정


결론적으로 Stratified cox regression 의 장점과 단점은 아래와 같이 요약해볼 수 있다.


장점 : PH 가정이 맞지 않는 변수에 대하여 층화 (Stratification)를 수행하여 분석하기 때문에, 다른 계수 추정을 더욱 신뢰성 있게 할 수 있다. 

단점 : 층화를 한 변수에 대해서는 HR을 추정할 수 없다. 층화한 변수와 다른 변수와의 교호작용을 고려하여야한다. 교호작용이 있는 경우 추정된 계수값은 바이어스가 생긴다. 







반응형
반응형

Competing Risk를 고려한 생존 분석


Competing risk 분석은 생존분석에서 관심 event 외의 다른 event가 있을 때, 분석하는 방법입니다. 예를 들어, 특정 약이 폐암으로 인한 사망을 줄이는가에 대해 관심을 갖고 연구하려고 하는데 심혈관 질환, 뇌혈관 질환 등으로 사망한 경우 Competing risk 분석을 통해 이 약이 폐암으로 인한 사망은 줄여도, 다른 사망에 대해서는 반대의 효과를 줄 수 있기 때문에 이를 확인할 필요가 있습니다.


Competing risk는 기본적인 생존분석 모형의 확장된 버전입니다. 데이터의 형태는 기본 생존 분석의 [time to event, event( censoring, event 를 나타내는 변수)]를 따르지만, vent가 censoring, event 0/1 로 나누어진 것이 아니라, 3개 이상의 범주형 변수를 갖게 됩니다. 


R의 경우 timereg, cmprsk 를 이용하여 competing risk 분석을 수행할 수 있습니다. 


먼저 데이터를 읽어옵니다. 

fol <- read.csv("data.csv", header=TRUE)

age
path1
hgb
ldh
clinstg
blktxcat
relsite
ch
rt
survtime
stat
dftime
dfcens
resp
stnum
56NH04140NA21BY0.698152010.2381930181CR1
36NH02130NA21DY14.5023956112.4188911701CR2
39NH02140NA23YY4.914442210.0027378511NR3
37NH03140NA11Y15.6851472115.6851471591CR4
61NH04110NA22Y0.235455210.0027378511NR5
69NH02120NA11Y8.418891218.4188911701CR6

이 데이터에는 1,2 두 가지의 사망원인이 있습니다. 


cause
  0   1   2 
193 272  76 



1. 관심 사건 외 다른 이벤트들을 censoring으로 취급하여 분석

library(data.table)
fol <- setDT(fol)

fol$y1 = fol$cause
fol$y2 = fol$cause
fol[cause==2, y1:=0]
fol[cause==1, y2:=0]
fol[y2==2 , y2:=1]

원래는 0이 censoring 인데, 관심요인이 1일 때는 2를 censoring, 관심요인이 2일 때는 1을 censoring으로 바꾸어주는 코드입니다. 이 때, data.table으로 dataframe으로 변환한 후, := 키워드를 이용하였습니다.


① Cause = 1에 대한 Model (Cause=2 를 Censoring 취급)

=> age, hgb, clinstg를 보정해서 blktxcat의 effect 파악

library(survival)

cause1 <- Surv(fol$dftime, fol$y1)
cox1 <- coxph(cause1 ~ age+hgb+blktxcat+clinstg, data=fol)


Call:
coxph(formula = y0 ~ age + hgb + blktxcat + clinstg, data = fol)

  n= 541, number of events= 272 

             coef exp(coef) se(coef)     z Pr(>|z|)    
age      0.023784  1.024069 0.004733 5.025 5.02e-07 ***
hgb      0.003078  1.003083 0.004075 0.755 0.449974    
blktxcat 0.207383  1.230454 0.057329 3.617 0.000298 ***
clinstg  0.329831  1.390733 0.138171 2.387 0.016981 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

         exp(coef) exp(-coef) lower .95 upper .95
age          1.024     0.9765    1.0146     1.034
hgb          1.003     0.9969    0.9951     1.011
blktxcat     1.230     0.8127    1.0997     1.377
clinstg      1.391     0.7190    1.0608     1.823

Concordance= 0.623  (se = 0.019 )
Rsquare= 0.082   (max possible= 0.997 )
Likelihood ratio test= 46.23  on 4 df,   p=2e-09
Wald test            = 45.16  on 4 df,   p=4e-09
Score (logrank) test = 45.84  on 4 df,   p=3e-09



② Cause = 2에 대한 Model (Cause=1 를 Censoring 취급)

=> age, hgb, clinstg를 보정해서 blktxcat의 effect 파악

cause2 <- Surv(fol$dftime, fol$y2)

cox2 <- coxph(cause2 ~ age+hgb+blktxcat+clinstg, data=fol)

summary(cox2)
Call:
coxph(formula = cause2 ~ age + hgb + blktxcat + clinstg, data = fol)

  n= 541, number of events= 76 

             coef exp(coef) se(coef)     z Pr(>|z|)    
age      0.087125  1.091033 0.011440 7.616 2.62e-14 ***
hgb      0.005945  1.005962 0.008452 0.703    0.482    
blktxcat 0.164626  1.178952 0.109133 1.508    0.131    
clinstg  0.353410  1.423915 0.285801 1.237    0.216    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

         exp(coef) exp(-coef) lower .95 upper .95
age          1.091     0.9166    1.0668     1.116
hgb          1.006     0.9941    0.9894     1.023
blktxcat     1.179     0.8482    0.9519     1.460
clinstg      1.424     0.7023    0.8132     2.493

Concordance= 0.764  (se = 0.039 )
Rsquare= 0.131   (max possible= 0.759 )
Likelihood ratio test= 75.68  on 4 df,   p=1e-15
Wald test            = 62.84  on 4 df,   p=7e-13
Score (logrank) test = 67.68  on 4 df,   p=7e-14



2. Cumulative incidence curve를 통한 분석


Cumulative incidence curve의 정의 


개념 : Cumulative incidence curve란 competing risk를 고려한 1-생존함수 의 추정값 이다. 


$$ CIC_c(t) = P(T_c \lt t) $$


위 식에서 CIC란 어떤 사람의 c라는 event의 발생 시각인 Tc가 t보다 작을 확률입니다. 만약 competing risk가 없다면 이것은  간단하게 계산됩니다. 일반적으로 competring risk 가 없는 상황에서는 이것은 1 - (Kaplen-Meier 생존함수)로 추정하게 됩니다. 하지만 competing risk가 있는 경우, 다른 원인으로도 사람이 죽을 수 있기 때문에 Kaplen-Meier 방법을 그대로 사용하면 특정 시점 t 이전에 event 가 발생했을 확률이 과대추정됩니다. 


CIC 방법에서는 proportion of dying을 아래와 같은 방식으로 추정하게 됩니다. 


$$ CIC_c(t) = \int_{0}^{t} h_c(u)S(u) du $$


이 방식을 직관적으로 이해하면 Incidence를 모든 t에 대해서 더해준다고 이해할 수 있는데 incidence는 특정 시점에서의 cause-specific hazard와 생존함수를 곱해준 값입니다. 이 때, 생존함수는 인구집단에서의 생존함수입니다. 만약 이 생존 함수를 해당 cause에 대한 생존함수를 사용한다면 1-KM과 같은 값이 나오게 됩니다. 하지만 인구집단에서의 생존함수를 사용하여 competing risk를 고려하는 것으로 이해할 수 있습니다. 


Cumulative incidence curve는 cmprsk 라는 라이브러리를 통해 분석할 수 있습니다. Cumulative incidence는 cause-specific hazard function으로 계산되며, proportion of dying을 계산해줍니다. 이 때, 관심 요인 blktxcat을 지정해줍니다. blktxcat을 약의 종류라고 생각을하고 0,1,2,3 총 4개의 약의 종류가 있는 것입니다. 이 4개의 약이 1,2 두 가지 사망 원인에 어떻게 작용하는지를 아래 표를 통해 확인할 수 있습니다=> 각각의 strata 별로 proportion of dying의 예측값을 보여주고 있습니다. 


예를 들어, 25달이 지난 후, 사망원인 1을 보면, 0의 약을 쓴 사람은 52%가 죽은 반면, 3 약을 쓴 사람은 66%가 죽었습니다.  

library(cmprsk)
CIC <- cuminc(fol$dftime, fol$cause, fol$blktxcat)
CIC
Tests:
       stat           pv df
1 17.189363 0.0006461085  3
2  4.596607 0.2038333549  3
Estimates and Variances:
$est
             5         10         15        20        25        30
0 1 0.28456914 0.40301775 0.47654623 0.5235252 0.5235252 0.5235252
1 1 0.36620667 0.44808409 0.47719815 0.5096313 0.5541112        NA
2 1 0.42528724 0.54412907 0.59678622 0.5967862 0.5967862        NA
3 1 0.50604626 0.63733974 0.66670849 0.6667085 0.6667085        NA
0 2 0.02540834 0.08048914 0.15465458 0.1546546 0.1546546 0.2619280
1 2 0.11604642 0.16329519 0.18920323 0.2309031 0.2679696        NA
2 2 0.05245607 0.07941283 0.13288099 0.2003667 0.2409361        NA
3 2 0.03960396 0.06897272 0.09834147 0.1374998 0.2353957        NA

$var
               5           10          15          20          25          30
0 1 0.0010438691 0.0013684404 0.001665324 0.002070841 0.002070841 0.002070841
1 1 0.0022693095 0.0025757378 0.002723652 0.003459139 0.004840443          NA
2 1 0.0018165618 0.0021166396 0.002288543 0.002288543 0.002288543          NA
3 1 0.0025253539 0.0027149325 0.002701947 0.002701947 0.002701947          NA
0 2 0.0001266488 0.0004372677 0.001007219 0.001007219 0.001007219 0.006742183
1 2 0.0010075372 0.0014431850 0.001683726 0.002346285 0.003481490          NA
2 2 0.0003774854 0.0005948500 0.001226766 0.002385591 0.003610060          NA
3 2 0.0003819491 0.0007880136 0.001162941 0.001791598 0.011245328          NA


plot(CIC, xlab="month", ylab="proportion dying")



위와 같이 그림도 그릴 수 있습니다. 위쪽에 위치한 4개의 그래프가 사망원인 1에 대한 4가지 약의 효과 그래프이고, 아래쪽에 있는 4개의 그래프가 사망원인 2에 대한 것입니다. 전반적으로 사망원인 1로 죽는 사람이 많다는 것을 확인할 수 있습니다. 또한 약의 경우 사망원인 1에 대해 어느 정도 연관성이 있는 것으로 보입니다. 각 4개의 약에 대해 proportion of dying에 차이를 보여줍니다. 하지만 사망원인 2에 대해서는 약과 별로 상관 없는 것을 확인할 수 있습니다. 



3. Conditional probability function

library(Cprob)
CPC <- cpf(Hist(dftime, cause)~blktxcat, data=fol, failcode=1)
CPC
plot(CPC, xlab="month", ylab="proportion dying")

Conditional probability function도 마찬가지로 그릴 수 있습니다. 이 때, failcode로 관심 event를 지정해줍니다. 


4. Proportional-odds Model for the Conditional Probability Function

CPC_reg=cpfpo(Hist(dftime, cause)~blktxcat+age, data=fol, failcode=1, tis=seq(0, 70, 5)) CPC_reg

Warning message:

“glm.fit: algorithm did not converge”

Test for non-significant effect 

                  stat       pvalue

(Intercept) -26.769122 0.000000e+00

blktxcat      3.952040 7.748788e-05

age           5.041975 4.607511e-07


 Test for constant fit 

                   coef     exp.coef     SE.coef       stat     pvalue

(Intercept) -9.51827834 7.349609e-05 0.355569317 -24.964365 0.00000000

blktxcat     0.27674405 1.318829e+00 0.070025626   1.790873 0.07331363

age          0.02991248 1.030364e+00 0.005932691  10.309364 0.00000000


Conditional probability function의 proportional odds 모델을 이용하면 regression을 통해 각 factor들의 odds ratio를 구할 수 있습니다. 



data.csv



데이터 출처


Thomas H. Scheike, Mei-Jie Zhang

Title: Analyzing Competing Risk Data Using the R timereg Package


Journal of statistical software

https://www.jstatsoft.org/article/view/v038i02

반응형
반응형


생존분석은 왜 하는가?

생존분석은 Censoring을 고려하여 Time to event에 대해 분석하기 위해 수행한다. 어떤 약의 효과를 판단한다고 해보자. 만약에 암에 걸린 사람을 대상으로 A라는 약을 처방하였는데, 이 약의 효과를 판단하기 위해서 여러가지 디자인을 해볼 수 있다. 

생존분석의 접근법은 약을 처방 받은 그룹 X, 처방받지 않은 그룹 Y에 대해서 생존 시간을 비교하고, 이 생존시간의 차이가 유의한지를 확인한다. 그럼 T-test로 할 수 있다고 생각할 수 있지만, 생존분석에서는 Censoring을 고려한다. 이것이 무슨말이냐하면 중도탈락한 데이터라도 그 데이터가 있었던 시점까지의 정보는 활용한다는 것이다. 생존분석은 중도절단된 자료의 부분적 정보를 최대한 이용한다.

즉, 기존 통계 모형을 쓰지 않고 생존분석을 쓰는 이유는 다음과 같이 두 가지로 정리할 수 있다.

1. Time to event를 알고 싶고,

2. Censoring 데이터를 고려하고 싶을 때


이는 linear regression, t-test, logistic regression 등의 다른 통계적 방법으로는 해결할 수 없다.

또한 생존분석의 목적은 다음과 같이 정리할 수 있다.

1. 어떤 사람의 Time to event를 예측 하고 싶을 때
2. 둘 이상의 그룹 간의 Time to event (생존예후) 를 비교하고 싶을 때
3. 변수들이 Event (생존)에 미치는 영향 파악 및 비교

Censoring이란 무엇인가?

Censoring은 생존분석에서 중요한 개념으로 두 종류로 나누어볼 수 있다.

1. left censoring : 관찰 기간보다 event가 발생 시각빠른 경우를 말한다.  

● 만약, 나무늘보가 언제 나무에서 내려오는지를 관찰하려고 한다. 근데 나무늘보는 항상 사람이 잠드는 새벽시간에만 땅으로 내려온다고 해보자 (예를 들어, 5am 정도). 그리고 사람은 아침 9시에 일어나서 나무늘보를 관찰한다. 그렇다면 사람은 평생 나무늘보다 땅으로 내려오는 것을 관찰할 수 없을지도 모른다. 이는 관찰기간 (9am~) 보다 event의 발생시각(5am) 이 전에 있기 때문이다. 
● 언제 담배를 처음 피었는가?
● 치매의 발생 (언제 정확히 발생했는지 알기 힘들다.)

2. right censoring :   관찰기간보다 event 발생 시각느린 경우를 말한다. 

● 가장 일반적인 censoring의 의미이다. censoring하면 보통 right censoring을 의미하는 경우가 많다. 
● 연구자는 어떤 연구 참여자를 평생 관찰할 수 없다. 예를 들어, 흡연자와 비흡연자의 폐암 발생까지의 시간을 비교하는 연구를 해본다고 해보자. 흡연자가 생각보다 건강해서 100살 넘도록 살수도 있을 것이다. 하지만 100년 넘도록 폐암의 발생여부를 주기적으로 관찰하는 것은 매우 어렵다. 따라서 적절한 시점에서 연구 종료를 선언하고, 지금까지 수집된 정보를 바탕으로 흡연자와 비흡연자를 비교하는 것이 적절할 것이다. 또는 중간에 폐암이 아닌 다른 원인으로 사망한다거나, 더 이상의 연구 참여를 하지 않겠다고 통보할 수도 있다. 이러한 경우를 right censoring 이라 한다. 
● 즉, right censoring이 발생하는 경우는 다음과 같은 상황을 예로 들어볼 수 있다. -> 스터디의 종료, 관심 event가 아닌 이유로 사망, 중도탈락
● 실제 분석 시, right censoring 이 있는 경우, 그 사람의 정보가 어떤 특정시점 t까지는 available 한 것을 이용하게 된다. 이러한 right censoring을 활용하는 것이 생존분석의 강점이라고 할 수 있다.

생존분석 관련 함수

생존분석 함수는 개인의 생존시간 T가 확률변수 (random variable) 라고 생각했을 때 이와 관련된 함수를 의미한다.

Survival function
S(t) = P(T > t) : 특정 시점 t에서 살아 있을 확률을 나타내는 함수이다. 즉, 이것은 event time T가 t보다 클 확률이다. 

F(t) : 특정시점 t까지 event가 발생했을 확률을 말한다. 이는 1-S(t)이다. f(t)의 cdf (cumulative density function)이다.
f(t) : 특정 시점 t에서 event가 발생할 확률을 나타내는 함수이다. (이것은 probability density function 이다.) 그리고 f(t)는 F(t)의 t에 대한 미분이다.

Hazard function
h(t) : t까지 살았을 때, 직후에 바로 event가 일어날 조건부 확률을 나타낸다.

h(t) = f(t)/S(t) 로 나타내어 지는데, 아래 식을 통해 확인해 보자.



생존분석 관련 함수의 정리


$$ S(t) = P(T> t) $$

$$ F(t) = 1-S(t) = P(T \leq t) $$

$$ f(t) = F'(t) $$

$$ h(t) = \lim_{\Delta{t}\to\ 0}P(t\leq T<t+\Delta{t} | T > t) = \frac{f(t)}{S(t)} $$

why? 직접 f(t)/S(t) 를 계산해보면 조건부 확률의 계산 공식을 통해 양변이 같다는 것을 알 수 있다.


$$ f(t) = \lim_{\Delta{t}\to\ 0}P(t<T<t+\Delta{t}) $$

$$ \frac{f(t)}{S(t)} =  \frac{\lim_{\Delta{t}\to\ 0}P(t<T<t+\Delta{t})}{P(T>t)} = \lim_{\Delta{t}\to\ 0}P(t\leq T<t+\Delta{t} | T > t) $$

$$ S(t) = e^{-\int_{0}^{t}h(u)du} $$

why? h(t) 라는 것은 1-S(t)를 미분한 것을 다시 S(t) 로 나눈 것이다. 이를 만족하는 S(t)는 위의 S(t) 밖에 없다. (if and only if 이다.)



카플란마이어 estimation


Censoring이 있는 데이터에서 생존함수를 추정하는 비모수적인 방법이다 만약 censoring이 아예 없다면, 생존함수는 그 시점에서 살아있는 사람을 보면 된다.  하지만 right-censoring이 있는 경우 해당시점에서 살아있는 사람은 censoring 된 사람을 제외한 사람일 것이고, 이 경우에 살아있는 사람만 계산하게 되면  생존 함수가 잘못 추정되게 된다.  따라서 censoring이 있을 때, 그 사람이 t시점까지 살았다는것을 활용하여 각 시점에서 survival rate을 구하여 계속 곱하면서 survival function을 추정한다.




http://sphweb.bumc.bu.edu/otlt/MPH-Modules/BS/BS704_Survival/BS704_Survival_print.html


반응형
반응형

7v로 알아보는 빅데이터의 정의 및 데이터셋과의 차이점


Big data is a term used to refer to data sets that are too large or complex for traditional data-processing application software to adequately deal with.


Wikipedia의 정의에 따르면 빅데이터는 전통적인 데이터 프로세싱 소프트웨어로 다룰 수 없는 큰 규모의 데이터셋을 말합니다. 



데이터를 저장하는 방식은 과거 추억의 아날로그 저장형태 (비디오 테이프, 레코드판, 카세트 테이프, 인쇄 책 등)으로부터 디지털 저장형태(하드디스크, CD, SSD 등)로 변화하였습니다. 인간은 기하급수적으로 발전한 데이터 저장 기술을 통해 엄청난 양의 데이터를 생성하고 이를 저장할 수 있는 기술을 갖게 되었습니다. 2010년대 들어서는 빅데이터라는 말이 심심찮게 들려왔습니다. 그리고 오늘날, 빅데이터라는 말을 한 번도 들어보지 않은 사람들이 없을 정도로 미디어에서 빅데이터라는 말은 일반적인 용어가 되어가고 있습니다. 그렇다면 도대체 빅데이터란 어떻게 정의될까요? 그 이름에서처럼 단순히 큰 데이터를 빅데이터라고 하는걸까요? 빅데이터와 비슷하면서 과거부터 써왔던 용어는 데이터셋이라고 볼 수 있습니다. 그렇다면 그냥 데이터셋과 빅데이터의 차이점은 무엇일까요?


출처 - https://www.ibmbigdatahub.com/infographic/four-vs-big-data


빅데이터는 원래 3v (volume, variety, velocity) 로 정의되었었습니다.  여기에 veracity, value가 추가되면서 보통 5v로 많이 불립니다. 하지만 여기에 validity와 volatility를 추가하여 7v로 부르기도 합니다. 이것은 정의하기 나름이기 때문에 정답이란 없다고 볼 수 있습니다. 이번 포스팅에서는 이 7v로 빅데이터의 개념을 설명하고, 일반적인 데이터셋과 무엇이 다른지를 풀이해보는 시간을 가져보겠습니다.



빅 데이터의 정의 (7v)


1. Volume

빅데이터란 우선, 그 이름에서도 알 수 있듯, 양이 큰 데이터를 말합니다. 과거에는 사람이 데이터를 만들었지만, 현시대에서는 데이터가 기계로부터 자동으로 생성되어져 나옵니다. 그렇기 때문에 데이터의 크기가 커집니다. 과거에는 사람들이 병원에 오면, 이를 병원 직원이 병원의 데이터 시스템에 입력을 해주었습니다. 현재는 이 뿐 아니라 개인의 생체 검사 정보, 의학 영상 정보, 또한 개인의 유전체 정보까지 수많은 종류의 데이터가 여러 플랫폼에 저장되고 있습니다. 이는 예를 들어, 과거의 텍스트 데이터로부터 다양한 멀티미디어 데이터(ex. SNS 로부터 수집되는 수많은 사진, 동영상 등의 정보)로 시대가 변화하였음을 의미합니다.


2. Variety

빅데이터란 그 종류가 매우 다양합니다. 이는 다양한 Source로 부터 정형(Structured), 비정형(Structured) 데이터가 수집되는 것을 의미합니다. 예를 들어, 은행의 거래 시스템 정보는 정형화된 데이터입니다. 누가 누구한테 얼마를 보냈냐는 정보가 정형화된 형테로 데이터베이스에 들어있습니다. 하지만, 빅데이터라는 것은 이 뿐아니라 예를 들어, 의사의 손글씨 데이터, 사람의 음성 데이터 등 정형화 되지 않은 데이터까지 포함하는 의미합니다. 이러한 것들을 가공, 분석하기 위해서는 특별한 기술이 필요합니다.  


3. Velocity

빅데이터는 데이터가 수집되는 속도가 매우 빠릅니다. 데이터가 수집의 원천은 비지니스, 기계, 네트워크, 소셜미디어, 모바일 기기 등 다양해지고 있으며, 이러한 데이터들의 흐름은 그 양이 크고, 연속적입니다. 이러한 real-time 데이터가 비지니스 혹은 연구자들이 의사결정 (decision making)할 때 도움이 되고 있습니다. 


4. Veracity

Volume이나 Velocity가 있더라도, 그것이 빅데이터라고 불릴 수 없는 것은 아닙니다. 주로 진실성이라고 번역하는 Veracity는 빅데이터셋이 얼마나 신뢰할 수 있는지를 의미합니다. 만약 빅데이터에 수많은 노이즈와 바이어스가 있어, 이를 적절히 처리할 수 없을 때에는 이를 통해 유용한 가치를 만들어낼 수 없을지도 모릅니다. 빅데이터는 Veracity를 확보하는 것이 중요하지만, 빅데이터에서의 노이즈와 오류는 종종 피할 수 없는 것이기도 합니다. 따라서 필요없는 정보를 삭제  (processing 또는 cleaning) 해야할 수도 있습니다. 이것이 빅데이터를 다루는 사람이 도메인 지식을 가지거나, 관련 도메인 지식을 갖은 사람들과 협업이 필요한 이유라고 할 수 있습니다.  


5. Validity

Validity의 개념은 그 데이터의 정확성을 의미합니다. 데이터가 타당한지 정확한지 여부는 어떠한 결정을 내리는데 중요합니다. Veracity와 Validity는 비슷한 개념이나, 데이터에 Veracity가 없다면, 노이즈와 바이어스로 인해 잘못된 결론을 이끌어낼 수 있으며, Validity가 없다면 데이터는 규모가 크더라고 쓸모가 없어집니다. (참고) 예를 들어, 개와 고양이 사진 DB을 예로 들어보면, 개와 고양이 사진에 기술적 결함으로 생겨난 인공적 노이즈가 많다면, Veracity가 없는 것입니다. 하지만, 개와 고양이의 Labeling이 잘못된 데이터라면 Validity가 없는 것입니다. 


6. Volatility

Volatility란 휘발성으로 번역되며, 데이터가 얼마나 오래 저장될 수 있고, 타당하여 오랫동안 쓰일 수 있을지에 관한 것입니다. 아무리 데이터의 양이 많고 깔끔하게 정리되어있더라도 몇 년만 지나면 의미가 없어지는 유형의 데이터이거나, 데이터의 양이 가진 자원에 비해 너무나도 커서 이를 오래 저장할 수 없는 환경을 마련하는 것이 힘들다면 빅데이터로서의 활용성을 점검해보아야할 것입니다. 빅데이터는 단기적으로 활용하기 보다는 장기적인 관점에서 유용한 가치를 창출할 수 있어야합니다.


7. Value

빅데이터는 결국 비즈니스나 연구에 사용되며 유용한 가치를 이끌어낼 수 있어야 그 의미가 있습니다. 마지막 Value 는 이러한 빅데이터의 가치를 의미합니다. 최근 많은 빅데이터 관련 initiative가 나오고 있는데, 빅데이터를 설계하고 그것을 수집하기 전에 그 데이터를 활용하여 무엇을 할 수 있을지에 대한 고민이 먼저 필요할 것입니다. 


2016년에 언급된 빅데이터 정의

A 2016 definition states that "Big data represents the information assets characterized by such a high volume, velocity and variety to require specific technology and analytical methods for its transformation into value".

빅데이터란 Volume, Velocity, Variety로 특징지을 수 있는 정보 자원이며, 이를 활용하여 기술 및 분석 방법에서의 가치를 얻을 수 있어야합니다. 


2018년 언급된 빅데이터 정의

A 2018 definition states "Big data is where parallel computing tools are needed to handle data", and notes, "This represents a distinct and clearly defined change in the computer science used, via parallel programming theories, and losses of some of the guarantees and capabilities made by Codd’s relational model."

빅데이터는 그것을 다루기 위해 병렬 컴퓨팅 툴이 필요할 정도의 데이터를 말합니다.


빅데이터의 정의는 시대에 따라달리지고, 또 이를 해석하는 분야, 사람에 따라 달라질 수 있습니다. 하지만 공통적으로 많은 사람들의 동의하는 정의가 바로 위의 정의들이라고 볼 수 있습니다. 이러한 관점에서 빅데이터와 기존 데이터셋의 차이점은 바로 다음과 같이 정리해볼 수 있습니다.


1. 빅데이터는 다양한 소스로부터 수집된 데이터를 이르지만 이 중, 비정형화된 데이터(Unstructured data)에 더 초점을 맞춥니다.

2. 빅데이터는 병렬 컴퓨터의 필요할 정도의 큰 데이터셋을 말합니다. 

3. 빅데이터는 비지니스 혹은 연구에서 유용한 가치를 창출하여야 합니다.

4. 빅데이터는 타당성 (Validity), 신뢰성(Veracity)이 확보되어야합니다. 하지만 이것은 힘들 수도 있습니다.

5. 빅데이터는 오랫동안 저장되어 가치를 창출할 수 있어야하며, 단기간 활용보다는 장기적 활용에 초점을 맞춥니다.  


반응형
반응형

머신러닝, 딥러닝, 인공지능


머신러닝, 딥러닝, 인공지능 이 용어들의 차이는 무엇일까? 인공지능 하면 인간에게 도움을 주는 아이폰의 시리와 같은 인공지능 비서를 떠올릴 수도 있고, 또는 영화 아이로봇의 로봇처럼 인간을 위협하는 존재가 떠오를 수도 있다. 딥러닝하면 얼마전 이세돌을 바둑으로 격파한 알파고의 학습 방법으로 많은 사람들이 기억한다. 하지만 이러한 개념들이 서로 간에 어떠한 관계를 갖고 있는지에 대해 모호하게 느껴질 수도 있다. 본 포스팅에서는 인공지능이 머신러닝과 다른점, 그리고 머신러닝과 딥러닝의 차이점에 대해서 구체적으로 살펴보아 이들의 차이점이 궁금한 분들에게 도움이 될 수 있는 포스팅을 해보고자 한다. 


인공지능에 대한 인류의 오랜 꿈


피그말리온과 갈라테아 (출처)


사실, 인공지능이라는 개념은 최근에 와서 생긴 개념이 아니다. 역사적으로 생각하는 물체를 만든다는 것은 인류의 오랜 꿈이였다. 그리스 로마신화에 나오는 피그말리온과 갈라테아 그 한 예이다. 이 이야기는 독신으로 살던 한 조각가가 상아로 조각상을 만들고 아프로디테에게 간절히 빌어, 아프로디테가 이 남자를 딱하게 여겨 조각상에 생명을 불어넣고 조각상이 여인으로 변했다는 이야기이다. 넓은 의미의 인공지능은 기계를 인간처럼 보이게 만드는 모든 기술을 총칭한다. 갈라테아는 본래 조각상이었지만 인간처럼 생각하고 행동할 수 있게 되었다. 이러한 이야기를 통해 우리는 옛 사람들에게도 기계에 생명을 불어넣어 인간처럼 만드는 '환상' 이 있었음을 짐작할 수 있다.


하지만 오늘날, 이러한 신화처럼 인공지능이 어느날 갑자기 생기지는 않을 것이다. 우리는 인공지능을 구현하기 위해서 컴퓨터 프로그램을 활용한다. 프로그램은 인공 지능을 구현하는 방법이다. 즉, 현대에서 말하는 인공지능이란 컴퓨터 프로그램을 통해 인간처럼 이해하고, 추론하고, 사고하게 할 수 있는 방법이다. 다른 말로 인공지능이란 인간의 "인지기능" 을 모방하는 시스템을 말한다. 인지 기능이란 무언가를 배우고 이를 통해 문제를 해결할 수 있는 인간의 능력이다. 


"artificial intelligence" is applied when a machine mimics "cognitive" functions that humans associate with other human minds, such as "learning" and "problem solving".


출처 - Deep learning, Youshua Bengio et al. (2016)

인공지능은 머신러닝, 딥러닝을 포함하고 있는 상위 개념이다. 


인공지능을 구현하는 두 가지 방법


IBM - Deep blue (1996)


컴퓨터 프로그램을 통해 인공지능을 구현하는 방법에는 두 가지가 있다. 하나는 규칙기반 시스템(Rule-based system) 이다. (이는 expert system, Knowledge base system 등으로 불리기도 한다.) 이 방법은 기계가 인간처럼 사고하도록 하기 위해서 Rule을 이용한다. 얼마 전, 바둑은 인간의 영역이라고 여겨졌던 바둑에서 최정상 선수인 이세돌과 커제를 각각 4:1, 3:0으로 꺾었다. 하지만 그로부터 약 20년 여년전 체스가 먼저 컴퓨터에게 정복 당했는데,  IBM에서 만든 Deep blue라고 하는 체스용 컴퓨터가 체스 챔피언을 접전 끝에 4:2로 이긴 것이다. Deep blue는 1초에 20억개 이상의 경우의 수를 계산하여 최고의 수를 두는 당시대의 최고의 기술이었다. 이러한 경우의 수를 구하는 것은 프로그래밍을 통해 체스의 규칙을 컴퓨터에 입력해주고, 이 규칙하에서 Deep blue가 가능한 경우의 수를 조회하는 것이다. 즉, 체스 게임의 Rule을 이용한 것이다. 


인공지능을 구현하는 두 번째 방법은 바로 머신러닝(Machine Learning)이다. 이 방법인 인간이 컴퓨터에게 규칙을 입력해주는 것이 아니라, 기계 스스로 배우도록 한다. 이게 무슨말이냐 하면, 데이터를 주고 이 데이터에서의 정답을 알려주면 기계가 새로운 데이터가 들어왔을 때 정답을 예측한다는 것이다. 고양이 사진 100개를 보여주고 새로운 고양이 사진을 보여주면 기계가 이 사진을 고양이라고 맞춘다는 원리이다. 이 방법의 놀라운 점은 사람이 학습하는 방법과 같다는 것이다. 태어난지 얼마 안 된 아이는 고양이가 무엇인지 모른다. 하지만 사람들이 그것을 고양이라고 부르기 때문에 새로운 고양이를 보았을 때 지금까지의 경험을 토대로 그것을 "고양이" 라고 말할 수 있게 된다. Knowledge from experience 즉, 경험으로부터의 지식이 머신러닝의 핵심이라고 할 수 있다. 


A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P if its performance at tasks in T, as measured by P, improves with experience E. Mitchell, T. (1997)



현대의 인공지능 예를 들어, 자율 주행차, 컬링 로봇, 의료 진단 시스템 등은 대부분 머신러닝을 활용한다. 하지만 규칙기반 시스템이 아예 쓰이지 않는 것은 아니다. 규칙기반 시스템은 풀고자 하는 문제에 따라서 유용하기도 하다. 특히, 세계관이 좁은 문제의 경우. 예를들어 체스의 경우 경우의 수가 바둑에 비해 적기 때문에 인간이 모든 규칙을 일일히 입력하는 것이 어렵지 않다. 또 게임 캐릭터의 인공지능도 규칙기반 시스템을 사용한다. 하지만 인공지능에 대한 연구는 대부분 머신러닝을 어떻게 하면 더 잘할 수 있을지에 대한 것이다. 


딥러닝


Deep learning (also known as deep structured learning or hierarchical learning) is part of a broader family of machine learning methods based on learning data representations, as opposed to task-specific algorithms. Learning can be supervised, semi-supervised or unsupervised.


딥러닝은 생물의 뇌 회로에서 영감을 받은 머신러닝 모델이다. 인간처럼  인간은 어떻게 생각하고, 사고하고, 기억을 저장할까? 



인간의 뇌는 1000억개의 뉴런100조개의 시냅스로 이루어져 있다. 시냅스에서 뉴런에 전기적 신호를 보내면 뉴런은 이 전기적 신호에 반응하여 이 신호를 다음 뉴런으로 전달한다. 이러한 뉴런-시냅스라는 작은 단위가 이루어진 뇌를 통해 인류는 이해하고 사고하고 고차원적인 사고를 할 수 있는 것이다. 딥 러닝은 이러한 뇌의 신호 전달 과정에서 영감을 얻어 고안되었다. 


딥러닝에서 뉴런을 모방한 것은 퍼셉트론(Perceptron)이라고 하며, 이는 1958년 Rosenblatt에 의해 처음 제안되었다. 퍼셉트론은 x1~xn의 인풋을 받아들이고 이 인풋들의 곱의합(weighted sum)을 계산하고, 활성화 함수(activation function)에 대입하여 최종 y를 예측한다. 하지만 이러한 기본적인 퍼셉트론 만으로는 복잡한 문제를 해결하기 어렵다. 


Multi-layer perceptron (MLP) Hidden layer라는 layer를 도입해 인풋을 한 차원 높은 단계의 특징, 즉 representation으로 나타낸다. 퍼셉트론의 y를 그 다음 layer의 input으로 넣어준다는 것이다. 이것이 딥러닝을 Representation learning의 한 종류라고 말하는 이유이다. 



1986년 hidden layer를 포함한 신경망 모델을 효율적으로 트레이닝 할 수 있는 방법, Backpropagation이 등장한다.


우리가 길거리의 고양이를 보고 왜 고양이라고 생각을 할까? 우리는 분자 단위로 고양이를 읽어들여 뇌에서 직접적으로 이 정보를 이용하여 고양이라고 판단하지 않는다. 우리는 눈에 보이는 고양이의 형체를 전체적으로 보고, 이곳에서 고양이로 판단할만한 유용한 정보를 추출(extract)한다. 이 정보는 예를 들면, 뾰족한 귀, 갈색 털, 날카로운 눈빛, 네 개의 발과 같은 것이다. 분자 단위의 고양이의 형체에서 이러한 정보를 인간은 자동적으로 추출하는 능력이 있는 것이다. 이 때, 뾰족한귀, 갈색 털과 같은 고양이의 특징을 representation 이라고 한다. 딥러닝 모델에 Hidden layer를 추가한다는 것은 이러한 representation을 추출해내는 한 개의 층을 더 추가한다는 것이다. 층을 깊게 쌓을 수록 기본적인 특징을 조합하여 한 단계 위의 고차원 적인 특징을 추출해낼 수 있는 능력을 갖게 된다. 


머신러닝과 딥러닝의 차이점은 바로 이부분이다.  고전적인 머신러닝 알고리즘을은 인풋 특징들 (예를 들면, 고양이의 분자단위)를 바로 매핑시켜 이를 통해 고양이인지 여부를 판단하고자 한다. 딥러닝이란 Deep 이라는 말에서 알 수 있듯, 매우 추상적인 분자단위의 고양이에서 유용한 정보를 추출하여 이를 통해 고양이를 판단할 수 있는 고차원 적인 Feature로 변환하는 Representation learning 과정이 그 알고리즘 자체에 내재되어 있다. 


딥러닝은 이러한 Deep 한 구조를 통해 인간이 쉽게 할 수 있는 것이지만 형식화하여 설명하기는 힘든 영역, 직관적이며 고차원적인 인간 고유의 영역에 도전하고 있다. 


The true challenge to artificial intelligence proved to be solving the tasks that are easy for people to perform but hard for people to describe formally—problems that we solve intuitively, that feel automatic, like recognizing spoken words or faces in images. (Deep learning, Yoshua bengio et al, 2016)

AI의 종류의 그 차이점 (Deep learning, Yoshua bengio et al, 2016)


딥러닝은 오로지 데이터로만 배우고, 데이터의 규칙을 찾아내는 수많은 파라미터들을 통해 구현되기 때문에 수많은 데이터가 필요하다. 예를 들어, 고양이를 찾아내는 딥러닝 시스템을 만들어본다고하자. 기계가 고양이 사진을 보고 고양이임을 알아내기 위해서는 많은 고양이 사진이 필요하다. 고양이와 비슷하게 생긴 여우, 삵 등을 고양이와 구분하는 것은 그 작은 디테일의 차이를 기계가 구분하는 것은 쉽지 않을 것이다. 따라서 수많은 데이터셋이 뒷받침 되지 않으면 아무리 좋은 딥러닝 모델을 구현하더라도 무용지물이다. 


한 편, 딥러닝이 뇌과학에서 영감을 얻은 것은 사실이지만, 반드시 뇌과학적 지식을 그대로 적용하지는 않는다. 딥러닝은 다소 공학적인 면이 있다. 실제로 biological relevance가 없더라도, 그것이 성능 향상에 도움이 된다면, 유용하게 쓰인다. 


결론


1. 인공지능 > 머신러닝 > 딥러닝

2. 인공지능을 구현하는 방법은 크게 규칙기반 시스템과 머신러닝으로 나눌 수 있다. 즉, 머신러닝은 인공지능을 구현하는 한 방법이다. 

3. 머신 러닝은 사람이 일일히 규칙을 정의하지 않아도 데이터를 통해 배우는 것이 핵심이다. 즉, Knowledge from experience로 인공지능을 구현한다. 

4. 딥 러닝은 생물체의 뇌 구조에서 영감을 얻은 머신러닝 기법 중 하나로 핵심 원리는 다계층 구조를 이용한 Representation Learning을 통해 스스로 데이터속에서 유용한 feature를 찾아내는 것이다. 딥 러닝은 기존 머신러닝과는 다르게 인간 고유의 영역, 이미지 분석, 언어 인식과 같은 직관적이고 고차원적인 사고를 요하는 분야에 강점이 있다.


참고

https://www.techrepublic.com/article/understanding-the-differences-between-ai-machine-learning-and-deep-learning/

Deep learning, Yoshua bengio et al, 2016


반응형
반응형

case/control 디자인에서 샘플 수를 계산하는 방법 


샘플 수를 계산한다는 것의 의미  


실제로 노출 여부가 case/control 여부에 영향을 줄 때, (association이 있을 때) 해당 샘플 수에서 이를 충분히 detection 할 수 있는가?


이는 다음과 같은 귀무가설/대립가설 하에서 가설 검정할 수 있습니다. 



p0 = Control에서 expose된 사람의 비율
p1 = Case에서 expose된 사람의 비율


즉, Control에서 expose된 사람이랑 case에서 expose된 사람의 비율이 같은지를 검정하는 것이죠.

이를 검정하기 위해서는 p0, p1, OR을 알아야 합니다. 근데 p0, p1, OR 중에 2개를 알면 1개를 아래와 같은 식으로 구할 수 있습니다. 




따라서 일반적인 샘플 수 구하는 공식처럼, 유의수준, 검정력, p0, p1 을 주고 샘플 수를 구할 수가 있습니다. 한가지 더 주어야할 것은 case/control 디자인에서는 보통 case/control의 비를 1 이상으로 맞추기 때문에 r이라고 하는 case/control ratio를 주어야합니다.  


이 때, Kelsey의 공식에 따르면 필요한 case의 숫자는 아래와 같이 계산됩니다. 


Kelsey의 방법 



이 때, x = (p1+rp0) / (r+1) 라고 놓고, p=x(1-x) 로 계산됨 



참고문헌

Kelsey J.L., Whittemore A.S., Evans A.S.,and Thompson W.D. Methods in Observational Epidemiology. Oxford University Press, 1996. Print.

http://www.openepi.com/PDFDocs/SSCCDoc.pdf

반응형
반응형

 

데이터과학이란 무엇인가?

 

데이터 과학이란 무엇인가? 사실 모든 학문, 산업 분야에서 "데이터" 는 필수적이다. 그런데 왜 "데이터" 과학이라는 이름을 따로 붙이는 걸까? 거기에 Science라니. 보통 Science라는 것은 새로운 지식을 찾는 활동, 즉, New finding에 대한 것을 Science라 한다. 하지만 데이터 과학에서 주로하는 것은 데이터를 처리하고 클리닝 하여 저장하고는 것, 즉 무언가를 개선 시키는 활동인 Engineering에 그치는 것 아닌가? 

 

데이터 과학자는 통계학자보다 컴퓨터를 잘하고, 컴퓨터과학자보다 통계학을 잘하는 사람이라는 우스갯 소리가 있다. 물론 어느 정도 맞는 부분이 있지만 데이터 과학은 단지 어떤 학문 분야들의 중간에 있는 것이 아니라 기존 학문들에서 다루지 않는 부분을 다루기도 한다. 데이터 과학의 정의, 기존 학문과의 차별점에 대해 짚어보자. 

 

최근 떠오르는 학문 분야들에 대한 농담

 

Data science의 정의

 

The term “data science” describes expertise associated with taking (usually large) data sets and annotating, cleaning, organizing, storing, and analyzing them for the purposes of extracting knowledge. It merges the disciplines of statistics, computer science, and computational engineering.

 

데이터과학이란 보통 큰 데이터셋에 대해 어노테이션, 클리닝, 핸들링, 저장, 분석을 하여 그로부터 유용한 지식을 추출하는 것을 말한다. 이는 Informatics와 비슷하다. Informatics 란 정보학으로 모든 데이터를 처리 분석하여 유용한 정보를 얻는 것이다.

 

Informatics와 Data science의 차이점은 무엇인가?

 

간단하게 말해 Data science는 "빅데이터시대"에 정의된 학문 분야로서 기존에 보기 힘든 정도의 큰 데이터를 다룬다는 특징이 있다. 데이터 과학자는 컴퓨터 메모리에 올라가지 않는 규모의 큰 데이터를 다루며 이를 위한 기술적인 지식이 필요하다. 이전에는 Informatics를 위해서 컴퓨터 프로그래머를 고용하여 해결하였다고 한다. 하지만 데이터 과학은 단순히 "프로그래밍" 으로 해결할 수 없는 많은 부분을 포함하고 있다. Informatics와 Data science의 여집합은 바로 이 부분에서 나온다. 또한 Data science는 단순 프로그래밍이 아니라 해당 분야의 지식에 대한 깊은 이해를 기본 가정으로 한다. 즉, 이를 다시 한 번 정리해보자.

 

Informatics와 Data science의 차이점

 

 

1. 데이터과학자는 컴퓨터 메모리에 올라가지 않는 수준의 빅데이터를 다룬다.

2. 데이터과학자는 메타데이터 및 large-scale annotation이 필요하며, 데이터의 noise가 어디에서 발생되었는지에 대해 설명할 수 있어야 한다. 이는 도메인에 대한 이해를 필요로 하며 단지 데이터를 정리하고 가공하는 것과는 다르다.

3. 이러한 빅데이터를 분석할 수 있는 방법론인 머신러닝, 딥러닝 등을 이해하고 이를 해당 분야의 데이터에 적용시켜 유용한 가치를 찾는다.

 

 
최근 많은 학교 교육 및 직업 교육에서 domain-free 데이터과학을 가르친다. 금융, 헬스, 생물 어떤 분야에도 통용할 수 있는 데이터 처리 기술이다. 물론 그것은 데이터 과학을 시작할 수 있는 "기초 단계"로서 유용하다. 하지만 단지 domain-free 데이터 과학만을 배우면 단지 데이터를 가공하고 매니지하는 사람에 그쳐버릴 수도 있다. (협업자의 엄청난 도움이 없다면) 하지만 domain에 대한 specific knowledge가 있으면 그 분야에 전문가이면서 데이터를 직접 처리하고 가공, 분석 할 수 있는 사람이 될 수 있다.  

 

데이터과학자에게 도메인 지식이 필수적인 이유는 다음과 같이 정리해볼 수 있다. 

 

1. 데이터에 무언가 문제가 생겼을 때,이를 해결하기 위해 필요하다.
2. 데이터의 annotation을 하기 위해서는 도메인 지식이 필요하다.
3. 문제를 찾고 이를 해결하기 위해서는 도메인 지식이 필수적이다.
 
 

 

빅데이터 시대의 대표적인 분석 방법론, 머신러닝

 
 
좋은 데이터 과학자란, 기존 Informatics 방법론으로는 다루기 힘든 수준의 복잡한 빅데이터를 다루며, 충분한 도메인 지식을 바탕으로 해당 분야의 데이터를 스스로의 계획을 통해 처리, 가공을 하며, 메타 데이터 annotation을 직접하며, 해당 분야의 문제를 찾고 이를 해결할 수 있는 사람이다.  어떤 도메인을 깊게 공부하고 그 데이터에 대해 즉각적으로 이해하고 데이터를 어떻게 처리하고 굴려서 분석할지를 정하는 데에 좋은 결정력을 갖고 있는 사람이다. 어떤 한 분야의 domain 지식을 가질 때 그 분야의 문제를 찾고, 직접 데이터를 처리하고 적절한 분석 방법을 통해 분석하여 해결할 수 있는 사람이 된다. 
Biomedical Data science 를 예로 들어보자.

 

Biomedical science 분야는 Bio와 medical이 합쳐진 분야이다. 즉, 생물학과 의학이 합쳐진 분야로 생물학, 의학 분야의 "과학적 발견"을 주로 population health에 응용하는 응용학문이다. 이러한 Biomedical 분야는 데이터를 통해서 무언가를 할 수 있다. 따라서 Biomedical 분야를 연구하려면 기본적으로 데이터를 가공하고, 클리닝하고, 분석할 수 있어야한다. 그러면 Biomedical data science라는 용어는 왜 존재하는가? 

 

Biomedical 분야의 데이터를 다음 세 가지로 크게 나눌 수 있다.

 

1. DNA 시퀀싱 데이터 (NGS 데이터)

2. 센서 데이터 (심박수, electrocardiogram signal 등)

3. Electronic health record (개인의 건강 임상 정보)

 

이러한 종류의 데이터는 소위 말하는 4v(Volume, Variety, Velocity, Value)를 만족하는 "빅데이터" 이다. 이러한 정보를 가공하고 분석하기 위해서는 특별한 skill set이 필요하다. NGS 데이터를 예로 들어보자. NGS는 새로운 인간 DNA의 시퀀싱 방법으로 massive parallele sequencing이라고 하는 특별한 시퀀싱 방법을 통해 인간 DNA 서열을 "추측"한다. 이 기술의 상당한 발전이 이루어져 정확도는 상당히 높지만, 중요한 것은 뚝딱하고 ATCG로 이루어진 DNA의 서열이 나오지 않는다는 것이다. 또 DNA 서열은 30억개 정도가 되기 때문에 한 글자당 4비트라고 놓고 계산을 하더라도 1GB 이상의 크기이며, 실제 NGS 분석에서 나오는 Raw 데이터는 1인당 200GB에 이른다. (참고)  따라서 이러한 특별한 종류의 NGS 데이터를 통해 인간 DNA 서열을 조립하고, 이곳에서 변이(variant)를 탐색하고 질병과의 연관성을 분석하는 것은 상당한 도메인 지식을 필요로 한다. Biomedical data science란 이러한 종류의 데이터를 직접 가공, 클리닝하여 이를 분석하고 유용한 지식을 탐색하는 활동이라고 할 수 있다. 

 

Reference

[1] What is Biomedical Data Science and Do We Need an Annual Review of It ? - Annual review of biomedical data science, 2018

반응형
반응형