이번 포스팅에서는 분류 모델 (classification model) 의 성능을 비교 평가할 수 있는 지표(evaluation metrics)들에 대해서 소개하겠습니다. 

 

(1) 혼돈 매트릭스 (Confusion Matrix)

(2) 혼돈 매트릭스 기반 분류 모델 성능 평가 지표

    - 정확도 (Accuracy)

    - 재현율 (Recall rate), 민감도 (Sensitivity)

    - 특이도 (Specificity)

    - 정밀도 (Precision)

    - F-1 점수 (F-1 Score)

(3) 정밀도와 재현율의 상충 관계 (Precision/ Recall Trade-off)

(4) 분류 확률 기반 ROC Curve, AUC (Area Under the ROC Curve)

(5) Python 을 이용한 분류 모델 성능 평가 (다음번 포스팅)

 

 

 

(1) 혼돈 매트릭스 (Confusion Matrix)

 

먼저 범주의 정답(Y, Label)을 알고 있는 데이터의 실제 값 (Actual) 과 분류 모델을 통해 분류한 예측 값 (Predicted) 을 평가하여 아래와 같은 표의 형태로 객체의 수를 셉니다. Positive 는 '1'/ 'Success'/ 'Pass'/ 'Live' 등에 해당하며, Negative 는 '0'/ 'Fail'/ 'Non Pass'/ 'Dead' 등을 의미합니다. 

 

TP (True Positive), FP (False Positive), FN (False Negative), TN (True Negative) 는 아래의 표를 보면 의미가 더 명확할거예요. (P와 N은 예측치를 의미하며, 이걸 실제 값과 비교했을 때 맞혔으면 True, 틀렸으면 False 로 표기한 것임)

 

책에 따라서 '실제 값 (Actual)'과 '예측 값 (Predicted)' 의 축이 다른 경우도 있으니 가로 축과 세로 축이 무엇을 의미하는지 꼭 확인이 필요합니다. 

 

confusion matrix

 

 

 

(2) 혼돈 매트릭스 기반 분류 모델 성능 평가 지표

 

모든 관측치의 개수를 N (= TP + TN + FP + FN) 이라고 하면, 

 

    - 정확도 (Accuracy) = (TP + TN) / N

    - 재현율 (recall rate), 민감도 (Sensitivity) = TP / (TP + FN)

    - 특이도 (Specificity) = TN / (FP + TN)

    - 정밀도 (Precision) = TP / (TP + FP)

    - F1 점수 (F1 Score) = 1 / (1/Precision + 1/Recall)

 

의 수식을 이용해서 구할 수 있습니다. 

F-1 점수 (F-1 Score)는 정밀도와 재현율의 조화평균(harmonic mean, 역수의 산술평균의 역수)으로서, 정밀도와 재현율이 균형있게 둘 다 높을 때 F-1 점수도 높게 나타납니다. 정밀도와 재현율이 모두 중요한 경우에는 F-1 점수를 사용해서 모델을 평가하면 됩니다. 

 

accuracy, recall rate, sensitivity, specificity, precision, F-1 score

 

 

 

(3) 정밀도와 재현율의 상충 관계 (Precision/ Recall Trade-off)

 

정밀도(Precision)와 재현율(Recall rate)은 분류 예측을 위한 의사결정 기준점(decision threshold)을 얼마로 하느냐에 따라 달라집니다. (의사결정 기준점에 따라 혼돈 매트릭스의 4사분면의 각 숫자가 달라짐) 

정밀도와 재현율은 상충 관계에 있어서, 마치 시소 게임처럼 정밀도가 높아지면 재현율이 낮아지고, 반대로 재현율이 높아지면 정밀도는 낮아집니다. 이 상충관계를 잘 이해해야 왜 이렇게 많은 분류 모델 성과평가 지표가 존재하고 필요한지 이해할 수 있습니다. 

 

보통은 '양성(Positive, 1)' 으로 분류할 확률이 의사결정 기준점 '0.5' 보다 크면 '양성 (Positive, 1)' 로 분류하고, '0.5' 보다 같거나 작으면 '음성 (Negative, 0)' 으로 분류를 합니다. (아래 그림의 (2)번 케이스)

 

만약 '실제 양성' (Actual Positive) 을 더 많이 잡아내고 싶으면 (실제 음성을 양성으로 오분류할 비용을 감수하고서라도), 의사결정 기준점을 내려주면 됩니다. (아래 그림의 (1)번 케이스) 그러면 재현율(Recall rate)은 올라가고, 정밀도(Precision) 은 낮아집니다. 

 

