R 기초 데이터 표준화 (Standardization) 및 데이터 정규화(Normalization) 방법, 유방암 데이터 셋 머신러닝

  데이터 표준화 및 정규화는  머신러닝에 있어서,  매우 중요한 사항이다.   서로 데이터의 크기가 맞지 않을 경우 정확 한 계산을 할 수 없다.    아래는 유방암 데이터 세트이다.  이 데이터는 머신러닝으로 모델 만들기 전에 반드시,  표준화 및 정규화 작업을 해야 하다. 


데이터 스케일



위의 그림을 보면  데이터의 크기 차이가 많이 난다.  이럴 경우에는 전부 스케일 하여,  훈련셋과 테스트 셋을 만들어야 한다. 

유방암 데이터 셋

유방암 데이터 셋은 아래와 같이 기술 되어 있다.  이것은 파이썬의 사이킨런에 올라와 있는 내용인데,  이번에는 R 에서 데이터를 가져올 것이다.     


**Data Set Characteristics:**

    :Number of Instances: 569

    :Number of Attributes: 30 numeric, predictive attributes and the class

    :Attribute Information:
        - radius (mean of distances from center to points on the perimeter) 반경
        - texture (standard deviation of gray-scale values) 질감
        - perimeter 둘레
        - area  면적
        - smoothness (local variation in radius lengths) 매끄러움
        - compactness (perimeter^2 / area - 1.0) 조그만 정도
        - concavity (severity of concave portions of the contour) 오목함
        - concave points (number of concave portions of the contour) 오목함 점의수
        - symmetry  대칭
        - fractal dimension ("coastline approximation" - 1) 프렉탈 차원

   30개의 독립변수(Predictive attributes)가 있고 주로 판단하는 정보는 위와 같다.   즉 여러가지 요소를 가지고 악성 종양 인지 정상 종양인지 분류 하는 것이다. 

  • 데이터 관측치 : 569
  • Predictive attributes(독립변수) : 30
  • target(반응변수) :  1.0으로 분류  


데이터 셋 준비 


# 라이브러리 로딩  
  library(dplyr)
  library(ggplot2)
  library(corrplot) 
  library(tidyr)
  library(rio)
  library(caret)
  options(scipen = 3)
  
  library(readxl)
  library(httr)
# 데이터 셋 가져오기 
url ="https://docs.google.com/uc?export=download&id=18OTXWHj8t9de9wSRmTg5423nX8e6DIzJ"
GET(url, write_disk(tf <- tempfile(fileext = ".xlsx")))
wdbc <- read_excel(tf, 1L)  # 1L은 sheet 


# 유방암 데이터 셋 그래프 그리기   
  wdbc %>% 
    select(-id, -diagnosis ) %>% 
    gather(value = "observ") %>% 
    rename(항목 = key) %>% 
    group_by(항목) %>% 
  ggplot(aes(x = 항목, y = observ, fill = 항목)) +
    geom_boxplot() +
    theme( axis.text.x = element_text(angle = 90),
           legend.position = "none")  


그림은 앞에서 그려서,  앞에 그림으로 대치 하고,   데이터 표준화 및 정규화 하기 위한 기본 준비 작업을 하겠다.  R에서 데이터 전처리 할때는 일괄로 함수를 처리를 할 수 있는 방법이 있다. 

   mutate_at(변수명, 함수)  → 즉 함수 하나가 정의 되면 일괄로 변환 할 수 있다.  

# 악성인지 음성인지 분류하는 target value factor  
 wdbc$diagnosis <- as.factor(wdbc$diagnosis) 

데이터 표준화 및 데이터 정규화 하기 위하여 Feature  셋(독립변수) 정리 한다. 30개의 데이터셋을 정리 하였다. 
# scale 할 데이터 정리  
 scale_set <- c("radius_mean",
                "texture_mean",
                "perimeter_mean",
                "area_mean",
                "smoothness_mean",
                "compactness_mean",
                "concavity_mean",
                "concave.points_mean",
                "symmetry_mean",
                "fractal_dimension_mean",
                "radius_se",
                "perimeter_se",
                "area_se",
                "smoothness_se",
                "compactness_se",
                "concavity_se",
                "concave.points_se",
                "symmetry_se",
                "fractal_dimension_se",
                "radius_worst",
                "texture_worst",
                "perimeter_worst",
                "area_worst",
                "smoothness_worst",
                "compactness_worst",
                "concavity_worst",
                "concave.points_worst",
                "symmetry_worst",
                "fractal_dimension_worst")

