분류 전체보기 (336)

반응형

딥러닝 모델의 K겹 교차검증 (K-fold Cross Validation)


K 겹 교차 검증(Cross validation)이란 통계학에서 모델을 "평가" 하는 한 가지 방법입니다. 소위 held-out validation 이라 불리는 전체 데이터의 일부를 validation set 으로 사용해 모델 성능을 평가하는 것의 문제는 데이터셋의 크기가 작은 경우 테스트셋에 대한 성능 평가의 신뢰성이 떨어지게 된다는 것입니다. 만약 테스트셋을 어떻게 잡느냐에 따라 성능이 다르면, 우연의 효과로 인해 모델 평가 지표에 편향이 생기게 됩니다.


이를 해결하기 위해 K-겹 교차 검증은 모든 데이터가 최소 한 번은 테스트셋으로 쓰이도록 합니다. 아래의 그림을 보면, 데이터를 5개로 쪼개 매번 테스트셋을 바꿔나가는 것을 볼 수 있습니다. 첫 번째 Iteration에서는 BCDE를 트레이닝 셋으로, A를 테스트셋으로 설정한 후, 성능을 평가합니다. 두 번째 Iteration에서는 ACDE를 트레이닝셋으로, B를 테스트셋으로하여 성능을 평가합니다. 그러면 총 5개의 성능 평가지표가 생기게 되는데, 보통 이 값들을 평균을 내어 모델의 성능을 평가하게 됩니다. (아래 데이터는 모두 사실은 트레이닝 데이터입니다. Iteration이라는 상황안에서만 테스트셋이 되는 것입니다.) 이 때, 데이터를 몇 개로 쪼갰느냐가 K-겹 교차검증의 K가 됩니다.


교차 검증을 통한 성능 평가의 목적


모델 성능 평가는 보통 2개의 목적이 있습니다. 1. Unseen 데이터에 대한 성능을 예측하기 위해, 2. 더 좋은 모델을 선택하기 위해 (혹은 Hyperparameter Tuning) 입니다. 교차 검증은 1,2를 달성하기 위한 좋은 방법입니다. 파이썬에서 K-겹 CV를 하는 방법은 여러가지가 있지만 scikit-learn이 많이 사용됩니다. 본 포스팅에서는 keras에서 모델을 만들고 이를 K-겹 교차검증하여 성능을 평가하는 방법을 알아보겠습니다. 


코드 & 데이터


pima-indians-diabetes.data.csv

# MLP for Pima Indians Dataset with 10-fold cross validation via sklearn from keras.models import Sequential from keras.layers import Dense from keras.wrappers.scikit_learn import KerasClassifier from sklearn.model_selection import KFold from sklearn.model_selection import cross_val_score import numpy   # Function to create model, required for KerasClassifier def create_model(): # create model model = Sequential() model.add(Dense(4, input_dim=8, activation='relu')) model.add(Dense(4, activation='relu')) model.add(Dense(1, activation='sigmoid')) # Compile model model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) return model   # fix random seed for reproducibility seed = 7 numpy.random.seed(seed)   # load pima indians dataset dataset = numpy.loadtxt("pima-indians-diabetes.data.csv", delimiter=",")   # split into input (X) and output (Y) variables X = dataset[:,0:8] Y = dataset[:,8]   # create model model = KerasClassifier(build_fn=create_model, epochs=150, batch_size=10, verbose=0)   kfold = KFold(n_splits=2, shuffle=True, random_state=seed) results = cross_val_score(model, X, Y, cv=kfold)

설명


create_model()을 통해 Keras Model 객체를 얻음

KerasClassifier Wrapper를 통해 Keras Model을 Scikit learn에서 사용할 수 있는 객체로 변환을 한다.

Scikit learn의 kFold를 통해 KFold의 Rule을 지정한다.

cross_val_score을 통해 해당 모델의 cross validation score를 계산한다.


결과

array([ 0.65104168,  0.59114585])

0.621093765677 (평균)

위 예제 코드에서는 간단하게 보이기 위해 2-Fold cross validation score를 계산하였습니다. results에 다음과 같은 두 개의 성능 지표가 계산되며 accuracy를 지표로합니다. 첫번째 iteration 의 accuracy 는 0.64, 두 번째 iteration 의 accuracy 는 0.59 로, 최종 cross validation score 는 0.62 가 됩니다.


반응형
반응형


Matching 데이터의 예


Matching이란 case의 control에서 혼란변수의 분포를 맞추어주는 방법으로 데이터셋을 구성할 때 자주 쓰이는 방식입니다. 이는 confounding을 방지하는 방법으로 알려져 있습니다. 이번엔 Matching 데이터를 분석할 때 매우 자주 쓰이는 Conditional Logistic Regression에 대해 아주 간단히 알아보겠습니다. R에서 먼저 사용할 데이터셋을 임포트합니다. 종속변수는 d이며, 이진변수입니다. 그래서 logistic regression으로 연관성 분석을 할 수 있는데요.


