[머신러닝 완벽 가이드] 2장_사이킷런으로 시작하는 머신러닝 (2)

이경민·2023년 1월 5일
0

📌 데이터 전처리

✅ 데이터 인코딩

(1) 레이블 인코딩 (Label encoding)

  • 문자열 값을 숫자형 카테고리 값으로 변환

  • 단순 코드일 뿐, 숫자 값에 따른 순서나 중요도 의미 X

    • 선형 회귀에는 적용 X -> 원-핫 인코딩 사용
    • 트리 계열은 상관없음
  • encoder = LabelEncoder()

    • encoder.fit() : 데이터 학습
    • encoder.transform(): 데이터 변환
    • encoder.inverse_transform(): 디코딩 결과 반환
    • encoder.classes_: 0번부터 순서대로 변환된 인코딩 값에 대한 원본값 반환
from sklearn.preprocessing import LabelEncoder

items=['TV','냉장고','전자렌지','컴퓨터','선풍기','선풍기','믹서','믹서']

# LabelEncoder를 객체로 생성한 후 , fit()과 transform()으로 label 인코딩 수행
encoder = LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)
print('인코딩 변환값:',labels) # 인코딩 변환값: [0 1 4 5 3 3 2 2]

print('인코딩 클래스:',encoder.classes_) # 인코딩 클래스: ['TV' '냉장고' '믹서' '선풍기' '전자렌지' '컴퓨터']
print('디코딩 원본 값:',encoder.inverse_transform([4, 5, 2, 0, 1, 1, 3, 3])) # 디코딩 원본 값: ['전자렌지' '컴퓨터' '믹서' 'TV' '냉장고' '냉장고' '선풍기' '선풍기']

(2) 원-핫 인코딩 (One-Hot encoding)

  • 피처 값의 유형에 따라 새로운 피처를 추가해 고유 값에 해당하는 칼럼에만 1을 표시하고, 나머지 칼럼에는 0을 표시하는 방식

  • encoder = OneHotEncoder()

    • OneHotEncoder로 변환하기 전에, 문자열 값 -> 숫자형 값으로 변환: LabelEncoder()
    • 2차원 데이터로 입력: reshape(-1, 1)
    • encoder.fit() : 데이터 학습
    • encoder.transform(): 데이터 변환
from sklearn.preprocessing import OneHotEncoder
import numpy as np

items=['TV','냉장고','전자렌지','컴퓨터','선풍기','선풍기','믹서','믹서']

# LabelEncoder: 숫자형 값으로 변환
encoder = LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)

# 2차원 데이터로 변환
labels = labels.reshape(-1,1)

# 원-핫 인코딩 적용
oh_encoder = OneHotEncoder()
oh_encoder.fit(labels)
oh_labels = oh_encoder.transform(labels)

# 원-핫 인코딩 데이터 확인
print(oh_labels.toarray())
  • pd.get_dummies(df)

    • 문자열 값을 숫자형 값으로 변환할 필요 없이 바로 변환 가능
import pandas as pd

df = pd.DataFrame({'item':['TV','냉장고','전자렌지','컴퓨터','선풍기','선풍기','믹서','믹서'] })
pd.get_dummies(df)

✅ 피처 스케일링

  • 서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업을 의미

(1) 표준화 (Standardization)

  • 평균이 0이고, 분산이 1인 가우시안 정규 분포를 가진 값으로 변환

  • sclaer = StandardScaler()

    • scaler.fit(): 데이터 학습
    • scaler.transform(): 데이터 변환 (numpy.ndarray로 반환)
  • 예측 성능 향상에 중요한 요소가 될 수 있음 -> SVM, 선형 회귀, 로지스틱 회귀

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler

# 붓꽃 데이터 세트를 로딩, DataFrame으로 변환 
iris = load_iris()
iris_data = iris.data
iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names)

# StandardScaler 객체 생성
scaler = StandardScaler()

# 각 피처별로 StandardScaler 적용: 표준화
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)

# 스케일 변환된 데이터 세트를 numpy ndarray로 반환 -> DataFrame으로 변환
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)

(2) 정규화 (Normalization)

  • 서로 다른 피처의 크기를 통일하기 위해 모두 똑같은 단위를 갖도록 크기를 변환

  • 최소 0 ~ 최대 1의 값으로 변환

  • scaler = MinMaxScaler()

    • 데이터의 분포가 가우시안 분포가 아닐 경우 적용
    • 0과 1사이의 범위 값으로 변환 (음수 값이 있으면 -1~1)
    • scaler.fit(): 데이터 학습
    • scaler.transform(): 데이터 변환 (numpy.ndarray로 반환)
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.preprocessing import MinMaxScaler

# 붓꽃 데이터 세트를 로딩, DataFrame으로 변환 
iris = load_iris()
iris_data = iris.data
iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names)

# MinMaxScaler 객체 생성
scaler = MinMaxScaler()

# 각 피처별로 MinMaxScaler 적용: 정규화 
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)

# 스케일 변환된 데이터 세트를 numpy ndarray로 반환 -> DataFrame으로 변환
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)

✅ 학습 데이터와 테스트 데이터의 스케일링 변환 시 유의점

  • fit(): 데이터 변환을 위한 기준 정보 설정
  • transform(): 설정된 정보를 이용해 데이터를 변환
  • fit_transform(): fit(), transform() 한번에 적용

[방법 1]
전체 데이터를 대상으로 스케일링 변환을 적용한 뒤, 학습과 테스트 데이터 분리

[방법 2]
학습 데이터: fit(), transform() / fit_transform()
테스트 데이터: transform()만 적용

✅ 결측값(Null) 처리

  • ML 알고리즘은 Null 값을 허용하지 않으므로 전처리 필요
    • Null 값이 얼마 되지 않는다면, 피처의 평균값 등으로 대체
    • Null 값이 대부분이라면, 해당 피처는 드롭
  • isnull(): 결측값 여부 반환 (True/False)

  • fillna(x, inplace=True): 결측값을 x로 대체

  • dropna(): 결측값 제거

    • axis=0, 결측값이 들어있는 행 제거
    • axis=1, 결측값이 들어있는 열 제거
# 피처별 결측값 개수 확인
df.isnull().sum()

# 결측값 -> 해당 피처의 평균값으로 대체
df['A'].fillna(df['A'].mean(), inplace=True)
profile
열정 가득한 공간

0개의 댓글