데이터 표준화(Standardization) 및 데이터 정규화(Normalization)

 

데이터 표준화


  데이터 표준화는 정규 분포 상의 Z 점수로 계산 한다.   공식은 아래와 같다. 
 
$$ Z = {  x - μ  \over  σ } $$

  관측치에서 평균값을 뺀 다음 시그마 값을 나는 것인데,  위와 같은 공식으로 계산 하면, 
정규분포의 범위 만큼 (음수 ~ 양수 ) 데이터 Scale 이 된다.    위와 같이 독립 변수 정리 한것을  mutate에 가져와서  표준화 한다. 

# mutate_at을 사용하여, 선택된 데이터 셋 scale   
 wdbc_scale <-   wdbc %>% 
      mutate_at(scale_set,
                   scale)

데이터를 요약 하면, 아래와 같이 정규분포의 평균값과 분산 범위 만큼 데이터가 펼처져 있다. 

# 데이터 비교   
  summary(wdbc_scale)
##        id            diagnosis   radius_mean.V1      texture_mean.V1  
##  Min.   :     8670   B:357     Min.   :-2.027864   Min.   :-2.227289  
##  1st Qu.:   869218   M:212     1st Qu.:-0.688779   1st Qu.:-0.725325  
##  Median :   906024             Median :-0.214893   Median :-0.104544  
##  Mean   : 30371831             Mean   : 0.000000   Mean   : 0.000000  
##  3rd Qu.:  8813129             3rd Qu.: 0.468980   3rd Qu.: 0.583662  
##  Max.   :911320502             Max.   : 3.967796   Max.   : 4.647799  
##   perimeter_mean.V1     area_mean.V1     smoothness_mean.V1 
##  Min.   :-1.982759   Min.   :-1.453164   Min.   :-3.109349  
##  1st Qu.:-0.691347   1st Qu.:-0.666609   1st Qu.:-0.710338  
##  Median :-0.235773   Median :-0.294927   Median :-0.034860  
##  Mean   : 0.000000   Mean   : 0.000000   Mean   : 0.000000  
##  3rd Qu.: 0.499238   3rd Qu.: 0.363188   3rd Qu.: 0.635640  
##  Max.   : 3.972634   Max.   : 5.245913   Max.   : 4.766717  
##  compactness_mean.V1  concavity_mean.V1  concave.points_mean.V1
##  Min.   :-1.608721   Min.   :-1.113893   Min.   :-1.260710     
##  1st Qu.:-0.746429   1st Qu.:-0.743094   1st Qu.:-0.737295     
##  Median :-0.221745   Median :-0.341939   Median :-0.397372     
##  Mean   : 0.000000   Mean   : 0.000000   Mean   : 0.000000     
##  3rd Qu.: 0.493423   3rd Qu.: 0.525599   3rd Qu.: 0.646366     
##  Max.   : 4.564409   Max.   : 4.239858   Max.   : 3.924477     
##   symmetry_mean.V1   fractal_dimension_mean.V1    radius_se.V1    
##  Min.   :-2.741705   Min.   :-1.818265         Min.   :-1.058992  
##  1st Qu.:-0.702621   1st Qu.:-0.722004         1st Qu.:-0.623022  
##  Median :-0.071564   Median :-0.178123         Median :-0.291988  
##  Mean   : 0.000000   Mean   : 0.000000         Mean   : 0.000000  
##  3rd Qu.: 0.530313   3rd Qu.: 0.470569         3rd Qu.: 0.265866  
##  Max.   : 4.480808   Max.   : 4.906602         Max.   : 8.899079  
##    texture_se       perimeter_se.V1       area_se.V1       smoothness_se.V1  
##  Min.   :0.3602   Min.   :-1.043131   Min.   :-0.737180   Min.   :-1.774504  
##  1st Qu.:0.8339   1st Qu.:-0.623220   1st Qu.:-0.494319   1st Qu.:-0.623470  
##  Median :1.1080   Median :-0.286400   Median :-0.347477   Median :-0.220142  
##  Mean   :1.2169   Mean   : 0.000000   Mean   : 0.000000   Mean   : 0.000000  
##  3rd Qu.:1.4740   3rd Qu.: 0.242817   3rd Qu.: 0.106679   3rd Qu.: 0.368031  
##  Max.   :4.8850   Max.   : 9.453668   Max.   :11.032135   Max.   : 8.022940  
##   compactness_se.V1    concavity_se.V1   concave.points_se.V1
##  Min.   :-1.296957   Min.   :-1.056571   Min.   :-1.911765   
##  1st Qu.:-0.692317   1st Qu.:-0.556671   1st Qu.:-0.673897   
##  Median :-0.280773   Median :-0.198890   Median :-0.140372   
##  Mean   : 0.000000   Mean   : 0.000000   Mean   : 0.000000   
##  3rd Qu.: 0.389312   3rd Qu.: 0.336456   3rd Qu.: 0.472241   
##  Max.   : 6.138081   Max.   :12.062067   Max.   : 6.643755   
##    symmetry_se.V1    fractal_dimension_se.V1   radius_worst.V1  
##  Min.   :-1.531542   Min.   :-1.096004       Min.   :-1.725382  
##  1st Qu.:-0.651108   1st Qu.:-0.584604       1st Qu.:-0.674328  
##  Median :-0.219238   Median :-0.229738       Median :-0.268803  
##  Mean   : 0.000000   Mean   : 0.000000       Mean   : 0.000000  
##  3rd Qu.: 0.355380   3rd Qu.: 0.288388       3rd Qu.: 0.521557  
##  Max.   : 7.065700   Max.   : 9.842932       Max.   : 4.090590  
##   texture_worst.V1   perimeter_worst.V1     area_worst.V1   
##  Min.   :-2.222039   Min.   :-1.691872   Min.   :-1.221348  
##  1st Qu.:-0.747971   1st Qu.:-0.688972   1st Qu.:-0.641571  
##  Median :-0.043477   Median :-0.285729   Median :-0.340881  
##  Mean   : 0.000000   Mean   : 0.000000   Mean   : 0.000000  
##  3rd Qu.: 0.657762   3rd Qu.: 0.539804   3rd Qu.: 0.357275  
##  Max.   : 3.882489   Max.   : 4.283568   Max.   : 5.924959  
##  smoothness_worst.V1 compactness_worst.V1 concavity_worst.V1 
##  Min.   :-2.680337   Min.   :-1.442609    Min.   :-1.304683  
##  1st Qu.:-0.690623   1st Qu.:-0.680485    1st Qu.:-0.755849  
##  Median :-0.046802   Median :-0.269264    Median :-0.218040  
##  Mean   : 0.000000   Mean   : 0.000000    Mean   : 0.000000  
##  3rd Qu.: 0.597020   3rd Qu.: 0.539194    3rd Qu.: 0.530674  
##  Max.   : 3.951897   Max.   : 5.108382    Max.   : 4.696536  
##  concave.points_worst.V1  symmetry_worst.V1  fractal_dimension_worst.V1
##  Min.   :-1.7435287      Min.   :-2.159060   Min.   :-1.600431         
##  1st Qu.:-0.7557349      1st Qu.:-0.641299   1st Qu.:-0.691303         
##  Median :-0.2232725      Median :-0.127297   Median :-0.216254         
##  Mean   : 0.0000000      Mean   : 0.000000   Mean   : 0.000000         
##  3rd Qu.: 0.7118836      3rd Qu.: 0.449742   3rd Qu.: 0.450366         
##  Max.   : 2.6835158      Max.   : 6.040726   Max.   : 6.840837