library(Epi)

data(bdendo)


setdgallhypobestdurnondurationagecestagegrpage3
11.001.00NoNoYesYes4Yes96.0074.00370-7465-74
21.000.00NoNoNo0No0.0075.00070-7465-74
31.000.00NoNoNo0No0.0074.00070-7465-74
41.000.00NoNoNo0No0.0074.00070-7465-74
51.000.00NoNoYesYes3Yes48.0075.00170-7465-74
62.001.00NoNoNoYes4Yes96.0067.00365-6965-74
72.000.00NoNoNoYes1No5.0067.00365-6965-74
82.000.00NoYesYesNo0Yes0.0067.00065-6965-74
92.000.00NoNoNoYes3No53.0067.00265-6965-74
102.000.00NoNoNoYes2Yes45.0068.00265-6965-74
113.001.00NoYesYesYes1Yes9.0076.00175-7975+
123.000.00NoYesYesYes4Yes96.0076.00275-7975+
133.000.00NoYesNoYes1Yes3.0076.00175-7975+
143.000.00NoYesYesYes2Yes15.0076.00275-7975+
153.000.00NoNoNoYes2Yes36.0077.00175-7975+


데이터셋의 대한 설명은 help(bdendo)를 입력하면 나오고, 아래를 참고 바랍니다.

 

Format


This data frame contains the following columns:


set: Case-control set: a numeric vector

d: Case or control: a numeric vector (1=case, 0=control)

gall: Gall bladder disease: a factor with levels No Yes.

hyp: Hypertension: a factor with levels No Yes.

ob: Obesity: a factor with levels No Yes.

est: A factor with levels No Yes.

dur: Duration of conjugated oestrogen therapy: an ordered factor with levels 0 < 1 < 2 < 3 < 4.

non: Use of non oestrogen drugs: a factor with levels No Yes.

duration: Months of oestrogen therapy: a numeric vector.

age: A numeric vector.

cest: Conjugated oestrogen dose: an ordered factor with levels 0 < 1 < 2 < 3.

agegrp: A factor with levels 55-59 60-64 65-69 70-74 75-79 80-84

age3: a factor with levels <64 65-74 75+


하지만 Matching 데이터에 일반적인 Unconditional Logistic regression을 쓰면 bias가 생깁니다. 왜냐하면 Matching을 하면서 가져온 데이터에는 데이터 고유의 특성이 있기 때문입니다. 예를 들어서 time matching을 한 경우에, 비슷한 시기의 데이터를 샘플링을해서 하나의 strata를 만들고 데이터셋을 구성하게 됩니다. 그러면 이 시기에 의한 효과가 추정량에 영향을 주게 됩니다. 따라서 conditional logistic regression 이라는 조금 더 개선된 logistic regression 방법을 사용하여야합니다. (수학적인 설명은 생략하겠습니다..)


## Analysis

res.clogistic <- clogistic(d ~ cest + dur, strata = set, data = bdendo)


R로 conditional logistic regression(clr)을 하는 방법은 간단한 데 Epi 패키지의 clogistic을 활용하면 됩니다.  분석하고자 하는 공변량을 ~ 뒤에 넣고, strata에 matching pair를 나타내는 변수값을 입력합니다. 이 데이터의 경우, set 이라는 변수가 strata의 정보를 갖고 있습니다. 총 5개의 row가 같은 strata임을 알 수 있습니다. 


결과를 돌리면 다음과 같이 나오는 것을 확인할 수 있습니다.


res.clogistic


Call: 

clogistic(formula = d ~ cest + dur, strata = set, data = bdendo)


         coef exp(coef) se(coef)      z    p

cest.L  0.240     1.271    2.276  0.105 0.92

cest.Q  0.890     2.435    1.812  0.491 0.62

cest.C  0.113     1.120    0.891  0.127 0.90

dur.L   1.965     7.134    2.222  0.884 0.38

dur.Q  -0.716     0.489    1.858 -0.385 0.70

dur.C   0.136     1.146    1.168  0.117 0.91

dur^4      NA        NA    0.000     NA   NA


Likelihood ratio test=35.3  on 6 df, p=3.8e-06, n=254


association을 알아보기 위한 변수 cest, dur의 추정량을 볼 수 있습니다. 



반응형
반응형


쉽게 이해하는 민감도, 특이도, False Positive, False Negative, 양성예측도



민감도 (Sensitivity), 특이도(Specificity), 양성 예측도(Positive Predictive Value, PPV) 는 바로 무언가를 예측하는 상황에서 쓰이는 통계적인 지표입니다. 이 지표들이 가장 많이 쓰이는 곳이 바로 검진(Diagnostic)인데요.


