JINWOOJUNG

[ 핸즈온 머신러닝 ] 2. 머신러닝 프로젝트 처음부터 끝까지...2(Data 전처리) 본문

핸즈온머신러닝

[ 핸즈온 머신러닝 ] 2. 머신러닝 프로젝트 처음부터 끝까지...2(Data 전처리)

Jinu_01 2024. 8. 20. 22:41
728x90
반응형

본 포스팅은 Hands-On Machine Learning with Scikit-Learn, Keras & TensorFlow 2판을 토대로

공부한 내용을 정리하기 위한 포스팅입니다. 

해당 도서에 나오는 Source Code 및 자료는 GitHub를 참조하여 진행하였습니다.

https://github.com/ageron/handson-ml2

 

GitHub - ageron/handson-ml2: A series of Jupyter notebooks that walk you through the fundamentals of Machine Learning and Deep L

A series of Jupyter notebooks that walk you through the fundamentals of Machine Learning and Deep Learning in Python using Scikit-Learn, Keras and TensorFlow 2. - ageron/handson-ml2

github.com

https://jinwoo-jung.tistory.com/95

 

[ 핸즈온 머신러닝 ] 2. 머신러닝 프로젝트 처음부터 끝까지...2(Data 전처리 1)

본 포스팅은 Hands-On Machine Learning with Scikit-Learn, Keras & TensorFlow 2판을 토대로공부한 내용을 정리하기 위한 포스팅입니다. 해당 도서에 나오는 Source Code 및 자료는 GitHub를 참조하여 진행하였습니

jinwoo-jung.com


 

특성 스케일링(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의 전처리는 완료되었다.

728x90
반응형