본문 바로가기
AI

[sklearn] 데이터 전처리 - 1) 데이터 인코딩

by didi0di 2023. 7. 24.
728x90

데이터 전처리는 ML 알고리즘 만큼 중요합니다.

GIGO (Garbage In, Garbage Out) 이라고 하죠.

 

머신러닝을 위한 대표적인 인코딩 방식은 2가지가 있습니다.

 

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

: 카테고리 피처를 코드형 숫자값으로 변환 

 

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

 

먼저 레이블 인코딩에 대해 알아보겠습니다.

 

레이블 인코딩

 

사이킷런의 레이블 인코딩은 LabelEncoder 클래스로 구현합니다.

LabelEncoder 객체 생성 후 fit()과 transform()을 호출해 레이블 인코딩을 수행합니다.

 

from sklearn.preprocessing import LabelEncoder

items = ['우유', '계란', '치즈', '요거트', '식빵', '식빵' ]

# LabelEncoder 객체 생성 후 fit()과 transform()을 호출해 레이블 인코딩을 수행
encoder = LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)
print('인코딩 변환값: ', labels)

>> 인코딩 변환값:  [3 0 4 2 1 1]

위 경우엔 데이터가 적어서 문자열 값이 어떤 숫자 값으로 인코딩됐는지 직관적으로 알 수 있지만,

데이터가 많은 경우에는 이를 알 수 없습니다.

이 때는 LabelEncoder 객체의 classes_ 속성값으로 확인하면 됩니다.

print('인코딩 클래스 : ', encoder.classes_)

>> 인코딩 클래스 :  ['계란' '식빵' '요거트' '우유' '치즈']

 

classes_ 속성은 0번부터 순서대로 변환된 인코딩 값에 대한 원본값을 가지고 있습니다.

따라서 계란이 0, 식빵이 1, 요거트가 2, 우유가 3, 치즈가 4로 인코딩됐음을 알 수 있습니다.

 

inverse_transform() 을 통해 인코딩 된 값을 다시 디코딩 할 수 있습니다.

 

print('디코딩 원본값 : ', encoder.inverse_transform([4,3,3, 1,2,1,0]))

>> 디코딩 원본값 :  ['치즈' '우유' '우유' '식빵' '요거트' '식빵' '계란']

 

하지만, 레이블 인코딩은 일괄적인 숫자값으로 변환이 되면서

숫자값의 대소 비교 가능 특성 상 몇몇 ML 알고리즘에는 이를 적용할 경우 예측 성능이 떨어지는 경우가 발생할 수 있습니다. 

이러한 특성 때문에 레이블 인코딩은 선형 회귀와 같은 ML 알고리즘에는 적용하지 않아야 합니다.

트리 계열의 ML 알고리즘은 숫자의 이러한 특성을 반영하지 않으므로 괜찮습니다.

 

원-핫 인코딩은 레이블 인코딩의 이러한 문제점을 해결하기 위한 인코딩 방식입니다.

 

원-핫 인코딩

피처값의 유형에 따라 새로운 피처를 추가해

고유 값에 해당하는 칼럼에만 1을 표시하고 나머지 칼럼에는 0을 표시하는 방식입니다.

 

사이킷런에서 OneHotEncoder 클래스로 쉽게 변환이 가능합니다.

단 주의해야 할 사항이 있습니다.

 

** OneHotEncoder 주의점 

1) OneHotEncoder로 변환하기 전에 모든 문자열 값이 숫자형으로 변환돼야 함

2) 입력값으로 2차원 데이터가 필요함

 

이제 원-핫 인코딩을 적용해 보겠습니다.

from sklearn.preprocessing import OneHotEncoder
import numpy as np

items = ['우유', '계란', '치즈', '요거트', '식빵', '식빵']

# 1) 숫자값으로 변환을 위해 LabelEncoder 사용
encoder = LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)

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

# 원-핫 인코딩 적용
oh_encoder = OneHotEncoder()
oh_encoder.fit(labels)
oh_labels = oh_encoder.transform(labels)
print('원-핫 인코딩 데이터')
print(oh_labels.toarray())
print('원-핫 인코딩 차원')
print(oh_labels.shape)

>> 원-핫 인코딩 데이터
[[0. 0. 0. 1. 0.]
 [1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1.]
 [0. 0. 1. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 1. 0. 0. 0.]]
원-핫 인코딩 차원
(6, 5)

 

판다스의 get_dummies() API를 이용하면 더 쉽게 원-핫 인코딩을 수행할 수 있습니다.

사이킷런과 달리, 숫자형으로 변환할 필요 없이 바로 변환할 수 있습니다.

 

import pandas as pd

items = ['우유', '계란', '치즈', '요거트', '식빵', '식빵']
df =  pd.DataFrame({'item' : items})
pd.get_dummies(df)

get_dummies()를 이용한 원-핫 인코딩 결과

 

728x90

'AI' 카테고리의 다른 글

Stable Diffusion 2.1 Demo 리뷰  (0) 2023.11.03

댓글