우선 검진의 정의에 대해서 명확히 짚고 넘어가보겠습니다. 검진이란 "건강 상태와 질병의 유무를 알아보기 위하여 증상이나 상태를 살피는 일" 입니다. 이처럼 검진은 그 사람의 병의 유무를 알기 위해 일종의 검사를 하여 병의 유무를 예측하는 것입니다. 중요한 건, 검진은 실제와 다를 수 있다는 것입니다.  


예를 들어, 폐암 검진을 위해 흉부를 X-ray로 촬영한다고 해봅시다. X-ray는 저비용으로 폐암 여부를 알아보는 효과적인 방법입니다. 하지만 문제는 X-ray 결과로 그 사람의 폐암 여부가 결정이 나는 것이 아니라는 것입니다. X-ray에서 폐암이 의심이 가는 경우, MRI, CT 등의 더 정밀한 검사를 통해 폐암의 실제 여부를 결정하게 됩니다. 


이 때, X-ray가 "폐암 여부를 정확하게 가려내는 정도" 를 수치화할 수 있겠죠. 이렇게 수치화하는 지표 중에 유명한 것이 바로 민감도, 특이도, 양성 예측도입니다. 이를 이해하기 쉽게 설명하기 위해 다음과 같은 표로 많이 설명합니다.



폐암 X-ray 검진 예제

 

 폐암 O

폐암 X 

 

 X-Ray 양성

 90

100 

190 

 X-Ray 음성

10 

800 

810 

 

 100

 900

 1000


총 1000명이 X-ray 검사를 받았고, 이 중에 폐암환자는 10%인 100명, 비환자는 90% 입니다. 폐암환자 100명 중 90명이 X-ray 양성 판정을 받았고, 비환자 900명중 800명이 X-ray 음성 판정을 받았습니다. X-ray가 꽤 잘 맞춘 것이죠.


이 때, 폐암환자 중 양성 판정을 받은 사람의 비율을 민감도,

비환자 중 음성 판정을 받은 사람의 비율을 특이도라고 합니다. 


이 예에서, 민감도는 90/100 = 0.9, 특이도는 800/900 = 0.89 입니다. 이 때 1-0.9=0.1 = False Negative Rate, 1-0.89 = False Positive Rate 라고 합니다. 


즉, False Negative는 환자인데 검진에서 가려내지 못한 사람의 수, False Positive는 정상인인데 검진에서 환자로 판단한 사람의 수입니다. Rate가 붙으면 분모로 나누어 0과 1 사이의 값으로 나타내게 되는 것입니다. 민감도, 특이도, False Negative, False Positive는 이렇게 세트로 묶어서 이해할 수 있습니다.


그렇다면 양성 예측도, 음성예측도는 무엇일까요?


민감도와 특이도는 검진을 받은 "사람"의 관점에서 그 기기의 검진의 정확도를 판단한 것입니다. 반면, 양성 예측도, 혹은 음성 예측도의 경우 "기기의 관점"에서 검진의 정확도를 판단하게 됩니다. X-ray가 양성이라고 판단했을 때, 실제 폐암 환자일 확률은 90/190 = 0.47 입니다. 바로 이것을 양성 예측도라고 합니다. 반대로, X-ray가 음성이라고 판단했을 때, 진짜 정상인일 확률은 음성 예측도라고 하며, 800/810=0.98 입니다. 


문제는 양성 예측도가 왜이렇게 작게 나왔는가? 하는 것입니다. 양성 예측도는 민감도(0.9)와 특이도(0.89)처럼 그 값이 크지 않다는 것을 확인할 수 있습니다. 관찰력이 좋으신 분들은 직감으로 이걸 이해할 수 있으실 것입니다. 문제는 바로 "데이터의 불균형" 때문인데요. 비환자 900명중에 단지 100명만이 X-ray 양성으로 잘못 판단되었지만 (False Positive) 상대적으로 비환자가 1:9로 많기 때문에 그 값이 상대적으로 크게 잡혔다는 것을 볼 수 있습니다. 


이를 식으로 살펴보면, 양성 예측도 = 90 / 190 = 90 / 90+100 으로 풀어쓸 수 있겠죠. 이 때, 비환자가 환자와 마찬가지로 100명이었다면 90/90+100/9 = 약 0.9가 되었어야합니다. 하지만, 비환자가 환자에 비해 상대적으로 많기 때문에 False Positive가 많아져서 양성 예측도가 적게 나왔다는 것을 이해할 수 있습니다.


이를 두고, 양성 예측도는 유병률이 작을 수록 작다. 라고 표현합니다. 이 예제에서 폐암 유병률은 0.1이겠죠. 이 값이 작으면 작을 수록 False Positive에 의해 양성 예측도, PPV 는 작아지게 됩니다. 이를 보통 아래 식을 통해서 이해를 하게 되는데요. 


