Encoding & Discritization

고은서·2023년 12월 17일
0

Data Preprocessing

목록 보기
6/10

8. 인코딩과 범주화

8.1 인코딩

8.1.1 인코딩이란?

(1) 인코딩의 개념

  • 많은 실제 데이터셋에는 수치형(numerical)과 범주형(categorical) 변수가 혼재하고 있음
  • 인코딩은 컴퓨터가 처리하기 용이하도록 기존의 데이터를 변경하는 것
  • 범주형 데이터는 일반적으로 텍스트(string)로 되어 있으므로 이를 숫자(일반적으로 양의 정수)로 변환
  • 디코딩: 인코딩된 코드를 원래의 데이터로 변환하는 것
  1. 레이블 인코딩(Label encoding)
    • 분류(classification) 문제에서는 종속변수가 범주형이어야 하므로 수치형(numerical) 데이터는 범주형으로 변환해주어야 함
  2. 이진화(Binarizsaztion), 이산화(Discretization)
    • 회귀(regression) 모형이나 신경망에서는 독립변수는 수치형 변수이어야 하므로 범주형 변수를 수치형으로 변환해주어야 함
  3. 원핫인코딩(One-hot encoding), 더미변수화(Dummy encoding)
    • 텍스트 데이터는 자연어 처리를 위해 토큰화(tokenization) 과정을 거쳐야 함
  4. 정수인코딩(Integer encoding)
    • 인코딩된 코드를 원래의 데이터로 변환하는 것은 디코딩(Decoding)이라고 함

8.1.2 범주형 데이터 -> 이산 수치형 데이터

  • OrdinalEncoder() (1:1)
    • 범주형 데이터를 정수로 인코딩
    • 여러 컬럼(독립변수)에 사용 가능
  • LabelEncoder() (1:1)
    • 범주형 데이터를 정수로 인코딩
    • 하나의 컬럼(종속변수, 타겟)에만 사용 가능
  • TargetEncoder() (1:1)
    • 범주형 데이터를 특정한 컬럼(타겟)의 값의 크기와 비례한 숫자로 인코딩

예제 데이터 세트 생성

import pandas as pd

df = pd.DataFrame({'weight':[40, 80, 60, 50, 90], # feature: weight, continuous
                   'height':[162, 155, 182, 173, 177], # feature: height, continuous
                   'sex':['f', 'm', 'm', 'f', 'm'], # feature: sex, categorical
                   'blood_type':['O', 'A', 'B', 'O', 'A'], # feature: blood_type, categorical
                   'health':['good', 'excellent', 'bad', 'bad', 'good'], # target: health, categorical
                   })
df

Ordinal Encoder

  • 범주형 데이터를 정수로 인코딩
  • 여러 컬럼(독립변수)에 사용 가능
from sklearn.preprocessing import OrdinalEncoder

# 데이터프레임 복사
df_oe = df.copy()

# OrdinalEncoder에 대한 객체 생성
oe = OrdinalEncoder()

# 데이터로 oe 학습
oe.fit(df)

# 학습된 결과
print(f'{oe.categories_=}')
# OrdinalEncoder는 수치형 weight와 height도 범주형으로 인식하여 변경하므로 주의

# 학습된 결과를 적용하여 변환
df_oe = pd.DataFrame(oe.transform(df), columns=df.columns)
df_oe

Ordinal Encoder 수정된 사용

# OrdinalEncoder 수정된 사용

# 데이터프레임 복사
df_oe = df.copy()

# OrdinalEncoder에 대한 객체 생성
oe = OrdinalEncoder()

# 데이터로 oe 학습
oe.fit(df[['sex', 'blood_type']])

# 학습된 결과
print(f'{oe.categories_=}')

# 학습된 결과를 적용하여 삽입
df_oe.iloc[:,2:4] = oe.transform(df[['sex', 'blood_type']])
df_oe

디코딩

# 디코딩(decoding)
oe.inverse_transform(df_oe.iloc[:,2:4])

LabelEncoder

  • 범주형 데이터를 정수로 인코딩
  • 하나의 컬럼(종속변수, 타겟)에만 사용 가능
from sklearn.preprocessing import LabelEncoder

# 데이터프레임 복사
df_le = df.copy()

# LabelEncoder는 하나의 변수에 대해서만 변환 가능
# LabelEncoder 객체 생성과 fit을 동시에 적용
health_le = LabelEncoder().fit(df.health)
df_le['health'] = health_le.transform(df.health)
df_le
# fit_transform() 메서드를 사용하여 한번에 인코딩 수행가능