데이터 정규화

  데이터 정규화는 0 ~ 1까지의 데이터 셋을 만드는 것이다. 결론적으로 이야기해서 어떠한 모델을 돌렸을때,  결과 값은 차이가 없다.   공식은 아래와 같다. 

$$ Normal = { (x - min(x))  \over  (max(x) - min(x) } $$

  R에서는 데이터 정규화 할 수 있는 함수가 없으므로, 위의 공식을 이용하여 사용자 함수를 만들어야 한다.  
# min/max scale 
 normal_fun <- function(x){
   normal <- (x-min(x))/(max(x)-min(x))
   return(normal) }

정규화 함수를 만든 다음 muatat_at 함수를 이용해서 일괄로 계산 한다. 
#  mutate_at을 사용하여, 선택된 데이터 셋 정규화
  wdbc_normal <-   wdbc %>% 
    mutate_at(scale_set,
             normal_fun)

데이터를 요약 하면,  아래와 같이 0 ~ 1까지의 데이터 셋이 정리되어 있다. 
  summary(wdbc_normal)
##        id            diagnosis  radius_mean      texture_mean   
##  Min.   :     8670   B:357     Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:   869218   M:212     1st Qu.:0.2233   1st Qu.:0.2185  
##  Median :   906024             Median :0.3024   Median :0.3088  
##  Mean   : 30371831             Mean   :0.3382   Mean   :0.3240  
##  3rd Qu.:  8813129             3rd Qu.:0.4164   3rd Qu.:0.4089  
##  Max.   :911320502             Max.   :1.0000   Max.   :1.0000  
##  perimeter_mean     area_mean      smoothness_mean  compactness_mean
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:0.2168   1st Qu.:0.1174   1st Qu.:0.3046   1st Qu.:0.1397  
##  Median :0.2933   Median :0.1729   Median :0.3904   Median :0.2247  
##  Mean   :0.3329   Mean   :0.2169   Mean   :0.3948   Mean   :0.2606  
##  3rd Qu.:0.4168   3rd Qu.:0.2711   3rd Qu.:0.4755   3rd Qu.:0.3405  
##  Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.0000  
##  concavity_mean    concave.points_mean symmetry_mean    fractal_dimension_mean
##  Min.   :0.00000   Min.   :0.0000      Min.   :0.0000   Min.   :0.0000        
##  1st Qu.:0.06926   1st Qu.:0.1009      1st Qu.:0.2823   1st Qu.:0.1630        
##  Median :0.14419   Median :0.1665      Median :0.3697   Median :0.2439        
##  Mean   :0.20806   Mean   :0.2431      Mean   :0.3796   Mean   :0.2704        
##  3rd Qu.:0.30623   3rd Qu.:0.3678      3rd Qu.:0.4530   3rd Qu.:0.3404        
##  Max.   :1.00000   Max.   :1.0000      Max.   :1.0000   Max.   :1.0000        
##    radius_se         texture_se      perimeter_se        area_se       
##  Min.   :0.00000   Min.   :0.3602   Min.   :0.00000   Min.   :0.00000  
##  1st Qu.:0.04378   1st Qu.:0.8339   1st Qu.:0.04000   1st Qu.:0.02064  
##  Median :0.07702   Median :1.1080   Median :0.07209   Median :0.03311  
##  Mean   :0.10635   Mean   :1.2169   Mean   :0.09938   Mean   :0.06264  
##  3rd Qu.:0.13304   3rd Qu.:1.4740   3rd Qu.:0.12251   3rd Qu.:0.07170  
##  Max.   :1.00000   Max.   :4.8850   Max.   :1.00000   Max.   :1.00000  
##  smoothness_se    compactness_se     concavity_se     concave.points_se
##  Min.   :0.0000   Min.   :0.00000   Min.   :0.00000   Min.   :0.0000   
##  1st Qu.:0.1175   1st Qu.:0.08132   1st Qu.:0.03811   1st Qu.:0.1447   
##  Median :0.1586   Median :0.13667   Median :0.06538   Median :0.2070   
##  Mean   :0.1811   Mean   :0.17444   Mean   :0.08054   Mean   :0.2235   
##  3rd Qu.:0.2187   3rd Qu.:0.22680   3rd Qu.:0.10619   3rd Qu.:0.2787   
##  Max.   :1.0000   Max.   :1.00000   Max.   :1.00000   Max.   :1.0000   
##   symmetry_se     fractal_dimension_se  radius_worst    texture_worst   
##  Min.   :0.0000   Min.   :0.00000      Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:0.1024   1st Qu.:0.04675      1st Qu.:0.1807   1st Qu.:0.2415  
##  Median :0.1526   Median :0.07919      Median :0.2504   Median :0.3569  
##  Mean   :0.1781   Mean   :0.10019      Mean   :0.2967   Mean   :0.3640  
##  3rd Qu.:0.2195   3rd Qu.:0.12656      3rd Qu.:0.3863   3rd Qu.:0.4717  
##  Max.   :1.0000   Max.   :1.00000      Max.   :1.0000   Max.   :1.0000  
##  perimeter_worst    area_worst      smoothness_worst compactness_worst
##  Min.   :0.0000   Min.   :0.00000   Min.   :0.0000   Min.   :0.0000   
##  1st Qu.:0.1678   1st Qu.:0.08113   1st Qu.:0.3000   1st Qu.:0.1163   
##  Median :0.2353   Median :0.12321   Median :0.3971   Median :0.1791   
##  Mean   :0.2831   Mean   :0.17091   Mean   :0.4041   Mean   :0.2202   
##  3rd Qu.:0.3735   3rd Qu.:0.22090   3rd Qu.:0.4942   3rd Qu.:0.3025   
##  Max.   :1.0000   Max.   :1.00000   Max.   :1.0000   Max.   :1.0000   
##  concavity_worst   concave.points_worst symmetry_worst  
##  Min.   :0.00000   Min.   :0.0000       Min.   :0.0000  
##  1st Qu.:0.09145   1st Qu.:0.2231       1st Qu.:0.1851  
##  Median :0.18107   Median :0.3434       Median :0.2478  
##  Mean   :0.21740   Mean   :0.3938       Mean   :0.2633  
##  3rd Qu.:0.30583   3rd Qu.:0.5546       3rd Qu.:0.3182  
##  Max.   :1.00000   Max.   :1.0000       Max.   :1.0000  
##  fractal_dimension_worst
##  Min.   :0.0000         
##  1st Qu.:0.1077         
##  Median :0.1640         
##  Mean   :0.1896         
##  3rd Qu.:0.2429         
##  Max.   :1.0000


데이터를 정규화 하였으니,  데이터셋을 나눈 다음 로지스틱 회귀로 돌릴 예정이다.   머신러닝 패키지 중에서 가장 좋은 패키지는 caret 패키지 이다. 

  

머신러닝 테스트 (로지스틱 회귀)

   유방암 데이터 셋은 결측치가 없으므로,  이 부분은 지나간다.  하지만, 있을 경우에는 결측치를 대치 하거나,  결측치 있는 데이터 셋은 삭제를 해야 한다. 

  
  데이터를 실행 할때,  scale 된 데이터 셋으로 실행 하겠다.  다음 편에 다 정리된 데이터 셋가지고,  표준화와 정규화 부분을 상호 비교할 예정 입니다. 

   데이터 분산과 상관관계를 분석 할 것이다.   이것을 처리 할 때 아래와 같은 원칙이 있다. 

  • 데이터 분산 :  데이터 분산이 적은것은 머신러닝의 의미가 없다.   모든 숫자가 1인경우
  • 상관관계 :  가끔 가다 계산에 의한 변수가 나타나는 것이 있다.  이것은 상관관계가 높다 따라서 삭제 한다. 
아래는 위의 규칙에 따라서 삭제 하는 코드 이다. 
# scale 된 데이터 셋으로 실행
# 분산이 없는 데이터는 머신 러닝 하는데 필요가 없어 정리 해야 한다. 
  cor_wdbc <- wdbc_scale %>% select(-id, -diagnosis)
    
# 분산이 0인것 삭제
  except <- c(nearZeroVar(cor_wdbc))
  cor_wdbc <- cor_wdbc[-c(except,1)]

# 상관관계 분석
  correlations <- cor(cor_wdbc)
  
# 상관관계 구조를 시각적으로 확인한다.  
  corrplot(correlations, order ="hclust")


히트맵 상관관계 분석


# 상관관계가 높은 것은 데이터를 걸러낸다. 
  highCorr <- findCorrelation(correlations, cutoff = .75) 
  cor_wdbc <- cor_wdbc[, -highCorr]    

 위의 상관관계 그래프 시각화가 끝나면,  Boxplot으로 데이터를 그린 다음  outlier 가 있는 지 확인해 보고,  전처리 작업을 실행 해야 한다. 

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

boxplot


 아래는 target 변수를  정의 하는 것이다.   target 변수를 묶은 다음에,  다시 변수 이름을 정해 주는 코드이다. 

  wdbc_df <- cbind(cor_wdbc, wdbc_scale$diagnosis)  
  colnames(wdbc_df)[13] <- "diagnosis"

데이터 셋 나누기이다.   데이터셋은 일반적으로 train set과 test 셋 8:2로 나눈다. 

# 데이터 셋 나누기 
  # 데이터 셋 나누기 8:2
  set.seed(1004)
  inx   <- createDataPartition(wdbc_scale$diagnosis, p = 0.8, list = F)
  train <- wdbc_df[ inx, ]
  test  <- wdbc_df[-inx, ]
 
  데이터셋이 많으면, cross validation(교차 검증)을 실행 하지 않으나,  이것은  train set이 456개라  데이터가 적어 교차 검증을 실행 하여야 한다.  데이터 갯수가 1만개 이상이면 굳이 하지 않아도 된다. 

# 데이터 셋 나누기 
  # 데이터 셋 나누기 8:2
  set.seed(1004)
  inx   <- createDataPartition(wdbc_scale$diagnosis, p = 0.8, list = F)
  train <- wdbc_df[ inx, ]
  test  <- wdbc_df[-inx, ]

  boxplot 그렸을때,  outlier 가 발생 하여, 이것을 조정 하고,  정규 분포 형태로 맞추어야 모델의 성능이 잘 나온다. 


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

  아래는 Feature 셋을 x로 하고 target 셋은 y로 해서 로지스틱 회귀로 머신러닝을 실행 한것이다.  이진 분류 할때는 로지스틱 회귀가 좋으므로 로지스틱 회귀로 돌리는 것이 좋다. 


# logistic regression
  system.time(
    logis <- train( x = train[, -13],
                    y = train[, "diagnosis"],
                    method     = "glm",
                    metric     = "Accuracy",
                    trControl  = control,
                    preProcess = preProc) )

##    user  system elapsed 
##   0.860   0.001   0.860

데이터 양이 적어 연산하는데,  1초가 걸리지 않았다.   하지만 PC의 사양 마다 속도가 
조금씩 다를 수 있다. 

아래와 같이 결과를 확인 해보자.

 결과 확인 하기 
  logis
## Generalized Linear Model 
## 
## 456 samples
##  12 predictor
##   2 classes: 'B', 'M' 
## 
## Pre-processing: Box-Cox transformation (1), centered (1), ignore (11) 
## Resampling: Cross-Validated (10 fold, repeated 5 times) 
## Summary of sample sizes: 411, 410, 410, 411, 410, 411, ... 
## Resampling results:
## 
##   Accuracy   Kappa    
##   0.9635845  0.9221054

Accuracy 가 0.96이 나왔다.   꽤 좋은 성능이다.  다른 모델로 돌리면 더 높게 나올 수 있다.  지금은  데이터 표준화 및 데이터 정규화에 대한 방법을 이야기한것에 대한 예제 이므로 넘어 가겠다. 
 














댓글 없음:

댓글 쓰기

[주식 클로드 자동매매 프로젝트] 제2편. 데이터 인프라 구축 — 모델보다 데이터가 먼저다

 머신러닝 모델을 이야기하기 전에, 그 모델이 먹는 데이터가 어디서 어떻게 왔는지부터 정직하게 밝혀야 한다. 이 프로젝트에서 가장 많은 시간이 들어간 부분은 화려한 모델 튜닝이 아니라, "내가 정말 그 데이터를 갖고 있는가"를 확인하...