이 식은 위 테이블에서 변수를 놓고 방정식을 풀면 나오게 됩니다. (시간이 되시는 분들은 직접 손으로 풀어보시면 나옵니다.) 이 식을 보면, 분모는 검진의 양성 판단 횟수이며, 분자는 환자를 양성으로 판단한 횟수임을 알 수 있습니다. 


근데, sensitivity*prevalance는 분모, 분자에 같이 있으므로, (1-specificity)*(1-prevalence)가 실제 PPV 값에 영향을 주게 되겠죠. specificity가 고정되어있을 경우, prevalence, 유병률이 작아질 수록 분모가 커져 PPV 값은 작아진다는 것을 쉽게 알 수 있습니다. 


민감도, 특이도, 양성 예측도 중 어떤 지표로 검진 기기를 판단해야 할까요?


명확하게 무엇이 절대적인 기준이라는 것은 없습니다. 다만, 민감도의 경우 환자의 생명과 직접적인 관련이 있을 수 있습니다. 민감도가 낮은 검진의 경우, False Negative(환자인데 정상으로 판단)가 많아지게 되겠죠. 환자인데 정상으로 판단하여 적절한 치료를 받지 못하면, 환자의 생명에 지장이 있을 수도 있습니다. 이것이 많은 사람들이 민감도를 중요시하는 이유입니다. 반면, 특이도의 경우 불필요한 비용의 낭비와 관련이 있습니다. 특이도가 낮으면, False Positive(정상인데 환자로 판단)가 많아지게 되겠죠. 정상인이 환자로 판단되면, 환자가 불안감에 시달리거나, 불필요한 정밀한 추가검사를 받아 환자가 아니라는 것을 밝혀야합니다. 따라서 불필요한 손실이 일어나게 됩니다. 하지만 민감도와 특이도는 현실적인 관점에서 trade off의 관계에 있습니다. 민감도를 높이면 특이도는 보통 낮아지게 되죠. 따라서 적절한 수준에서 검진의 민감도와 특이도를 설정할 필요가 있습니다. 양성 예측도의 경우 유병률이 매우 낮은 질병에서는 높은 것을 기대하기가 힘듭니다. 위 식에서 봤듯이 유병률이 매우 낮으면, 데이터의 불균형으로 인해 False positive가 많아지고 양성 예측도는 낮아지게 됩니다. 이를 방지하기 위해서는 검진의 특이도를 매우 높여야하는데, 현실적으로 민감도를 포기할 수 없기 때문에 양성 예측도는 유병률이 낮은 질병에서 보통 낮은 경향이 있습니다. 

반응형
반응형


우분투 그룹 관련 명령어 정리


우분투를 다중 사용자 환경에서 이용하다보면 특정 폴더를 특정 그룹만 접근할 수 있게 하고 싶을 때가 있습니다.

이럴 때 유용한 그룹 관련 명령어를 정리해보려고 합니다.




  • 그룹 생성하기 

groupadd [group]




  • 현재 등록된 그룹 확인

/etc/group


예를 들어, groupadd test_group을 한 후, 

cat /etc/group을 하면 아래와 같이 test_group이 잘 추가 되었음을 볼 수 있습니다.




  • 사용자한테 그룹 추가하기

usermod -a -G [group] [사용자아이디]



  • 사용자 그룹을 변경하기

usermod -g [group] [사용자아이디]

이렇게하면 사용자의 그룹이 [group]으로 변경됨. 나머지 것들은 다 삭제됨



  • 해당 폴더의 그룹 소유권을 변경

chown [소유자]:[그룹] [폴더이름]


해당 폴더의 소유자와 그룹을 변경한다. 




  • 해당 폴더의 권한 변경

chmod xxx [폴더이름]


이 때 xxx에는 0~7사이의 숫자가 들어갑니다. 이 숫자에 따라서 소유자권한, 그룹권한, 기타 사용자권한이 나뉜다. 이것에 관해서는 다른 포스트를 참조하길 바랍니다.



이 정도만 할 줄 알아도 우분투에서 그룹 관련된 권한 관리는 웬만한 건 다 할 수 있을 거라 생각합니다.



반응형
반응형


문제

/usr/bin/x86_64-linux-gnu-ld: cannot find -lgfortran


Bioconductor를 통해 R 라이브러리를 설치할 때, 위와 같은 컴파일 오류로 인해 제대로 설치되지 않는 현상 발생



해결

https://askubuntu.com/questions/1007591/usr-bin-ld-cannot-find-lopencl


아래 위치에 gfortran 라이브러리가 없어서 문제 발생

/usr/lib/x86_64-linux-gnu/

아래 명령어로 문제 해결

sudo ln -s /usr/lib/x86_64-linux-gnu/libgfortran.so.3 /usr/lib/libgfortran.so

반응형
반응형

티스토리 블로그에서 수식 쉽게 쓰기


