R 고급 caret을 이용한 머신러닝(로지스틱 회귀 colon 데이터 셋 )

  caret은  대표적인 머신러닝 패키지이다.  이것이 있어서,  R에서는 파이썬 보다 좋은 경쟁력을 가지고 분석 할 수 있다.      즉 파이썬에서 경쟁력이 있는 것은 비정형 자료 즉,  이미지,  문자, 음성등 과 같은 것이다.  개인 적으로는 파이썬의 사이킷런 보다,  이것이 더욱 좋다. 


아래의 예제 코드는 아래의 책을 참고 하여 작성 하였다. 


로지스틱 회귀 실전 예측분석 모델링

1.  변수의 선택 

 변수가 많을 때 변수간 상관관계를 가지고 필터링 하는 예제이다.  변수가 많을 때 주성분 분석하여 변수의 비중을 알아 낼 수 있었지만,  이건은 변수간의 상관관계를 가지고 정리 한것이다. 
# 서바이벌 패키지를 읽어 온다. 
  library(survival)
  library(corrplot)  
  library(caret)  
  library(dplyr)  
  library(tidyr) 
  library(e1071)

  결측치를 찾아 본다 결측치가 있으면,  분석 할 수 없으므로,  이번에는 결측치 있는 셀은 삭제 하기로 한다. 

# na 찾아 보기 
  sum(is.na(colon))
## [1] 82
# 머신러닝을 돌리기 위해 결측치 제거 
  colon  <-  na.omit(colon)  
 머신러닝 할때는 범주형 데이터인 rx : 치료방법 (“Obs”=ervation, “Lev”=amisole, “Lev+5FU”=amisole + 5-FU) 은 인식 할 수 없으므로,   원-핫 인코딩 하여,  각 방법별로, 숫자 1,0을 만든다. 
# 범주형 자료로 되어 rx를 원핫인코딩 한다.   
  dummy <- dummyVars("~.", data= colon)
  new_colon <- data.frame(predict(dummy, newdata = colon))

데이터 레벨의 차이가 크면, 머신러닝에서 연산 할 수 없어서 레벨을 맞추어 준다. 이것은 이후에 나오는 BoxPlot 분석 할때, 매우 용이하다.

# 데이터를 스케일링 한다. (age, nodes, extent, time, etype)
  new_colon <- new_colon %>%
                   mutate ( age = scale(age),
                            nodes = scale(nodes),
                            extent = scale(extent),
                            time = scale(time))
 분산이 0에 가까운 예측 변수를 걸러내고자 할 때는 caret 패키지의 nearZeroVar를 사용해야 하며 예측 변수간의 상관관계를 가지고 변수를 걸러내고 싶다면 cor 함수를 사용해 예측 변수간의 상관관계를 계산 하여야 한다. 
#  종속변수를  아래와 같이 빼고, 예측변수의 상관관계 시각화
   cor_colon <- new_colon %>% select(-c(status))

# 분산이 0인것 삭제
  except <- c(nearZeroVar(cor_colon))
  cor_colon <- cor_colon[-c(except,1)]
 
# 상관관계 분석
  correlations <- cor(cor_colon)

 
데이터 상관관계의 구조를 시각적으로 확인 하고 싶다면, corrplot 패키지의 동일한 이름의 좋은 함수 가 있다.  이 함수에는 높은 상관관계를 가진 예측 변수의 군집을 찾는 식으로 변수 순서를 재배치 할 수 있는 여러 옵션이 있다. 

# 상관관계 구조를 시각적으로 확인한다.  
  corrplot(correlations, order ="hclust")
상관관계 구조 시각화
상관관계를 토대로 변수를 걸러낼 대 findCorrelation 함수를 사용하면 다중 공선성의 문제 즉 변수간의 상관관계가 높아 사용하지 못하는 변수들을 걸러낼 수 있다. 

# 상관관계가 높은 것은 데이터를 걸러낸다. 
  highCorr <- findCorrelation(correlations, cutoff = .75) 
  cor_colon <- cor_colon[, -highCorr]    
 
# 아래에 상관계수가 높은 데이터 셋을 걸러내어 데이터가 나왔다.  
  glimpse(cor_colon)
## Rows: 1,776
## Columns: 13
## $ rx.Obs     <dbl> 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,…
## $ rx.Lev     <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,…
## $ rx.Lev.5FU <dbl> 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,…
## $ sex        <dbl> 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0,…
## $ age        <dbl[,1]> <matrix[26 x 1]>
## $ obstruct   <dbl> 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ adhere     <dbl> 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,…
## $ differ     <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,…
## $ extent     <dbl[,1]> <matrix[26 x 1]>
## $ surg       <dbl> 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1,…
## $ node4      <dbl> 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0…
## $ time       <dbl[,1]> <matrix[26 x 1]>
## $ etype      <dbl> 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 
 참고로 형광색 부분은 원-핫 인코딩 된것이다.

아래는 데이터 전처리 하기전에 Boxplot으로 어떻게 할 것인가 결정 하는 화면이다. 