# 데이터프레임 복사
df_le = df.copy()

# LabelEncoder 객체 생성과 fit을 동시에 적용
df_le['health'] = LabelEncoder().fit_transform(df.health)
df_le

Target Encoder

  • 범주형 데이터를 특정한 컬럼(타겟)의 값의 크기와 비례한 숫자로 인코딩
from sklearn.preprocessing import TargetEncoder

# 데이터프레임 복사
df_te = df.copy()

# TargetEncoder에 대한 객체 생성
# smooth는 정밀도를 조정하고 target_type은 인코딩 타입을 지정
te = TargetEncoder(smooth=0, target_type='continuous')

# 데이터로 te 학습
# 타겟을 weight라고 가정하고 blood_type을 인코딩
# blood_type_target은 weight와 비례하여 인코딩된 값
# 인코딩이 되는 값은 2차원으로 변환해야 함
te.fit(df['blood_type'].values.reshape(-1, 1), df.weight)

# 학습된 결과
print(f'{te.categories_=}')

# 학습된 결과를 적용하여 새로운 컬럼 삽입
df_te['blood_type_target'] = te.transform(df['blood_type'].values.reshape(-1, 1))
df_te

8.1.3 범주형 데이터 -> 이진형 데이터

  • One-hot encoding (1:M)
    • 하나의 컬럼에 있는 범주형 데이터를 여러개의 이진수 컬럼(수치형 데이터)로 인코딩
    • one-of-K 인코딩이라고도 함
  • Dummy encoding (1:M)
    • One-hot encoding과 동일한 기능
    • 회귀분석에서 범주형 변수를 고려할 때 사용

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

  • 하나의 컬럼에 있는 범주형 데이터를 여러개의 이진수 컬럼(수치형 데이터)로 인코딩
  • one-of-K 인코딩이라고도 함
from sklearn.preprocessing import OneHotEncoder

# 데이터프레임 복사
df_ohe = df.copy()

# OneHotEncoder에 대한 객체 생성 후 fit
ohe = OneHotEncoder().fit(df_ohe[['blood_type']])

# 학습된 결과
print(f'{ohe.categories_=}')

# 학습된 결과를 적용하여 새로운 컬럼 삽입
# OneHotEncoder는 결과를 sparse matrix로 반환하므로 toarray()를 통해 ndarray로 변환
df_ohe[ohe.categories_[0]] = ohe.transform(df_ohe[['blood_type']]).toarray()
df_ohe

Dummy encoding

  • Pandas에서 제공하는 get_dummies는 One-hot encoding과 동일한 기능
  • 여러 컬럼을 한 번에 변환 가능
  • 회귀분석에서 범주형 변수를 고려할 때 사용
pd.get_dummies(df, columns=['sex', 'blood_type'], drop_first=False)

8.1.4 연속수치형 데이터 -> 이진형 데이터

  • Binarizer() (1:1)
    • 연속 수치형 데이터를 기준값(threshold)을 기준으로 이진수로 인코딩
  • LabelBinarizer() (1:M)
    • 연속형 데이터를 이진수 컬럼으로 인코딩
    • 하나의 컬럼(종속변수, 타겟)에만 사용 가능
  • MultiLabelBinarizer() (1:M)
    • multi-class(여러개의 범주가 있는) 데이터를 이진수 컬럼으로 인코딩
    • 하나의 컬럼(종속변수, 타겟)에만 사용 가능

Binerizer

  • 연속 수치형 데이터를 기준값(threshold)을 기준으로 이진수로 인코딩
from sklearn.preprocessing import Binarizer

# 데이터 불러오기
df_bin = df.copy()

# Binarizer 객체 생성과 fit, transform을 동시에 적용
# Binarizer는 수치형 변수에 대해서만 변환 가능
df_bin['weight_bin'] = Binarizer(threshold=50).fit_transform(df.weight.values.reshape(-1,1))
df_bin['height_bin'] = Binarizer(threshold=170).fit_transform(df.height.values.reshape(-1,1))
df_bin

LabelBinerizer

  • 연속형 데이터를 이진수 컬럼으로 인코딩
  • 하나의 컬럼(종속변수, 타겟)에만 사용 가능
from sklearn.preprocessing import LabelBinarizer

# 데이터프레임 복사
df_lb = df.copy()

# LabelBinarizer 객체 생성과 fit을 적용
lb = LabelBinarizer().fit(df.health)

# lb.classes_ : LabelBinarizer가 인코딩한 클래스 확인
print(f'{lb.classes_ = }')

# lb.transform() : 인코딩 변환
health_lb = lb.transform(df.health)
print('health_lb = \n', health_lb)

