[Python] 범주형 데이터 인코딩하기
범주형 데이터 인코딩 방법
1) 순서가 없는 특성: One-Hot Encoding 더미변수화
pd.get_dummies
: 문자열 데이터만 변환, 나머지 열은 그대로
# 예제 데이터 프레임 만들기
import pandas as pd
df = pd.DataFrame([['green', 'M', 10.1, 'class1'],
['red', 'L', 13.5, 'class2'],
['blue', 'XL', 15.3, 'class1']])
df.columns = ['color', 'size', 'price', 'classlabel']
df
color | size | price | classlabel | |
---|---|---|---|---|
0 | green | M | 10.1 | class1 |
1 | red | L | 13.5 | class2 |
2 | blue | XL | 15.3 | class1 |
pd.get_dummies(df[['price', 'color', 'size']]) # 인자에 범위 지정
price | color_blue | color_green | color_red | size_L | size_M | size_XL | |
---|---|---|---|---|---|---|---|
0 | 10.1 | 0 | 1 | 0 | 0 | 1 | 0 |
1 | 13.5 | 0 | 0 | 1 | 1 | 0 | 0 |
2 | 15.3 | 1 | 0 | 0 | 0 | 0 | 1 |
pd.get_dummies(df['classlabel'])
class1 | class2 | |
---|---|---|
0 | 1 | 0 |
1 | 0 | 1 |
2 | 1 | 0 |
# columns 매개 변수 사용: 변환하려는 특성을 구체적으로 지정 가능
pd.get_dummies(df[['price', 'color', 'size']], columns = ['size'])
price | color | size_L | size_M | size_XL | |
---|---|---|---|---|---|
0 | 10.1 | green | 0 | 1 | 0 |
1 | 13.5 | red | 1 | 0 | 0 |
2 | 15.3 | blue | 0 | 0 | 1 |
# `drop_first` 매개 변수 True (첫번째 열 삭제)
pd.get_dummies(df[['price', 'color', 'size']], drop_first=True) # color_blue가 삭제됨
price | color_green | color_red | size_M | size_XL | |
---|---|---|---|---|---|
0 | 10.1 | 1 | 0 | 1 | 0 |
1 | 13.5 | 0 | 1 | 0 | 0 |
2 | 15.3 | 0 | 0 | 0 | 1 |
- sklearn.processing의
OneHotEncoder
사용법
from sklearn.preprocessing import OneHotEncoder
X = df[['color', 'price', 'size']].values
color_ohe = OneHotEncoder()
# 배열의 다른 2개 열 수정하지 않기 위해 첫번째 열만 적용 X[:, 0]
color_ohe.fit_transform(X[:, 0].reshape(-1, 1)).toarray()
array([[0., 1., 0.],
[0., 0., 1.],
[1., 0., 0.]])
- 여러 개의 특성이 있는 배열에서 특정 열만 반환 시
ColumnTransformer
사용
from sklearn.compose import ColumnTransformer
X = df[['color', 'size', 'price']].values
c_transf = ColumnTransformer([
('one_hot', OneHotEncoder(), [0]),
('nothing', 'passthrough', [1, 2])]) # 그대로 두기
c_transf.fit_transform(X)
array([[0.0, 1.0, 0.0, 'M', 10.1],
[0.0, 0.0, 1.0, 'L', 13.5],
[1.0, 0.0, 0.0, 'XL', 15.3]], dtype=object)
2) 순서가 있는 특성 Mapping
- Mapping 함수 만들거나
enumerate
활용
# 데이터 특성 간 산술적 차이 알고 있을 때
# XL = L +1 = M + 2
size_mapping = {
'XL': 3,
'L': 2,
'M': 1 }
df['size'] = df['size'].map(size_mapping)
df
color | size | price | classlabel | |
---|---|---|---|---|
0 | green | 1 | 10.1 | class1 |
1 | red | 2 | 13.5 | class2 |
2 | blue | 3 | 15.3 | class1 |
# 다시 문자열로 돌리고 싶을 때 사용하는 함수
inv_size_mapping = {v: k for k, v in size_mapping.items()}
df['size'].map(inv_size_mapping)
0 M
1 L
2 XL
Name: size, dtype: object
# numpy & enuemerate 함수 활용
import numpy as np
class_mapping = {label: idx for idx, label in enumerate(np.unique(df['classlabel']))}
class_mapping
{'class1': 0, 'class2': 1}
# 위와 동일하게 사용
df['classlabel'] = df['classlabel'].map(class_mapping)
df
color | size | price | classlabel | |
---|---|---|---|---|
0 | green | 1 | 10.1 | 0 |
1 | red | 2 | 13.5 | 1 |
2 | blue | 3 | 15.3 | 0 |
inv_class_mapping = {v: k for k, v in class_mapping.items()}
df['classlabel'] = df['classlabel'].map(inv_class_mapping)
df
color | size | price | classlabel | |
---|---|---|---|---|
0 | green | 1 | 10.1 | class1 |
1 | red | 2 | 13.5 | class2 |
2 | blue | 3 | 15.3 | class1 |
- sklearn
LableEncoder
활용
from sklearn.preprocessing import LabelEncoder
class_label = LabelEncoder()
y = class_label.fit_transform(df['classlabel'].values)
y
array([0, 1, 0])
df['classlabel'] = class_label.fit_transform(df['classlabel'].values)
df
color | size | price | classlabel | |
---|---|---|---|---|
0 | green | 1 | 10.1 | 0 |
1 | red | 2 | 13.5 | 1 |
2 | blue | 3 | 15.3 | 0 |
# inverse_transform() 사용하면 원복 가능
inv_y = class_label.inverse_transform(y)
df['classlabel'] = inv_y
df
color | size | price | classlabel | |
---|---|---|---|---|
0 | green | 1 | 10.1 | class1 |
1 | red | 2 | 13.5 | class2 |
2 | blue | 3 | 15.3 | class1 |
# 임계값 (threshold) 사용 인코딩
df['x > M'] = df['size'].apply(lambda x: 1 if x in ['L', 'XL'] else 0)
df['x > L'] = df['size'].apply(lambda x: 1 if x == 'XL' else 0)
del df['size']
df
color | price | classlabel | x > M | x > L | |
---|---|---|---|---|---|
0 | green | 10.1 | class1 | 0 | 0 |
1 | red | 13.5 | class2 | 1 | 1 |
2 | blue | 15.3 | class1 | 0 | 1 |
댓글남기기