데이터 표준화 및 정규화는 머신러닝에 있어서, 매우 중요한 사항이다. 서로 데이터의 크기가 맞지 않을 경우 정확 한 계산을 할 수 없다. 아래는 유방암 데이터 세트이다. 이 데이터는 머신러닝으로 모델 만들기 전에 반드시, 표준화 및 정규화 작업을 해야 하다.
데이터 스케일 |
위의 그림을 보면 데이터의 크기 차이가 많이 난다. 이럴 경우에는 전부 스케일 하여, 훈련셋과 테스트 셋을 만들어야 한다.
유방암 데이터 셋
유방암 데이터 셋은 아래와 같이 기술 되어 있다. 이것은 파이썬의 사이킨런에 올라와 있는 내용인데, 이번에는 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")
아래는 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이 나왔다. 꽤 좋은 성능이다. 다른 모델로 돌리면 더 높게 나올 수 있다. 지금은 데이터 표준화 및 데이터 정규화에 대한 방법을 이야기한것에 대한 예제 이므로 넘어 가겠다.
댓글 없음:
댓글 쓰기