# 인코딩된 데이터를 데이터프레임으로 변환
df_lb[lb.classes_] = health_lb
df_lb

MultiLabelBinerizer

  • multi-class(여러개의 범주가 있는) 데이터를 이진수 컬럼으로 인코딩
  • 하나의 컬럼(종속변수, 타겟)에만 사용 가능
from sklearn.preprocessing import MultiLabelBinarizer

# 데이터프레임 복사
df_mlb = df.copy()

# multi-class를 위한 컬럼 추가
df_mlb['test'] = [['math', 'english'], ['math', 'science'], ['science'], ['math', 'english'],
                           ['science']] # target: test, categorical, multi-class
df_mlb
# MultiLabelBinarizer 객체를 생성하고 fit() 메소드를 호출하여 클래스를 인코딩
mlb = MultiLabelBinarizer().fit(df_mlb.test)

# classes_ 속성을 사용하면 어떤 클래스가 인코딩되었는지 확인 가능
print(f'{mlb.classes_ = }')

# 인코딩된 데이터를 데이터프레임으로 변환
df_mlb[mlb.classes_] = mlb.transform(df_mlb.test)
df_mlb

8.2 범주화

8.2.1 범주화 (Discritization)

  • 연속형 변수를 구간별로 나누어 범주형 변수로 변환하는 것
  • quantization 또는 binning이라고도 함

K-bins discretization


from sklearn.preprocessing import KBinsDiscretizer

# 데이터프레임 복사
df_kbd = df.copy()

# KBinsDiscretizer 객체 생성과 fit을 적용
kbd = KBinsDiscretizer(n_bins=3, encode='ordinal').fit(df[['weight', 'height']])

# kbd.transform() : 인코딩 변환
# 인코딩된 데이터를 데이터프레임으로 변환
df_kbd[['weight_bin', 'height_bin']] = kbd.transform(df[['weight', 'height']])
df_kbd

8.3 Titanic 데이터 응용

8.3.1 데이터 불러오기 및 파악하기

import seaborn as sns
titanic = sns.load_dataset('titanic')

df = pd.DataFrame(titanic)
df.info()
df.head()
# 데이터프레임 복사
df_oe = df.copy()

# OrdinalEncoder에 대한 객체 생성
oe = OrdinalEncoder()

# 데이터로 oe 학습
oe.fit(df)

# 학습된 결과 출력
print(f'{oe.categories_=}')

# 학습된 결과를 적용하여 변환
df_oe = pd.DataFrame(oe.transform(df), columns=df.columns)
df_oe.head()

# OrdinalEncoder 수정된 사용

# 데이터프레임 복사
df_oe = df.copy()

# OrdinalEncoder에 대한 객체 생성
oe = OrdinalEncoder()

# 데이터로 oe 학습
oe.fit(df[['sex', 'embarked']])

# 학습된 결과
print(f'{oe.categories_=}')

# 학습된 결과를 적용하여 삽입
df_oe.iloc[:,2:4] = oe.transform(df[['sex', 'embarked']])
df_oe

디코딩

# 디코딩(decoding)
oe.inverse_transform(df_oe.iloc[:,2:4])
from sklearn.preprocessing import LabelEncoder

# 데이터프레임 복사
df_le = df.copy()

who_le = LabelEncoder().fit(df.who)
df_le['who'] = who_le.transform(df.who)
df_le
# fit_transform() 메서드를 사용하여 한번에 인코딩 수행가능

# 데이터프레임 복사
df_le = df.copy()

# LabelEncoder 객체 생성과 fit을 동시에 적용
df_le['who'] = LabelEncoder().fit_transform(df.who)
df_le
from sklearn.preprocessing import TargetEncoder

# 데이터프레임 복사
df_te = df.copy()

# TargetEncoder에 대한 객체 생성
# smooth는 정밀도를 조정하고 target_type은 인코딩 타입을 지정
te = TargetEncoder(smooth=0, target_type='continuous')

# 데이터로 te 학습
# 타겟을 survived라고 가정하고 embark_town을 인코딩
# embarktown은 survived와 비례하여 인코딩
# 인코딩이 되는 값은 2차원으로 변환해야 함
te.fit(df['embark_town'].values.reshape(-1, 1), df.survived)

# 학습된 결과
print(f'{te.categories_=}')

# 학습된 결과를 적용하여 새로운 컬럼 삽입
df_te['embark_town_target'] = te.transform(df['embark_town'].values.reshape(-1, 1))
df_te
profile
cities and data

0개의 댓글

관련 채용 정보