일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- image processing
- 강화학습
- 머신러닝
- TD
- MySQL
- AlexNet
- 인공지능
- 백준
- 그래프 이론
- SIFT
- MinHeap
- DP
- dynamic programming
- dfs
- clustering
- 딥러닝
- Mask Processing
- sklearn
- Python
- edge detection
- IN
- opencv
- Reinforcement Learning
- classification
- canny edge detection
- machine learning
- C++
- 자료구조
- BFS
- exists
- Today
- Total
JINWOOJUNG
[ 핸즈온 머신러닝 ] 2. 머신러닝 프로젝트 처음부터 끝까지...2(Data 전처리) 본문
본 포스팅은 Hands-On Machine Learning with Scikit-Learn, Keras & TensorFlow 2판을 토대로
공부한 내용을 정리하기 위한 포스팅입니다.
해당 도서에 나오는 Source Code 및 자료는 GitHub를 참조하여 진행하였습니다.
https://github.com/ageron/handson-ml2
https://jinwoo-jung.tistory.com/95
특성 스케일링(Feature Scaling)
머신러닝 알고리즘은 숫자형 특성들의 스케일이 많이 다르면 잘 동작하지 않는다. 따라서 무든 특성의 범위를 일치시켜줘야 하는데, 크게 min-max Scaling과 표준화(Standardization)이 있다.
min-max Scaling(= Normalization)
min-max Scaling의 경우 단순히 각 데이터에서 해당 특성의 최솟값을 뺀 후 해당 특성의 최댓값과 최솟값의 차이로 나누면 된다. 따라서 모든 데이터를 0~1의 범위로 정규화 시킬 수 있으며, sklearn의 MinMaxScaler Transformer를 이용하면 된다. 만약 0~1의 범위가 아닌 다른 범위를 원한다면, feature_range 매개변수를 사용하면 된다.
표준화
표준화는 각 데이터에서 해당 특성의 평균을 뺀 후 해당 특성의 표준편차로 나눔으로써, 스케일링 된 결과 분포의 분산이 1이 되도록 하는 방법이다. 표준화방식은 상한과 하한이 없지만, 이상치(Outlier)에 min-max Scaling보다 덜 민감하다. 표준화의 경우 sklearn의 StandardScaler Transformer를 활용하면 된다.
이러한 Scaling은 모든 데이터가 아닌 Train Data에 대해서만 fit() Method를 통해 적용해야 한다. 이 이유는 변환 파이프라인을 공부하면서 다시 설명하겠다.
변환 파이프라인(Transformation Pipeline)
앞서 살펴본 여러가지 데이터 전처리 과정은 정확한 순서데로 처리되어야 한다. sklearn에서는 다양한 데이터 전처리(변환)을 순서데로 처리 해 주는 Pipeline Class가 존재한다.
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
print(st_TrainSetNum.head())
st_PipeLine = Pipeline([
('imputer', SimpleImputer(strategy="median")), # 사전에 String형 특성 제외 필
('attribs_adder', CombinedAttributesAdder()), # 방당 침실수 특성도 추가. 즉, 총 3개 특성 추가됨.
('std_scaler', StandardScaler()), # Scaling -> 표준화
])
st_TrainSetNumTmp = st_PipeLine.fit_transform(st_TrainSetNum)
print("특성 수 : ", st_TrainSetNumTmp.shape[1])
SimpleImputer를 통해 Null Value를 중간값으로 채운다. 이를 위해, fit_transform()을 적용하는 DataFrame에는 숫자형 특성만 존재해야 한다. 또한, 앞서 구현한 CombinedAttributesAdder Class를 통해 가정 당 방 개수, 가정 당 인구 수, 방 당 침실 수 특성도 추가 해 준다. 그리고 숫자형 특성의 데이터들의 Scale를 StandardScaler()를 통해 표준화를 시킨다.
원래 st_TrainSetNum의 Dataframe은 8개의 특성을 가지고 있지만, Pipeline으로 데이터 전처리를 순차적으로 진행한 결과 3개의 특성이 추가적으로 생성되어 총 11개의 특성이 존재함을 확인할 수 있다.
전처리 된 데이터는 표준화 되었기 때문에, 각 특성의 값들이 변화된 것을 확인할 수 있으며, Pandas Dataframe이 아닌 Numpy Array 형태이다.
숫자형 특성과 범주형 특성을 따로 전처리 진행하였지만, 한번에 할 수 있으면 매우 편리하다. sklearn의 ColumnTransformer Class는 Pandas Dataframe과 연동되어 전처리를 손쉽게 진행할 수 있다.
from sklearn.compose import ColumnTransformer
st_TrainSet = st_TrainSetTmp.copy()
st_PipeLine = Pipeline([
('imputer', SimpleImputer(strategy="median")), # 사전에 String형 특성 제외 필
('attribs_adder', CombinedAttributesAdder()), # 방당 침실수 특성도 추가. 즉, 총 3개 특성 추가됨.
('std_scaler', StandardScaler()), # Scaling -> 표준화
])
num_attribs = list(st_TrainSetNum)
cat_attribs = ["ocean_proximity"]
full_pipeline = ColumnTransformer([
("num", st_PipeLine, num_attribs),
("cat", OneHotEncoder(), cat_attribs),
])
st_FinalTrainDataset = full_pipeline.fit_transform(st_TrainSet)
print(st_FinalTrainDataset)
ColumnTransformer Class의 생성자는 튜플 리스트를 인자로 받는데, 각 튜플은 이름, 변환기, 변환기가 적용될 열 이름의 리스트로 이루어진다.
숫자형 특성의 경우, 앞서 정의한 st_PipeLine을 사용해 변환되고, 범주형의 경우 OneHotEncoder를 사용해서 변환된다. 각 특성의 데이터 타입에 맞게 fit_transform()을 통해 전처리를 시켜주면 된다.
전처리된 결과인 st_FinalTrainDataset의 Numpy Array의 Shape는 16512 , 16로 16512개의 구역 샘플이 존재하고, 각 샘플은 16개의 전처리된 특성이 존재하는데, 기존의 수치형 특성 8개, 추가된 특성 3개, 범주형 특성의 One-Hot Encoding 결과 5개이다.
이로써 학습에 적용시킬 Train Set의 전처리는 완료되었다.
'핸즈온머신러닝' 카테고리의 다른 글
[ 핸즈온 머신러닝 ] 3. 분류...1(Binary Classifier) (14) | 2024.08.29 |
---|---|
[ 핸즈온 머신러닝 ] 2. 머신러닝 프로젝트 처음부터 끝까지...3(Model 선정) (2) | 2024.08.27 |
[ 핸즈온 머신러닝 ] 2. 머신러닝 프로젝트 처음부터 끝까지...2(Data 전처리 1) (0) | 2024.08.20 |
[ 핸즈온 머신러닝 ] 2. 머신러닝 프로젝트 처음부터 끝까지...1(데이터 분석) (0) | 2024.08.18 |
[ 핸즈온 머신러닝 ] 1-1. 한눈에 보는 머신러닝 (0) | 2024.08.17 |