아래 스크립트를 [블로그 관리]- [스킨 편집] - [html 편집] 후 head 아래에 아무곳에나 붙여넣으시면 됩니다.


<script>

(function () {

var script = document.createElement("script");

script.type = "text/javascript";

script.src  = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";

document.getElementsByTagName("head")[0].appendChild(script);

})();

</script>


아래 스크린샷처럼 head 태그 내부 아무곳에나 위 코드를 붙여 넣고 저장을 누르면 됩니다. 




이 스크립트를 적용하면 R markdown에서 사용하는 수식의 문법을 그대로 이용할 수 있습니다.


이 문법은 $표시로 수식의 시작과 끝을 나타내는데, 예를 들어 x의 제곱을 쓰고 싶다면 $표시를 두 번 사용후 x^2을 입력하고 $표시 두 번으로 수식이 끝났다고 표시하면 쉽게 x의 제곱을 나타낼 수 있습니다.


$$x^2$$


$$x^2$$


아래와 같은 복잡한 수학 수식도 이 문법을 이용하면 간단하게 표현할 수 있습니다.


$$\int_0^{2\pi} \sin x~dx$$


$$\int_0^{2\pi} \sin x~dx$$



이외에도 다양한 수학 수식을 표현할 수 있습니다. 문법은 구글에 R markdown formula 등을 검색하시면 쉽게 찾을 수 있는데 예를 들어 이곳을 참고하시면 좋습니다.



반응형

'Soft skills' 카테고리의 다른 글

우분투 14.04 LTS Server 텐서플로우 설치  (0) 2017.08.25
반응형

R로 구현하는 Gibbs Sampling

 

Bayesian Linear Regression

\[y_i = \beta_0 + \beta_1 x_i + \epsilon, \epsilon \sim N(0,1/\tau) \] \[ y_i \sim N(\beta_0 + \beta_1 x_i, 1/\tau)\] 이 모델에서 아래 데이터를 관찰했을 때, likelihood는 \[ (y_i, x_i), i=1,2,3...,N \] \[ L(yi,xi | \beta_0, \beta_1, \tau) = \prod_{i=1}^{N}N(\beta_0, \beta_1 x_i, 1/\tau) \] Bayesian의 특징은 여기서 beta0과 beta1, tau의 prior distribution을 정의한다는 것이다. 예를 들어, conjugate prior를 가정한다.

 

\[\beta_0 = N(\mu_0, 1/\tau_0) \] \[\beta_1 = N(\mu_1, 1/\tau_1) \] \[\tau \sim Gamma(\alpha, \beta) \] 이 파라미터들의 posterior distribution을 구하는 것이 bayesian estimation의 목적이다. 현재 데이터를 관찰함으로써, prior distribution이 변한 것이 posterior이다.

 

Gibbs sampling

우리의 목적은 theta0과 theta1의 joint posterior distribution을 구하는 것이다. 즉, 아래 pdf를 구하는 것이다.

\[ p(\theta_1, \theta_2 || x) \] 이걸 구하기 위해서 Gibbs sampling 방법에서는 각각의 파라미터에 대해full conditional distribution을 구한다. (이것이 가장 힘든 파트이다.) 데이터와, 모든 파라미터를 상수로 가정하고, 관심 있는 파라미터의 조건부 pdf를 구하는 것이다.

 

  1. 초기값을 정한다. \[ \theta_2^{(i)} \]
  2. 표본을 아래 분포에서 뽑는다. \[\theta_1^{(i+1)} \sim p(\theta_1 | \theta_2^{(i)}, x) \]

  3. 표본을 아래 분포에서 뽑는다. \[ \theta_2^{(i+1)} \sim p(\theta_2 | \theta_1^{(i)}, x) \]

그러면 위에 기술했던 Linear 모델의 posterior를 우선 구해보자.

우선 x,y data를 관찰했을 때의 beta0의 posterior는 아래와 같다.

\[ \beta_0|\beta_1,\tau,\tau_0,\mu_0,x,y \] 이것은 아래의 정규분포를 따른다. 왜 이렇게 되는지 자세한 설명은 이곳에 있다. 

\[ \beta_0|\beta_1,\tau,\tau_0,\mu_0,x,y \sim N(\frac{\tau_0\mu_0 + \tau \sum_i(y_i-\beta_1 x_i)}{\tau_0 + \tau N}, 1/(\tau_0 + \tau N)) \] 마찬가지로 나머지 추정하고 싶은 파라미터에 대한 posterior는 아래와 같다.

\[ \beta_1|\beta_0,\tau,\tau_0,\mu_0,x,y \sim N(\frac{\tau_1\mu_1 + \tau \sum_i(y_i-\beta_0 x_i)}{\tau_1 + \tau \sum_ix_i{^2}}, 1/(\tau_1 + \tau \sum_ix_i{^2}))\]

