일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Apple
- 미국주식
- 코스피
- 힐스테이트 광교산
- Python
- 해외주식
- 나스닥
- raspberry pi
- Espressif
- Bestin
- 파이썬
- 티스토리챌린지
- MQTT
- homebridge
- 홈네트워크
- 애플
- 매터
- SK텔레콤
- 월패드
- esp32
- matter
- 현대통신
- 배당
- ConnectedHomeIP
- 오블완
- RS-485
- 국내주식
- Home Assistant
- 공모주
- cluster
- Today
- Total
YOGYUI
R caret::preProcess - 수치형 데이터 정규화, 표준화 본문
caret 패키지의 preProcess 함수를 활용하면 수치형 데이터 정규화 (normalization) 및 표준화 (standardization)을 쉽게 수행할 수 있으며, 특정 데이터셋에 적용된 min, max, average 등 파라미터를 다른 데이터셋에 적용하는 것도 가능하다
(ex: 머신러닝 훈련용 데이터셋에 정규화 적용 후, 계산시 사용된 값을 테스트용 데이터셋에 그대로 적용)
iris 데이터를 두 세트로 나눈뒤 실습해보도록 한다
set.seed(210617)
library(caret)
df <- iris
idx <- caret::createDataPartition(df$Species, p = 0.6)
df_train <- df[idx$Resample1, ]
df_test <- df[-idx$Resample1, ]
df_train: 레코드 수 90, df_test: 레코드 수 60
table(df_train$Species)
>
setosa versicolor virginica
30 30 30
table(df_test$Species)
>
setosa versicolor virginica
20 20 20
1. 정규화 (Normalization)
수치형 데이터의 범위를 [0, 1]로 조정한다
\(x'={{x - x_{min}} \over {x_{max}-x_{min}}}\)
데이터 속성들의 범위가 천차만별일 경우 regression 모델의 예측 정확도를 향상시킬 수 있다
preProcess의 method = "range" 인자로 구현할 수 있다
norm <- caret::preProcess(df_train, method = 'range')
norm
> Created from 90 samples and 5 variables
Pre-processing:
- ignored (1)
- re-scaling to [0, 1] (4)
Species 속성은 'factor'형이므로 계산 시 제외되었음을 알 수 있다
norm$ranges
>
Sepal.Length Sepal.Width Petal.Length Petal.Width
[1,] 4.3 2.2 1.0 0.1
[2,] 7.7 4.4 6.9 2.5
preProcess 객체에서 계산에 사용된 min, max 값을 알 수 있다 (1행 = min값, 2행 = max값)
df_train의 summary를 통해 확인한 min, max값과 동일한 것을 알 수 있다
summary(df_train)
>
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.200 Min. :1.000 Min. :0.10 setosa :30
1st Qu.:5.200 1st Qu.:2.800 1st Qu.:1.525 1st Qu.:0.30 versicolor:30
Median :5.750 Median :3.000 Median :4.400 Median :1.35 virginica :30
Mean :5.847 Mean :3.061 Mean :3.740 Mean :1.22
3rd Qu.:6.375 3rd Qu.:3.375 3rd Qu.:5.100 3rd Qu.:1.80
Max. :7.700 Max. :4.400 Max. :6.900 Max. :2.50
preProcess 객체를 predict 함수를 사용해 데이터셋에 적용할 수 있다
df_train_norm <- predict(norm, df_train)
df_test_norm <- predict(norm, df_test)
summary(df_train_norm)
>
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.00000 setosa :30
1st Qu.:0.2647 1st Qu.:0.2727 1st Qu.:0.08898 1st Qu.:0.08333 versicolor:30
Median :0.4265 Median :0.3636 Median :0.57627 Median :0.52083 virginica :30
Mean :0.4549 Mean :0.3914 Mean :0.46441 Mean :0.46667
3rd Qu.:0.6103 3rd Qu.:0.5341 3rd Qu.:0.69492 3rd Qu.:0.70833
Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.00000
summary(df_test_norm)
>
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :0.02941 Min. :-0.09091 Min. :0.0339 Min. :0.00000 setosa :20
1st Qu.:0.23529 1st Qu.: 0.27273 1st Qu.:0.1017 1st Qu.:0.08333 versicolor:20
Median :0.44118 Median : 0.36364 Median :0.5508 Median :0.50000 virginica :20
Mean :0.45245 Mean : 0.38712 Mean :0.4720 Mean :0.44514
3rd Qu.:0.61765 3rd Qu.: 0.50000 3rd Qu.:0.7331 3rd Qu.:0.70833
Max. :1.05882 Max. : 0.77273 Max. :0.9153 Max. :1.00000
머신러닝 구현 시, 훈련용 데이터에 적용된 데이터 전처리 과정을 테스트 데이터에도 그대로 적용해야 올바른 결과를 얻을 수 있는데, caret::preProcess 객체와 predict 함수를 통해 손쉽게 구현할 수 있다
직접 함수로 구현하면 다음과 같다
func_norm <- function(x) {
(x - min(x)) / (max(x) - min(x))
}
df_train_norm2 <- sapply(df_train[, 1:4], func_norm)
summary(df_train_norm2)
>
Sepal.Length Sepal.Width Petal.Length Petal.Width
Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.00000
1st Qu.:0.2647 1st Qu.:0.2727 1st Qu.:0.08898 1st Qu.:0.08333
Median :0.4265 Median :0.3636 Median :0.57627 Median :0.52083
Mean :0.4549 Mean :0.3914 Mean :0.46441 Mean :0.46667
3rd Qu.:0.6103 3rd Qu.:0.5341 3rd Qu.:0.69492 3rd Qu.:0.70833
Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.00000
sum(df_train_norm[, 1:4] - df_train_norm2)
> [1] 0
두 결과물 간 값의 차이는 없는 것을 알 수 있다
단, 직접 함수로 구현하면 테스트 데이터에 적용 시 각 속성별 min, max값을 따로 저장해뒀다가 사용해야 하니 꽤 번거롭다
2. 표준화 (Standardization)
평균이 0, 표준편차가 1 (= 분산이 1)인 표준정규분포로 값을 변환
\(z={{x-\bar{x}}\over{\sigma_{x}}}\)
\(\bar{x}\)는 평균, \(\sigma_{x}\)는 표준편차를 말한다
preProcess의 method="center" 일 경우 데이터에서 평균을 빼주게 되며 (\(x-\bar{x}\)), method="scale"일 경우 데이터의 표준편차로 나누어 준다 (\(/{\sigma_{x}}\))
두 방법을 다음과 같이 하나로 묶어 표준화 객체를 생성할 수 있다
pstd <- caret::preProcess(df_train, method = c("center", "scale"))
pstd
> Created from 90 samples and 5 variables
Pre-processing:
- centered (4)
- ignored (1)
- scaled (4)
각 속성별 계산에 사용된 평균과 표준편차를 다음과 같이 확인할 수 있다
pstd$mean
>
Sepal.Length Sepal.Width Petal.Length Petal.Width
5.846667 3.061111 3.740000 1.220000
pstd$std
>
Sepal.Length Sepal.Width Petal.Length Petal.Width
0.8296744 0.4523831 1.7787636 0.7756404
데이터에 적용하는 방법을 predict로 동일하다
df_train_std <- predict(pstd, df_train)
df_test_std <- predict(pstd, df_test)
summary(df_train_std)
>
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :-1.8642 Min. :-1.9035 Min. :-1.5404 Min. :-1.4440 setosa :30
1st Qu.:-0.7794 1st Qu.:-0.5772 1st Qu.:-1.2452 1st Qu.:-1.1861 versicolor:30
Median :-0.1165 Median :-0.1351 Median : 0.3710 Median : 0.1676 virginica :30
Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
3rd Qu.: 0.6368 3rd Qu.: 0.6939 3rd Qu.: 0.7646 3rd Qu.: 0.7478
Max. : 2.2338 Max. : 2.9596 Max. : 1.7765 Max. : 1.6502
summary(df_test_std)
>
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :-1.74366 Min. :-2.34560 Min. :-1.4280 Min. :-1.44397 setosa :20
1st Qu.:-0.89995 1st Qu.:-0.57719 1st Qu.:-1.2031 1st Qu.:-1.18612 versicolor:20
Median :-0.05625 Median :-0.13509 Median : 0.2867 Median : 0.10314 virginica :20
Mean :-0.01004 Mean :-0.02088 Mean : 0.0253 Mean :-0.06661
3rd Qu.: 0.66693 3rd Qu.: 0.52807 3rd Qu.: 0.8911 3rd Qu.: 0.74777
Max. : 2.47487 Max. : 1.85438 Max. : 1.4954 Max. : 1.65025
직접 함수로 구현하면 다음과 같다
func_std <- function(x) {
(x - mean(x)) / (sd(x))
}
df_train_std2 <- sapply(df_train[, 1:4], func_std)
sum(df_train_std[, 1:4] - df_train_std2)
> [1] 0
두 결과물은 역시 동일하다
이 외에도 method 인자에 쓸 수 있는 다양한 옵션이 존재한다
"pca": 주성분분석(Principal Component Analysis)
"knnImpute": K-Nearest Neighbor 알고리즘 결측치 대체
"bagImpute": Bagged-Tree 알고리즘 결측치 대체
"medianImpute": 중앙값으로 결측치를 대체
"nzv": near zero variance 변수 제거 (caret::nearZeroVariance 참고)
데이터 전처리는 (일반적으로) 다음 과정으로 진행하면 제일 무난하다
NA 처리 - 표준화 - 아웃라이어 감지 및 처리 - 정규화
NA는 imputation(대체) 혹은 (수가 많지 않을 경우) 레코드 제거
아웃라이어 감지는 BoxPlot, IQR 등 시각화를 사용하거나, Z-score 판별, 스튜던트화 잔차 이용, Grubss 검정, Dixon 검정, Rosner 검정 등 다양한 방식이 있다 (따로 글을 작성해야 할듯)
caret 패키지만 제대로 쓸 줄 알면 데이터 전처리의 거의 전과정을 패키지 하나로 해결할 수 있다
[참고]
서민구, 『R을 이용한 데이터 처리 & 분석 실무』, 길벗(2014), p532-536.
https://lumiamitie.github.io/r/preProcess/
'Software > R' 카테고리의 다른 글
R caret::varImp - 변수중요도 측정 (0) | 2021.06.18 |
---|---|
R caret::confusionMatrix - 혼동행렬 작성 및 metric 추출 (2) | 2021.06.17 |
R 회귀분석 모델 성능판단 - RMSE, MAE, R squared (0) | 2021.06.16 |
R pROC 패키지::ROC 커브 그리기, AUC 메트릭 계산하기 (0) | 2021.06.15 |
R NA 처리하기 (with dplyr) (0) | 2021.06.13 |