만약 '예측한 양성'이 실제로도 양성인 비율 (즉, 정밀도, Precision)을 높이고 싶으면 의사결정 기준점을 올려주면 됩니다. (아래 그림의 (3)번 케이스). 그러면 정밀도(Precision)은 올라가고, 재현율(Recall rate)은 내려가게 됩니다. 

 

precision/ recall trade-off

 

의사결정 기준점을 변경하고 싶다면 비즈니스 목적 상 재현율과 정밀도 중에서 무엇이 더 중요한 지표인지, 실제 양성을 놓쳤을 때의 비용과 예측한 양성이 실제로는 음성이었을 때의 비용 중에서 무엇이 더 끔찍한 것인지를 생각해보면 됩니다. 

 

가령, 만약 코로나 진단 키트의 분류 모델이라면 '실제 양성 (즉, 코로나 감염)' 인 환자가 '음성'으로 오분류 되어 자가격리 대상에서 제외되고 지역사회에 코로나를 전파하는 비용이 '실제 음성 (즉, 코로나 미감염)' 인 사람을 '양성'으로 오분류했을 때보다 비용이 더 크다고 할 수 있으므로 (1) 번 케이스처럼 의사결정 기준점을 내려서 재현율(Recall rate)을 올리는게 유리합니다. 

 

반면, 유튜브에서 영유아용 컨텐츠 적격 여부를 판단하는 분류모델을 만든다고 했을 때는, 일단 분류모델이 '영유아용 적격 판단 (Positive)' 을 내련 영상 컨텐츠는 성인물/폭력물/욕설 등의 영유아용 부적격 컨텐츠가 절대로 포함되어 있으면 안됩니다. 이럴경우 일부 실제 영유아용 적격 컨텐츠가 '부적격'으로 오분류되는 비용을 감수하고서라도 (3)번 케이스처럼 의사결정 기준점을 올려서 정밀도를 높게 해주는 것이 유리합니다. 

 

그리고, 극도로 불균형한 데이터셋 (extremely imbalanced dataset) 의 경우 정확도(Accuracy) 지표는 모델을 평가하는 지표로 부적절합니다. 이때는 비즈니스 목적에 맞게 재현율과 정밀도 중에서 선택해서 사용하는 것이 필요합니다. (양성이 희소한 경우 모델이 모두 음성이라고 예측해도 정확도 지표는 매우 높게 나옴. 하지만 우리는 희소한 양성을 잘 찾아내는 모델을 원하지 모두가 다 음성이라고 예측하는 쓸모없는 모델을 원하지는 않음.)

 

 

 

(4) 분류 확률 기반 ROC Curve, AUC (Area Under the ROC Curve)

 

ROC 곡선(Receiver Operating Characteristic Curve)은 모든 분류 의사결정 기준값(decision threshold)에서 분류 모델의 성능을 보여주는 그래프입니다. X축은 False Positive Rate, Y축은 True Positive Rate 으로 하여 모든 의사결정 기준값 (Positive 일 확률) 별로 혼돈 매트릭스를 구하고, 여기에서 재현율과 특이도를 구해서 TPR과 FPR을 구하고, 이를 선으로 연결해주면 됩니다. 

 

ROC Curve

 

ROC 곡선은 45도 대각선이 무작위로 추측하여 분류했을 때를 의미하며, ROC 곡선이 좌측 상단으로 붙으면 붙을 수록 분류 모델의 성능이 더 좋다고 해석합니다. (False Positive Rate 보다 True Positive Rate이 상대적으로 더 높을 수록 더 좋은 분류 모델임)

 

 

AUC (Area Under the ROC Curve) 점수는 위의 ROC 곡선의 아랫 부분을 적분하여 하나의 수치로 분류 모델의 성능을 표현한 것입니다. AUC 점수가 높으면 높을 수록 더 좋은 분류 모델입니다.  

 

ROC 곡선과 AUC 모두 분류 모델이 '양성일 확률(probability)'을 반환할 때만 계산이 가능합니다.

(즉, 모델이 분류할 범주(category, class)로 예측값을 반환하면 ROC 곡선, AUC 계산 불가)

 

AUC

 

 

다음번 포스팅에서는 Python을 이용한 분류모델 성능 평가를 해보겠습니다. 