# 데이터 확인을 위한 BOXPLOT 그리기 
  cor_colon %>% 
    gather( key = "변수명", value = "값") %>% 
    group_by(변수명) %>% 
    ggplot(aes(변수명, 값, fill= 변수명)) +
    geom_boxplot() +
    theme( axis.text.x = element_text(angle = 90),
           legend.position = "none")

adhere. age, differ, etype extent, obstruct 에서  이상치(outlier)가 많이 나왔다. 이것은 모델을 돌리면서 전처리 할 것이다.  특히 age나 adhere 같은 변수는 정규분포에 근사하지 못하므로 center를 맞출 것이다. 

2.  데이터 분할, 모델 튜닝/평가

   데이터 분할을 왜 하는지 처음에 이것을 보았을때 무슨 의미인지 알 수 가 없었다.  하지만 모집단 전체의 데이터를 사용하여, 적합한 모델링을 할 수 있는 경우도 있지만,  대부분 최적의 샘플링을 하여 예측 하게 된다.  특히 단일 테스트 세트로 모델을 평가하기 위한 대안으로 훈련 데이터 세트는 여러가지로 수정 하여 사용한다. 

 모집단 전체를 선택하지 왜 훈련셋을 만드느냐? 쉽게 설명 하면 아래와 같다,  전국에 대통령 선거 여론 조사를 하였는데,  어떤 지역과 특정 연령층의 응답이 높을 경우 모든 데이터를 샘플을 전부 사용하는 것 보다는 지역과 연령층을 고르게 재 샘플링 하는 것이 오히려 예측의 정확도가 높아 진다.  이 문서에서는 모델 성능 평가까지만 다룰 것이다. 

  모델 구축의 일반적인 단계는 아래와 같다. 
  • 예측 데이터 전처리
  • 모델 변수 추정
  • 모델에 사용할 예측 변수 선정
  • 모델성능평가
  • 예측규칙 미세조정(ROC 곡선등)

데이터 분할
 모델 실행 데이터 
  colondf <- cbind(cor_colon, colon$status)
  colnames(colondf)[14] <- "status"
  colondf$status <- as.factor(colondf$status)

# 클래스 레벨을 정한다.     
  levels(colondf$status) <- c("relapse", "dead")
    
# 데이터 셋 나누기 8:2
  set.seed(1001)
  inx   <- createDataPartition(colon$status, p = 0.8, list = F)
  train <- colondf[ inx, ]
  test  <- colondf[-inx, ]
   선택된 데이터를 분할 하고,  target 변수은 status는 머신러닝에서 1,0을 인식 하지 못하므로, 문자형태로 클래스 레벨을 정한다. 

    그리고,  데이터셋은 8:2로 나눈다.  7:3으로 할 수 있으나 대부분 8:2로 많이 나눈다.  파이썬 사이킨런과,  딥러닝은 데이터셋 나누는 것이 조금 다르다. 

 80%의 데이터는 층화 샘플링 하는 것이 좋다.  예전 학부에서 통계학을 배울때,  데이터 샘플링이 가장 중요하다고 하였는데,  편향되지 않게 샘플링 하는 것이 좋다고 하였다.  편향되지 않게 샘플링 하는 것은 리샘플링이 가장 좋다.   

# cross validation 교차 검증 시행
  control <- trainControl(
    method  = "repeatedcv",
    number  = 10,
    repeats = 5,
    search  = "grid",
    classProbs = TRUE)

앞서서 BoxPolt으로 검토 한 바와 같이  BoxCox, center, corr 정의한다.  

 # preprocess 데이터 전처리
  preProc <- c("BoxCox",
               "center",
               "corr"
               )

그리고 이 둘을 묶어서 데이터 모델을 돌린다. 

# logistic regression
  system.time(
    logis <- train( x = train[, -14],
                    y = train[, "status"],
                    method     = "glm",
                    metric     = "Accuracy",
                    trControl  = control,
                    preProcess = preProc) 
    )
##    user  system elapsed 
##   8.794   0.040   8.855
  logis   
## Generalized Linear Model 
## 
## 1421 samples
##   13 predictor
##    2 classes: 'relapse', 'dead' 
## 
## Pre-processing: Box-Cox transformation (1), centered (10), ignore (3) 
## Resampling: Cross-Validated (10 fold, repeated 5 times) 
## Summary of sample sizes: 1279, 1279, 1279, 1279, 1279, 1279, ... 
## Resampling results:
## 
##   Accuracy   Kappa   
##   0.9307545  0.861386

 정확도는 93% 정도 나왔고 Box-Cox transformations은 1개 실행 하였고,  중심화적도를 맞추는 것은 10개,  분산이 같이 무시한것은 3개 였고,  크로스 벨리데이션도 실행 하였다. 





댓글 없음:

댓글 쓰기

css cheat sheet 클래스 선택자, margin(마진), display , center 조정 간단한 구성 요소

 앞에서는 html의 간단한 sheet를 소개 하였습니다.   html은  주로 골격을 나타나는 것이라, 디자인을 하는데는 css로 하여야 합니다.  아래 코드와 같이 css 관련 하여 매우 간단하게 코딩 하겠습니다.  body 부분의 css 코딩  ...