-
데이터 전처리 Data Preprocessing
-
어떤 데이터를 입력으로 가지느냐에 따라 결과가 크게 달라짐 (Garbage In, Garbage Out)
사이킷런 ML 알고리즘을 적용하기 전 처리할 기본 사항
-
결손값, NaN, Null 허용 안됨
-
문자열값 허용 안됨
결손값, NaN, Null 처리
-
결손값등이 얼마 되지 않는 다면 피처의 평균값 등으로 간단히 처리
-
결손값등이 대분이라면 해당 피처 Drop
-
결손값등이 일정 수준 이상되는 경우 일정 수준의 기준이 없어 선택이 어려움
-
중요도가 높은 피처이고 단순히 평균값등로 대체할 경우 예측 왜곡이 심할 수 있다면 상세히 검토해 더 정밀한 대체 값을 선정 해야 함
문자열값 처리
-
모든 문자열은 인코딩돼서 숫자로 변환
-
문자열 피처는 카테고리형 피처와 텍스트 피처를 의미
-
카테고리형 피처는 코드 값으로 표현
-
텍스트형 피처는 피처 벡터화(feature vectorization)등의 기법으로 벡터화
-
불필요한 피터 예를 들어 ID나 주민번호 같은 행 실별 피처 같은 경우 삭제 처리
데이터 인코딩
-
레이블 인코딩(Label encoding)
-
원-핫 이코딩(One Hot encoding)
레이블 인코딩
-
카테고리 피처를 코드형 숫자 값으로 변환 하는 것
-
상품데이터의 상품구분이 휴대폰, TV, 컴퓨터 값이면 휴대폰:1, TV:2, 컴퓨터:3
-
사이킷런의 LabelEncoder 클래스로 구현
import numpy as np from sklearn.preprocessing import LabelEncoder
items = ['휴대폰', 'TV', '컴퓨터']
encoder = LabelEncoder()
encoder.fit(items) labels = encoder.transform(items) print(labels)
[2 0 1]
# classes_ 0번부터 순서대로 변환된 인코딩 원본값 print('encoding class', encoder.classes_)
encoding class ['TV' '컴퓨터' '휴대폰']
print('decoding values', encoder.inverse_transform([0, 1, 2]))
decoding values ['TV' '컴퓨터' '휴대폰']
레이블 인코딩 주의 사항
-
몇몇 ML 알고리즘에는 숫자 값의 크고 작음에 대한 특성이 작용 해 예층 성능이 떨어짐
-
회귀와 같은 ML 알고리즘에서는 휴대폰:1, TV:2, 컴퓨터:3 숫자 값에 따른 순서나 중요도로 인식 됨
-
트리 계열의 ML 알고리즘은 숫자의 이러한 특성을 반영하지 않음
-
이러한 문제점을 해결하기 위한 인코딩 방식이 원-핫 인코딩
원-핫 인코딩(One-Hot Encoding)
-
피처 값의 유형에 따라 새로운 피처를 추가해 고유 값에 해당하는 칼럼에만 1을 표시
-
원본데이터 => 원-핫 인코딩으로 변환
-
단점 : 무수한 0의 난발
사이킷런의 LabelEncoder 클래스로 구현
from sklearn.preprocessing import OneHotEncoder
items
['휴대폰', 'TV', '컴퓨터']
# 숫자로 변환 encoder = LabelEncoder() encoder.fit(items) labels = encoder.transform(items) print(labels)
[2 0 1]
# 2차원 데이터로 변환 # reshape(-1,n), reshape(n,-1)의 의미 https://rfriend.tistory.com/345 labels = labels.reshape(-1, 1) # shape(3, 1) labels
array([[2], [0], [1]], dtype=int64)
# 원-핫 인코딩 적용 oh_encoder = OneHotEncoder() oh_encoder.fit(labels) oh_labels = oh_encoder.transform(labels) oh_labels.toarray()
array([[0., 0., 1.], [1., 0., 0.], [0., 1., 0.]])
# 판다스로 원-핫 인코딩 적용 import pandas as pd df = pd.DataFrame(items) pd.get_dummies(df)
0_TV 0_컴퓨터 0_휴대폰 0 0 0 1 1 1 0 0 2 0 1 0 피처 스케일링(feature scaling) 과 정규화
-
피처 스케일링 : 서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업
-
대표적 방법 : 표준화(Standardization)와 정규화(Normalization)
-
사이킷런의 StandardScaler, MinMaxCaler 모듈
표준화
-
피처 각각이 평균이 0이고 분산이 1인 가우시안 정규 본포를 가진 값으로 변환
정규화
-
서로 다른 피처의 크기를 통일하기 위해 크기를 변환해 주는 개념
-
피처 A(거리) : 0~ 100KM, 피처 B(금액) : 0 ~ 100,000,000 => 최소 0 ~ 최대 1 값으로 변환
백터 정규화(선형대수 개념의 정규화)
-
사이킷런의 Nomalizer 모듈
-
세개의 피처 x, y, z가 있다면 x_new/(|x,y,z|)
StandardScaler
-
표준화 지원 클래스
-
사이킷런의 서포트 백터 머신(SVM), 선형회귀(Linear Regression), 로지스틱 회귀(Logistic Regression)는 가우시안 분포라고 가정하고 구현된 알고리즘
from sklearn.datasets import load_iris import pandas as pd
# 붗꽃 데이터 세트 로딩 iris = load_iris() # iris
iris_data = iris.data #iris_data
iris.feature_names
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names) iris_df.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) 0 5.1 3.5 1.4 0.2 1 4.9 3.0 1.4 0.2 2 4.7 3.2 1.3 0.2 3 4.6 3.1 1.5 0.2 4 5.0 3.6 1.4 0.2 # StandardScaler 표준화 from sklearn.preprocessing import StandardScaler scaler = StandardScaler() scaler.fit(iris_df) iris_scaled = scaler.transform(iris_df) # numpy.ndarray로 저장됨
# Numpy => DataFrame iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names) iris_df_scaled.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) 0 -0.900681 1.019004 -1.340227 -1.315444 1 -1.143017 -0.131979 -1.340227 -1.315444 2 -1.385353 0.328414 -1.397064 -1.315444 3 -1.506521 0.098217 -1.283389 -1.315444 4 -1.021849 1.249201 -1.340227 -1.315444 iris_df_scaled.mean()
sepal length (cm) -1.690315e-15 sepal width (cm) -1.842970e-15 petal length (cm) -1.698641e-15 petal width (cm) -1.409243e-15 dtype: float64
iris_df_scaled.var()
sepal length (cm) 1.006711 sepal width (cm) 1.006711 petal length (cm) 1.006711 petal width (cm) 1.006711 dtype: float64
MimMaxScaler
-
0 ~ 1 사이의 값으로 변환
-
음수 값이 있으면 -1 ~ 1 사이의 값으로 변환
# MinMaxScaler 정규화 from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() scaler.fit(iris_df) iris_scaled = scaler.transform(iris_df)
# numpy => DataFrame iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names) iris_df_scaled.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) 0 0.222222 0.625000 0.067797 0.041667 1 0.166667 0.416667 0.067797 0.041667 2 0.111111 0.500000 0.050847 0.041667 3 0.083333 0.458333 0.084746 0.041667 4 0.194444 0.666667 0.067797 0.041667 iris_df_scaled.min(), iris_df_scaled.max()
(sepal length (cm) 0.0 sepal width (cm) 0.0 petal length (cm) 0.0 petal width (cm) 0.0 dtype: float64, sepal length (cm) 1.0 sepal width (cm) 1.0 petal length (cm) 1.0 petal width (cm) 1.0 dtype: float64)
'머신러닝' 카테고리의 다른 글
교차검증 (0) 2020.07.28 랜덤 포레스트 (0) 2020.07.28 SVM (0) 2020.07.28 Machine-Learning (0) 2020.07.23 -