(https://rfriend.tistory.com/772)

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요!  :-)

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 마지막 네번째 포스팅으로서, 12개의 설명변수를 사용하여 유방암 악성, 양성 여부 진단하는 로지스틱 회귀모형을 훈련 데이터셋으로 적합시켜보고, 테스트셋에 대해 모델 성능을 평가하며, 모델의 회귀계수를 가지고 해석을 해보겠습니다. 


[로지스틱 회귀분석을 통한 유방암 예측(분류) 포스팅 순서]

  1. WDBC(Wisconsin Diagnostic Breast Cancer) dataset 소개 및 분석 목적과 방향 설정
  2. 탐색적 데이터 분석 및 전처리
  3. 1차 변수 선택 및 목표변수와 설명변수 간 관계 분석
  4. 로지스틱 회귀모형 적합 및 모델 평가, 해석



이번 포스팅은 아래의 순서대로 분석을 진행해보겠습니다. 

(탐색적 데이터 분석 및 전처리는 이전 포스팅 참고 => http://rfriend.tistory.com/400)


(1) training set (80%) vs. test set (20%) 분리

(2) 로지스틱 회귀모형 적합 (w/ training set)

(3) 후진 소거법 (backward elimination)

(4) 모델 성능 평가 (w/ test set) : confusion matrix, ROC curve

(5) 모델 해석



  (1) training set (80%) vs. test set (20%) 분리


569개 관측치를 가진 데이터셋을 (a) 모형 적합에 사용할 훈련용 데이터셋(training set), (b) 모형 성능 평가에 사용할 테스트 데이터셋(test set) 으로 나누어 보겠습니다. 이번 포스팅에서는 training : test 를 8:2 비율로 나누어서 분석하였습니다. 


만약 training set으로 훈련한 모델의 정확도는 높은데 test set을 대상으로 한 정확도는 낮다면 과적합(overfitting)을 의심해볼 수 있습니다. 




로지스틱 회귀모형을 적합하는데는 나중에 회귀계수 해석하기에 용이하도록 표준화하기 이전의 원래의 데이터를 사용하였으며, training : test = 8:2 로 나누기 위해 base패키지의 sample() 함수를 사용하여 indexing을 위한 무작위 index를 생성해두었습니다. 


참고로, 아래 코드의 train, test, Y.test에는 관측치 측정치가 들어있는 것이 아니라 나중에 indexing을 위한 index 정보 (랜덤 샘플링 indexing 할 위치 정보)가 들어 있습니다. 다음번 glm() 함수에서 subset argument에 train, test index를 사용할 예정입니다. 



> ##=========================

> ## fitting logistic regression

> #----------

> # data set with 12 input variable and Y variable

> wdbc_12 <- data.frame(Y, wdbc[,x_names_sorted])

> str(wdbc_12)

'data.frame': 569 obs. of  13 variables:

 $ Y                      : num  1 1 1 1 1 1 1 1 1 1 ...

 $ concavity_se           : num  0.0537 0.0186 0.0383 0.0566 0.0569 ...

 $ compactness_se         : num  0.049 0.0131 0.0401 0.0746 0.0246 ...

 $ fractal_dimension_worst: num  0.1189 0.089 0.0876 0.173 0.0768 ...

 $ symmetry_mean          : num  0.242 0.181 0.207 0.26 0.181 ...

 $ smoothness_mean        : num  0.1184 0.0847 0.1096 0.1425 0.1003 ...

 $ concave.points_se      : num  0.0159 0.0134 0.0206 0.0187 0.0188 ...

 $ texture_mean           : num  10.4 17.8 21.2 20.4 14.3 ...

 $ symmetry_worst         : num  0.46 0.275 0.361 0.664 0.236 ...

 $ smoothness_worst       : num  0.162 0.124 0.144 0.21 0.137 ...

 $ perimeter_se           : num  8.59 3.4 4.58 3.44 5.44 ...

 $ area_worst             : num  2019 1956 1709 568 1575 ...

 $ concave.points_mean    : num  0.1471 0.0702 0.1279 0.1052 0.1043 ...

> # split train(0.8) and test set(0.2)

> set.seed(123) # for reproducibility

> train <- sample(1:nrow(wdbc_12), size=0.8*nrow(wdbc_12), replace=F)

> test <- (-train)

> Y.test <- Y[test]

 




  (2) 로지스틱 회귀모형 적합 (w/ training set)


R의 stats 패키지의 glm() 함수로 training set의 12개 설명변수를 모두 사용하여 로지스틱 회귀모형을 적합하여 보겠습니다. 회귀계수 모수 추정은 최대가능도추정(Maximum Likelihood Estimation)법을 통해서 이루어집니다. 




참고로, GLM 모형의 family 객체에 들어갈 random components 와 link components 에 사용할 수 있는 arguments 는 아래와 같습니다. 


[ Family Objects for Models ]


binomial(link = "logit")  # logistic regression model

poisson(link = "log") # poisson regression model

gaussian(link = "identity") # linear regression model

Gamma(link = "inverse") # gamma regression model

inverse.gaussian(link = "1/mu^2")

quasi(link = "identity", variance = "constant")

quasibinomial(link = "logit")

quasipoisson(link = "log") 




> # train with training set

> glm.fit <- glm(Y ~ ., 

+                data = wdbc_12, 

+                family = binomial(link = "logit")

+                subset = train)

Warning message:

glm.fit: 적합된 확률값들이 0 또는 1 입니다 

> summary(glm.fit)


Call:

glm(formula = Y ~ ., family = binomial(link = "logit"), data = wdbc_12, 

    subset = train)


Deviance Residuals: 

    Min       1Q   Median       3Q      Max  

-1.8232  -0.0662  -0.0074   0.0001   3.8847  


Coefficients:

                           Estimate  Std. Error z value Pr(>|z|)    

(Intercept)              -36.903201    9.099492  -4.056  0.00005 ***

concavity_se              29.311264   22.989079   1.275 0.202306    

compactness_se          -100.786803   36.755041  -2.742 0.006104 ** 

fractal_dimension_worst   37.094117   43.007209   0.863 0.388407    

symmetry_mean             19.015372   30.163882   0.630 0.528432    

smoothness_mean         -109.619744   74.382548  -1.474 0.140554    

concave.points_se       -123.097155  203.980072  -0.603 0.546192    

texture_mean               0.393147    0.107909   3.643 0.000269 ***

symmetry_worst            13.278414   10.461508   1.269 0.204347    

smoothness_worst         105.722805   35.197258   3.004 0.002667 ** 

perimeter_se               1.033524    0.780904   1.323 0.185670    

area_worst                 0.013239    0.003786   3.496 0.000472 ***

concave.points_mean      104.113327   46.738810   2.228 0.025910 *  

---

Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


(Dispersion parameter for binomial family taken to be 1)


    Null deviance: 601.380  on 454  degrees of freedom

Residual deviance:  60.175  on 442  degrees of freedom

AIC: 86.175


Number of Fisher Scoring iterations: 10

 


각 회귀계수의 유의성을 Wald-test()를 통해 해보면 'concave.points_se' 변수가 p-value가 0.54192이므로 유의수준 5% 하에서 [귀무가설(H0): 회귀계수 beta(concave.points_se) = 0]을 채택합니다. 즉, 반응변수에 concave.points_se 변수는 별 영향 혹은 관련이 없다고 판단할 수 있습니다. 따라서 제거를 해도 되겠습니다. 



Wald Test

  • 통계량  
  • 귀무가설(): 회귀계수 
  • 대립가설(): 회귀계수 




  (3) 후진 소거법 (backward elimination)


위의 (2)번 처럼 전체 변수를 포함한 full model (saturated model)에서 시작해서, 가장 유의미하지 않은 변수(가장 큰 p-value 값을 가지는 변수)를 제거하고, 다시 모형을 적합하고, 남은 예측변수가 모두 유의할 때까지 계속 순차적으로 가장 유의미하지 않은 변수를 계속 제거해나가는 후진 소거법(backward elimination)을 사용해서 모델을 적합하겠습니다. 이로써, 모델의 정확도는 어느정도 유지하면서도 해석하기에 용이한 가장 간소한(parsimonious) 모델을 만들어보겠습니다. 



> # Backward Elimination Approach

> # remove 'concave.points_se' variable

> glm.fit.2 <- glm(Y ~ concave.points_mean + area_worst + 

+                    perimeter_se + smoothness_worst + symmetry_worst +

+                    texture_mean + smoothness_mean + symmetry_mean + 

+                    fractal_dimension_worst + compactness_se + concavity_se, 

+                  data = wdbc_12, 

+                  family = binomial(link = "logit")

+                  subset = train)

Warning message:

glm.fit: 적합된 확률값들이 0 또는 1 입니다 

> summary(glm.fit.2)


Call:

glm(formula = Y ~ concave.points_mean + area_worst + perimeter_se + 

    smoothness_worst + symmetry_worst + texture_mean + smoothness_mean + 

    symmetry_mean + fractal_dimension_worst + compactness_se + 

    concavity_se, family = binomial(link = "logit"), data = wdbc_12, 

    subset = train)


Deviance Residuals: 

    Min       1Q   Median       3Q      Max  

-1.8363  -0.0645  -0.0076   0.0001   3.8297  


Coefficients:

                           Estimate  Std. Error z value  Pr(>|z|)    

(Intercept)              -37.182194    8.981711  -4.140 0.0000348 ***

concave.points_mean       87.773808   37.117336   2.365  0.018041 *  

area_worst                 0.013785    0.003734   3.692  0.000222 ***

perimeter_se               0.894502    0.747623   1.196  0.231517    

smoothness_worst         104.169968   35.281001   2.953  0.003151 ** 

symmetry_worst            15.057387   10.048439   1.498  0.134009    

texture_mean               0.385946    0.105254   3.667  0.000246 ***

smoothness_mean         -103.800173   73.953483  -1.404  0.160442    

symmetry_mean             10.952803   26.586484   0.412  0.680362    

fractal_dimension_worst   42.376803   42.322307   1.001  0.316688    

compactness_se           -98.379602   35.688499  -2.757  0.005840 ** 

concavity_se              18.847381   13.973683   1.349  0.177409    

---

Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


(Dispersion parameter for binomial family taken to be 1)


    Null deviance: 601.380  on 454  degrees of freedom

Residual deviance:  60.551  on 443  degrees of freedom

AIC: 84.551


Number of Fisher Scoring iterations: 10


> # remove 'symmetry_mean' variable

> glm.fit.3 <- glm(Y ~ concave.points_mean + area_worst + 

+                    perimeter_se + smoothness_worst + symmetry_worst +

+                    texture_mean + smoothness_mean + 

+                    fractal_dimension_worst + compactness_se + concavity_se, 

+                  data = wdbc_12, 

+                  family = binomial(link = "logit")

+                  subset = train)

Warning message:

glm.fit: 적합된 확률값들이 0 또는 1 입니다 

> summary(glm.fit.3)


Call:

glm(formula = Y ~ concave.points_mean + area_worst + perimeter_se + 

    smoothness_worst + symmetry_worst + texture_mean + smoothness_mean + 

    fractal_dimension_worst + compactness_se + concavity_se, 

    family = binomial(link = "logit"), data = wdbc_12, subset = train)


Deviance Residuals: 

    Min       1Q   Median       3Q      Max  

-1.7842  -0.0630  -0.0083   0.0001   3.7588  


Coefficients:

                          Estimate Std. Error z value  Pr(>|z|)    

(Intercept)             -36.121685   8.504448  -4.247 0.0000216 ***

concave.points_mean      89.488263  37.243081   2.403  0.016269 *  

area_worst                0.013329   0.003532   3.774  0.000161 ***

perimeter_se              0.976273   0.722740   1.351  0.176762    

smoothness_worst        100.865240  33.783402   2.986  0.002830 ** 

symmetry_worst           17.885605   7.503047   2.384  0.017136 *  

texture_mean              0.382870   0.103885   3.686  0.000228 ***

smoothness_mean         -95.335007  70.234774  -1.357  0.174662    

fractal_dimension_worst  40.176580  41.722080   0.963  0.335569    

compactness_se          -97.950160  35.684347  -2.745  0.006053 ** 

concavity_se             19.800333  13.655596   1.450  0.147064    

---

Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


(Dispersion parameter for binomial family taken to be 1)


    Null deviance: 601.380  on 454  degrees of freedom

Residual deviance:  60.721  on 444  degrees of freedom

AIC: 82.721


Number of Fisher Scoring iterations: 10


> # remove 'fractal_dimension_worst' variable

> glm.fit.4 <- glm(Y ~ concave.points_mean + area_worst + 

+                    perimeter_se + smoothness_worst + symmetry_worst +

+                    texture_mean + smoothness_mean + 

+                    compactness_se + concavity_se, 

+                  data = wdbc_12, 

+                  family = binomial(link = "logit")

+                  subset = train)

Warning message:

glm.fit: 적합된 확률값들이 0 또는 1 입니다 

> summary(glm.fit.4)


Call:

glm(formula = Y ~ concave.points_mean + area_worst + perimeter_se + 

    smoothness_worst + symmetry_worst + texture_mean + smoothness_mean + 

    compactness_se + concavity_se, family = binomial(link = "logit"), 

    data = wdbc_12, subset = train)


Deviance Residuals: 

    Min       1Q   Median       3Q      Max  

-1.6650  -0.0653  -0.0079   0.0001   3.9170  


Coefficients:

                       Estimate  Std. Error z value  Pr(>|z|)    

(Intercept)          -33.656002    7.809704  -4.310 0.0000164 ***

concave.points_mean   96.137001   36.867939   2.608  0.009118 ** 

area_worst             0.012905    0.003435   3.757  0.000172 ***

perimeter_se           0.676729    0.642490   1.053  0.292208    

smoothness_worst     109.530724   32.239695   3.397  0.000680 ***

symmetry_worst        19.724732    7.543696   2.615  0.008930 ** 

texture_mean           0.381544    0.103567   3.684  0.000230 ***

smoothness_mean     -101.037553   70.839248  -1.426  0.153784    

compactness_se       -80.383972   30.461425  -2.639  0.008318 ** 

concavity_se          20.771502   14.372162   1.445  0.148385    

---

Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


(Dispersion parameter for binomial family taken to be 1)


    Null deviance: 601.380  on 454  degrees of freedom

Residual deviance:  61.657  on 445  degrees of freedom

AIC: 81.657


Number of Fisher Scoring iterations: 10


> # remove 'perimeter_se' variable

> glm.fit.5 <- glm(Y ~ concave.points_mean + area_worst + smoothness_worst + 

+                    symmetry_worst + texture_mean + smoothness_mean + 

+                    compactness_se + concavity_se, 

+                  data = wdbc_12, 

+                  family = binomial(link = "logit")

+                  subset = train)

Warning message:

glm.fit: 적합된 확률값들이 0 또는 1 입니다 

> summary(glm.fit.5)


Call:

glm(formula = Y ~ concave.points_mean + area_worst + smoothness_worst + 

    symmetry_worst + texture_mean + smoothness_mean + compactness_se + 

    concavity_se, family = binomial(link = "logit"), data = wdbc_12, 

    subset = train)


Deviance Residuals: 

    Min       1Q   Median       3Q      Max  

-1.7487  -0.0602  -0.0079   0.0002   4.2383  


Coefficients:

                      Estimate Std. Error z value  Pr(>|z|)    

(Intercept)         -33.156014   7.674110  -4.321 0.0000156 ***

concave.points_mean  98.900172  35.529247   2.784   0.00538 ** 

area_worst            0.013819   0.003339   4.139 0.0000349 ***

smoothness_worst    105.448378  32.444984   3.250   0.00115 ** 

symmetry_worst       17.412883   6.654537   2.617   0.00888 ** 

texture_mean          0.385751   0.102180   3.775   0.00016 ***

smoothness_mean     -89.410469  70.307291  -1.272   0.20348    

compactness_se      -78.009472  29.946520  -2.605   0.00919 ** 

concavity_se         24.607453  13.153360   1.871   0.06137 .  

---

Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


(Dispersion parameter for binomial family taken to be 1)


    Null deviance: 601.380  on 454  degrees of freedom

Residual deviance:  62.777  on 446  degrees of freedom

AIC: 80.777


Number of Fisher Scoring iterations: 10


> # remove 'smoothness_mean' variable

> glm.fit.6 <- glm(Y ~ concave.points_mean + area_worst + smoothness_worst + 

+                    symmetry_worst + texture_mean +  

+                    compactness_se + concavity_se, 

+                  data = wdbc_12, 

+                  family = binomial(link = "logit"), 

+                  subset = train)

Warning message:

glm.fit: 적합된 확률값들이 0 또는 1 입니다 

> summary(glm.fit.6)


Call:

glm(formula = Y ~ concave.points_mean + area_worst + smoothness_worst + 

    symmetry_worst + texture_mean + compactness_se + concavity_se, 

    family = binomial(link = "logit"), data = wdbc_12, subset = train)


Deviance Residuals: 

    Min       1Q   Median       3Q      Max  

-1.8607  -0.0640  -0.0080   0.0002   4.0912  


Coefficients:

                      Estimate Std. Error z value     Pr(>|z|)    

(Intercept)         -39.164619   6.748646  -5.803 0.0000000065 ***

concave.points_mean  73.504634  27.154772   2.707     0.006792 ** 

area_worst            0.015465   0.003248   4.762 0.0000019175 ***

smoothness_worst     78.962941  23.746808   3.325     0.000884 ***

symmetry_worst       17.429475   6.497808   2.682     0.007310 ** 

texture_mean          0.423250   0.099815   4.240 0.0000223171 ***

compactness_se      -79.556564  29.747330  -2.674     0.007486 ** 

concavity_se         27.279384  12.093534   2.256     0.024089 *  

---

Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


(Dispersion parameter for binomial family taken to be 1)


    Null deviance: 601.380  on 454  degrees of freedom

Residual deviance:  64.446  on 447  degrees of freedom

AIC: 80.446


Number of Fisher Scoring iterations: 10

 



(2)의 12개 설명변수를 사용한 full model에서 시작해서 (3)의 후진소거법(backward elimination)에 의해 5개의 변수를 하나씩 순차적으로 제거하면서 적합한 모형의 결과를 표로 정리하면 아래와 같습니다. 


자유도(df) 대비 이탈도(deviance)와의 차이가 거의 없으므로 후진소거법에 의해 변수를 제거해도 모델에는 별 영향이 없음을 알 수 있습니다. 그리고 AIC(= -2(로그가능도 - 모형에 있는 모수 개수)) 기준에 의하면 6번째 모형 (concave.points_se, symmetry_mean, fractal_dimension_worst, perimeter_se, smoothness_mean 제거한 모형)이 가장 우수한 모형임을 알 수 있습니다.(AIC 값이 가장 작으므로)



6번째 모델의 '귀무가설 H0: 모든 회귀계수 = 0 (무가치한 모형)'에 대한 가능도비 검정(likelihood ratio test) 결과, 


 

> # likelihood ratio test

> LR_statistic = 601.380 - 64.446

> LR_statistic

[1] 536.934

pchisq(LR_statistic, df = (454-447), lower.tail = F)

[1] 9.140339e-112




이므로 적어도 하나의 설명변수는 반응변수를 예측하는데 유의미한 관련이 있다고 볼 수 있다. 



그리고 각 설명변수별 Wald-test 결과 p-value(Pr(>|z|) 가 모두 0.05보다 작으므로, 유의수준 5% 하에서 모두 유의미하다(즉, 반응변수와 관련이 있다)고 판단할 수 있다. 



summary(glm.fit.6)


Call:

glm(formula = Y ~ concave.points_mean + area_worst + smoothness_worst + 

    symmetry_worst + texture_mean + compactness_se + concavity_se, 

    family = binomial(link = "logit"), data = wdbc_12, subset = train)


Deviance Residuals: 

    Min       1Q   Median       3Q      Max  

-1.8607  -0.0640  -0.0080   0.0002   4.0912  


Coefficients:

                      Estimate Std. Error z value     Pr(>|z|)    

(Intercept)         -39.164619   6.748646  -5.803 0.0000000065 ***

concave.points_mean  73.504634  27.154772   2.707     0.006792 ** 

area_worst            0.015465   0.003248   4.762 0.0000019175 ***

smoothness_worst     78.962941  23.746808   3.325     0.000884 ***

symmetry_worst       17.429475   6.497808   2.682     0.007310 ** 

texture_mean          0.423250   0.099815   4.240 0.0000223171 ***

compactness_se      -79.556564  29.747330  -2.674     0.007486 ** 

concavity_se         27.279384  12.093534   2.256     0.024089 *  

---

Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


(Dispersion parameter for binomial family taken to be 1)


    Null deviance: 601.380  on 454  degrees of freedom

Residual deviance:  64.446  on 447  degrees of freedom

AIC: 80.446


Number of Fisher Scoring iterations: 10

 




로지스틱 회귀계수의 95% 신뢰구간은 confint() 함수를 통해 구할 수 있습니다. 



> confint(glm.fit.6)

Waiting for profiling to be done...

                            2.5 %       97.5 %

(Intercept)         -5.483332e+01 -27.92705624

concave.points_mean  2.353047e+01 131.95158315

area_worst           9.906713e-03   0.02282079

smoothness_worst     3.617243e+01 131.06234268

symmetry_worst       6.422548e+00  32.73189772

texture_mean         2.428527e-01   0.64064918

compactness_se      -1.411215e+02 -15.15533223

concavity_se        -1.259598e+01  49.25042906

 




  (4) 모델 성능 평가 (w/ test set) : confusion matrix, ROC curve


모델 성능 평가는 훈련용 데이터셋이 아니라 반드시 테스트셋(test set)을 대상으로 진행해야 합니다! 


(a) confusion matrix를 이용한 분류 정확도, 오분류율을 구해보고, (b) ROC 곡선도 그려보겠습니다. 


(a) Confusion matrix, accuracy, test error rate


cutoff 기준을 이면 이면 으로 예측을 하면, 양성 72개는 모두 양성으로 전부 정확하게 분류를 하였으며, 악성 42개에 대해서는 41개를 악성으로 정확하게 분류하고 1개는 양성으로 오분류 하였습니다. 


따라서 정확도(accuracy) = (TP + TN) / N = (72 + 41)/ 114 = 0.9912281 로서 매우 높게 나왔습니다. 유방암 예측(악성, 양성 분류) 로지스틱 회귀모형이 잘 적합되었네요. 



> # calculate the probabilities on test set

> glm.probs <- predict(glm.fit.6, wdbc_12[test,], type="response")

> glm.probs[1:20]

                6                 8                10                11                12 

0.986917125953939 0.992018931502162 0.998996856414432 0.992792364235021 0.999799557490392 

               13                25                35                39                54 

0.999938548975209 1.000000000000000 0.999981682993826 0.003031968742568 0.999978684326258 

               61                67                72                77                86 

0.000024521469882 0.000434266606978 0.000000006158534 0.002210951131364 0.999999952448192 

               92                98               106               108               115 

0.923496652258054 0.000007994931448 0.998688178459914 0.000576845750543 0.000149114805822 

> # compute the predictions with the threshold of 0.5

> glm.pred <- rep(0, nrow(wdbc_12[test,]))

> glm.pred[glm.probs > .5] = 1

> table(Y.test, glm.pred)

      glm.pred

Y.test  0  1

     0 72  0

     1  1 41

> mean(Y.test == glm.pred) # accuracy

[1] 0.9912281

> mean(Y.test != glm.pred) # test error rate

[1] 0.00877193

 



(b) ROC 곡선 (ROC curve), AUC (The Area Under an ROC Curve)


cutoff 별  'False Positive Rate(1-Specificity)', 'True Positive Rate(Sensitivity)' 값을 연속적으로 계산하여 ROC 곡선을 그려보면 아래와 같습니다. 대각선이 random guessing 했을 때를 의미하며, 대각선으로부터 멀리 떨어져서 좌측 상단으로 곡선이 붙을 수록 더 잘 적합된 모형이라고 해석할 수 있습니다. 


AUC(Area Under an ROC Curve)는 ROC 곡선 아래 부분의 면적의 합이며, 1이면 완벽한 모델, 0.5면 random guessing한 모델의 수준입니다. AUC가 0.9 이상이면 매우 우수한 모형이라고 할 수 있습니다. 


이번 로지스틱회귀모형은 ROC 곡선을 봐서도 그렇고, AUC가 0.9933로서 아주 잘 적합된 모형이네요. 



> # ROC curve

> install.packages("ROCR")

> library(ROCR)

> pr <- prediction(glm.probs, Y.test)

> prf <- performance(pr, measure = "tpr", x.measure = "fpr")

> plot(prf, main="ROC Curve")




> # AUC (The Area Under an ROC Curve)

> auc <- performance(pr, measure = "auc")

> auc <- auc@y.values[[1]]

> auc

[1] 0.9933862

> detach(wdbc)





  (5) 모델 해석


최종 적합된 로지스틱 회귀모형식은 아래와 같습니다. 

(워드 수식입력기에서 '_'를 입력하니 자꾸 '.'으로 자동으로 바뀌는 바람에 변수이름 구분자 '_'가 전부 '.'로 잘못 입력되었습니다....)




위의 최종 모형으로 부터 다른 설명변수가 고정(통제)되었을 때 설명변수 가 한단위 증가할 때 유방암 악성(M)일 확률의 오즈(odds)는 exp() 배만큼 증가한다는 뜻입니다. 


가령, texture_mean 의 회귀계수가0.42 이므로 이를 해석하자면, 다른 설명변수들이 고정되었을 때 texture_mean이 한 단위 증가할 때 유방암 악성일 확률의 오즈(odds)는 exp(0.42)=1.52 배 증가한다는 뜻입니다. 


악성 유방암일 확률은  

식을 사용해서 구할 수 있습니다. (위의 식 beta_hat 에 추정한 회귀계수를 대입해고 x 값에 관측값을 대입해서 풀면 됩니다)


많은 도움이 되었기를 바랍니다. 


그동안 4번에 걸쳐서 로지스틱 회귀모형 분석에 대해 연재를 했는데요, 혹시 포스팅에 잘못된 부분이나 궁금한 부분이 있으면 댓글로 남겨주시면 수정, 보완하도록 하겠습니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. ^^



728x90
반응형
Posted by Rfriend
,