\[ \tau|\beta_0,\beta_1, \alpha, \beta ,x,y \sim Gamma(\alpha+\frac{N}{2}, \beta + \sum_i( \frac{(y_i-\beta_0-\beta_1x_i)^2}{2}) \] 이제 posterior를 알았으니, Gibbs sampling을 이용해 이를 추정해보자.

 

# Hyperparameters (Prior) 
k.mu0 <- 0
k.mu1 <- 0
k.tau0 <- 1
k.tau1 <- 1
k.alpha <- 2
k.beta <- 1
# Initial parameter (임의의 값)
k.beta0 <- 0
k.beta1 <- 0
k.tau <- 2

# Simulation을 위한 데이터 생성. 
beta.true <- 2
int.true <- -1
tau.true <- 1
x <- runif(min = 0, max = 4, 100)
y <- beta.true*x + int.true + rnorm(100, mean=0, sd=1/tau.true)
plot(x,y)

 

관찰한 데이터

 

full condition pdf에서 sample 추출하는 함수 정의

get.beta0.sample <- function(beta1, tau, tau0, mu0, x, y) { 
  N <- length(y) 
  precision <- tau0 + tau*N 
  mean <- tau0 * mu0 + tau * sum(y - beta1 * x) 
  mean <- mean/precision 
  result <- rnorm(1, mean=mean,sd=1/sqrt(precision)) 
  return(result) 
}
get.beta1.sample <- function(beta0, tau, tau1, mu1, x, y) {
  N <- length(y)
  precision <- tau1 + tau*sum(x*x)
  mean <- tau1 * mu1 + tau * sum((y - beta0) * x)
  mean <- mean/precision
  result <- rnorm(1, mean=mean,sd=1/sqrt(precision))
  return(result)
}
get.tau.sample <- function(x, y, beta0, beta1, alpha, beta){
  N <- length(y)
  alpha_new <- alpha + N / 2
  resid <- y - beta0 - beta1 * x
  beta_new <- beta + sum(resid * resid)/2
  return(rgamma(1, shape=alpha_new, scale=1/beta_new))
}
# Burn-in period를 제거하고 result를 저장
burnin <- 9000
result <- trace[-burnin,]
# Prior와 Posterior 비교하기
temp_x <- seq(from=-3,to=3,by = 0.01)
beta0.prior <- dnorm(x=temp_x, mean=k.mu0, sd=1/k.tau0)
beta0.post <- result[,'beta0']
plot(temp_x, beta0.prior)

 

hist(beta0.post)

 

temp_x <- seq(from=-3,to=3,by = 0.01)
beta1.prior <- dnorm(x=temp_x, mean=k.mu1, sd=1/k.tau1)
beta1.post <- result[,'beta1']
plot(temp_x, beta1.prior)

 

hist(beta1.post)

 

temp_x <- seq(from=0,to=10,by = 0.01)
tau.prior <- dgamma(x=temp_x, shape=k.alpha, scale = k.beta)
tau.post <- result[,'tau']
plot(temp_x, tau.prior)

hist(tau.post)

 

 

참고 

https://kieranrcampbell.github.io/blog/2016/05/15/gibbs-sampling-bayesian-linear-regression.html

반응형
반응형


Markov Chain Monte Carlo


Basic Idea


어떤 분포(pdf)로부터 데이터를 sampling 하거나, 분포의 기댓값을 구하기 위해 사용하는 방법이다. high-dimensional pdf일 경우 이 pdf에서 데이터를 샘플링하기가 힘든데, 이를 하기 위한 방법이 MCMC이다. 또는 MCMC는 uncertain parameter model에서 parameter을 추정할 때 쓰기도 한다. 


기본 아이디어는 다음과 같다. 


1. 시작점을 정하고 그 지점에서의 확률(pdf(x))을 구한다. 

2. 그 지점에서 이동할 수 있는 임의의 지점을 정한다. (이를 주로 "random walk" 라고 부른다.)

3. 만약 그 지점의 확률이 이전 지점보다 높다면 이동하고, 낮으면 이동하지 않거나, 어떤 확률로 이동한다. (이는 강화학습에서의 exploit & explore의 원리와 비슷하다.)


이러한 절차를 계속하다보면 실제 pdf에서 데이터가 나온 것처럼 샘플링할 수 있다. 왜 이것이 Markkov Chain인가하면, 2번 단계에서 임의의 지점을 정할 때, 이전 단계에만 의존적이기 때문이다. 


MCMC를 구현하는 알고리즘은 크게 두 가지 방법이 있는데 우선 Metropolis-Hastings algorithm을 살펴보자.


Metropolis-Hastings algorithm


여기서 Q는 proposal distribution P*(x)는 high-dimensional pdf 이다. 이 때, Q는 random walk를 샘플링할 분포로 대칭 분포여야하며, 잘 설정되어야한다. (즉, Q(x|y) = Q(y|x) 여야 한다.) 이 알고리즘을 먼저 간단히 기술해보면, x(1)을 임의로 고른 후, Q(x;x(1)) 에서 x(2)를 샘플링한다. 이 때, P*(x(2))가 P*(x(1))보다 크면, alpha의 확률로 accpet해서 이동하고, 1-alpha의 확률로 reject한다. 이 때, alpha는 acceptance ratio인데 alpha = P*(x(2))/P*(x(1)) 이다. 즉, 이동한 점의 pdf값이 이전 값보다 크면 무조건 이동하고, 이전값보다 작으면 일정 확률로 이동하는데 이 일정확률은 이후값과 이전값의 ratio이다. 



위키피디아의 좀 더 자세한 알고리즘도를 보면 아래와 같다. 


  1. Initialization: Choose an arbitrary point x0 to be the first sample, and choose an arbitrary probability density  (sometimes written ) that suggests a candidate for the next sample value x, given the previous sample value y. For the Metropolis algorithm, g must be symmetric; in other words, it must satisfy . A usual choice is to let  be a Gaussian distribution centered at y, so that points closer to y are more likely to be visited next—making the sequence of samples into a random walk. The function g is referred to as the proposal density or jumping distribution.
  2. For each iteration t:
    • Generate : Generate a candidate x for the next sample by picking from the distribution .
    • Calculate : Calculate the acceptance ratio , which will be used to decide whether to accept or reject the candidate. Because f is proportional to the density of P, we have that .
    • Accept or Reject :
      • Generate a uniform random number u on [0,1].
      • If  accept the candidate by setting ,
      • If  reject the candidate and set , instead.


MCMC(Metropolis-Hastings algorithm)를 통해 파라미터를 추정(파라미터를 샘플링)하는 것도 이와 비슷한 절차를 따른다. 


1. 모델의 초기 파라미터 값을 정한다. (이는 랜덤으로 정해도 되고, 기존 문헌의 정보가 있다면 이를 활용한다.)

2. 파라미터를 랜덤하게 선택해서 "이후 파라미터"를 구한다. 

3. 초기 파라미터에서의 cost와 이후 파라미터의 cost를 비교해, 이후 파라미터의 cost가 작으면 파라미터를 업데이트한다. (ex. cost = Mean absolute error)

4. 만약 이후 파라미터의 cost가 크면 alpha의 확률로 파라미터를 업데이트 한다. 

5. alpha는 예를 들어 exp(-(cost(이후)-cost(이전)) 으로 정할 수 있다. (이후 cost가 크면 이 값은 0에서 1사이의 값을 같기 때문에 확률로 쓰는것)


최종적으로 MCMC를 통해 나오는 것은 파라미터의 분포이다. 이 분포에서 어떤 값을 파라미터의 추정값으로 쓸 것인가도 하나의 문제이다. 예를 들어, MLE, 평균 등을 쓸 수 있다.


참고

https://www.youtube.com/watch?v=h1NOS_wxgGg


반응형
반응형


SAMtools BCFtools 1.8버전 설치


다운로드 링크

http://www.htslib.org/download/


설치 절차

1. 위 링크에서 우분투 운영체제 wget을 통해 samtools, bcftools tar.gz2 파일을 다운받는다.

2. tar -xvf [파일명] 을 통해 압축을 해제한다.

3. 이 때, 압축 해제는 아무데나 해도된다.


cd samtools-1.x    # and similarly for bcftools and htslib
./configure --prefix=/where/to/install
make
make install

4. 이후 /where/to/install/bin에 samtools binary 파일이 생성된다.

5. /usr/bin 에 심볼릭 링크를 만들어준다.


sudo ln -s /where/to/install/bin /usr/bin/samtools


6. samtools --version  명령어를 통해 잘 설치 되었는지 확인한다.


BCFTools도 이와 마찬가지 방법이다. 폴더 명만 바꿔주면된다.


반응형

'Domains > Bioinformatics' 카테고리의 다른 글

Functional genomics - Chip-seq 의 기초  (1) 2019.09.05
GATK4 설치  (0) 2018.02.20
Chip-seq 데이터를 통한 binding motif 분석 [rGADEM]  (0) 2018.01.13
Variant calling 이란?  (0) 2017.11.20
IGV Tutorial [BAM File]  (0) 2017.10.16
반응형
제목

부모-자식 데이터를 통한 유전율 추정


본 포스팅은 부모-자식 데이터를 통해 heritability를 추정하는 것을 포스팅한다. 아래 데이터는 parent와 child의 height를 나타내는 수치이다. 옥수수의 키라고 생각하자. 알고 싶은 것은 child의 키가 유전적 요소로 설명되는 정도이다. 우리는 이 수치를 heritability(h^2)라는 값으로 표현한다. 데이터는 이곳에서 다운로드 할 수 있다.


\[ h^2 = \frac{V(G)}{V(Y)}\]

library(data.table)
## Warning: package 'data.table' was built under R version 3.4.3
load("C:\\workspace\\r\\genetics\\data\\mod7_data.R")
  head(Galton)
##     parent child
  ## 1 71.40788  61.7
  ## 2 68.57945  61.7
  ## 3 64.33681  61.7
  ## 4 62.92260  61.7
  ## 5 62.21549  61.7
  ## 6 67.16524  62.2

데이터에 약간의 random error를 주어 아래의 그래프를 통해 표현해보자.

plot(Galton$parent+rnorm(928,0,.1),Galton$child+rnorm(928,0,.1),xlab="Father's Height",ylab="Child's Height")
  abline(v=mean(Galton[,1]),col=2,lty=3,lwd=3)
  abline(h=mean(Galton[,2]),col=2,lty=3,lwd=3)
  abline(a=0,b=1,col=2,lty=3,lwd=3)

summary(lm(Galton$child~Galton$parent))
## 
  ## Call:
  ## lm(formula = Galton$child ~ Galton$parent)
  ## 
  ## Residuals:
  ##     Min      1Q  Median      3Q     Max 
  ## -7.8050 -1.3661  0.0487  1.6339  5.9264 
  ## 
  ## Coefficients:
  ##               Estimate Std. Error t value Pr(>|t|)    
  ## (Intercept)   36.87187    1.98827   18.55   <2e-16 ***
  ## Galton$parent  0.45700    0.02909   15.71   <2e-16 ***
  ## ---
  ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
  ## 
  ## Residual standard error: 2.239 on 926 degrees of freedom
  ## Multiple R-squared:  0.2105, Adjusted R-squared:  0.2096 
  ## F-statistic: 246.8 on 1 and 926 DF,  p-value: < 2.2e-16

회귀계수가 0.457이다. 이 때, 유전율은 0.457*2 = 약 92%로 추정된다. 왜 그런지 살펴보기 위해 우선 beta의 추정치를 아래와 같이 회귀식의 양변에 Cov(, X)를 취해 구해보자.


\[ Y = \alpha + \beta X \] \[ Cov(Y, X) = \beta Cov(X,X) \] \[ \hat{\beta} = \frac{Cov(Y,X)}{Var(X)} \]

Phenotype Y에 대해 아래와 같은 일반적인 Phenotype에 대한 모델을 세우자. 이 때, A,D,C,E 각각의 컴포넌트들에 대한 것은 나중에 살펴보고 i, j 두 개체의 Covariance만 살펴본다. A : additive effect D : dominance effect C : shared environment effect E : residuals \[ Y = A + D + C + E\] r은 relatedness, k2는 genome상의 IBD2의 비율, a는 shared environment를 나타내는 수치이다. 만약 shared environment이면 a=1, 아니면 a=0이다. 



이 Covariance 모델은 어디까지나 가정이다. 이 가정 하에서 각각의 Variance를 추정하고 이를 통해 heritability를 추정하게 된다.

\[ E[Cov(Y_i, Y_j)] = rVar(A) + k_2Var(D) + aVar(C)\]

이제 현재 데이터에서 위 식을 적용하자. 이 때, r=0.5, k2=0, a=0을 가정하자. (부모-자식 간의 IBD2=0이므로 k2=0이다. ) 그러면 랜덤으로 i번째 부모-자식 pair를 골랐을 때, Covariance 모델은 아래와 같다. (P : Parent, C : Child의 약자)


이러면 Var(D)가 사라지기 때문에 우리는 쉽게 Var(A)를 데이터를 통해 추정할 수 있다.

\[ E[Cov(P_i, C_i)] = 0.5Var(A)\] \[ Var(A) = 2E[Cov(P_i, C_i)] \]

print(var(Galton$parent))
## [1] 6.389121
print(var(Galton$parent, Galton$child)) # Sample Covariance
## [1] 2.919806

따라서 위 데이터에는 D(Dominance effect가 없으므로 아래와 같이 유전율을 추정할 수 있다.) \[ h^2 = \frac{V(G)}{V(Y)} = \frac{V(A)}{V(P)} \]

따라서 2.91*2 = 5.82 = Var(A) 이다. Var(P) = 6.39 (Phenotype의 분산을 V(P)로 추정) 이므로 이 모델하에서 추정한 유전율은 아래와 같다.

\[ \frac{V(A)}{V(P)} = 5.82/6.39 = 0.91 \]

print(paste0("Heritability : ", 2*var(Galton$parent, Galton$child) / var(Galton$parent)))
## [1] "Heritability : 0.913992906289406"

따라서 부모-자식 데이터에 이러한 모델을 통해 유전율을 추정할 때 유전율은 회귀계수의 2배를 해주면 된다.


참고

https://jvanderw.une.edu.au/AGSCcourse.htm

반응형