working_helen

[데이터 전처리] Encoding 인코딩 본문

TAVE/뿌스팅 project

[데이터 전처리] Encoding 인코딩

HaeWon_Seo 2023. 8. 7. 22:25

데이터 전치리 과정에서 학습한 내용 중 첫 번째로 Encoding 인코딩 방법에 대해 공부해본다.

 

1. 인코딩이란?
2. One-Hot Encoding 원 핫 인코딩
3. Binary Encoding 바이너리 인코딩
4. Label Encoding 라벨 인코딩
5. Ordinal Encoding 오디널 인코딩



1. 인코딩이란?

인코딩 = 자연어 or 범주형 데이터를 수치적 데이터로 변환해주는 작업

: 기계는 수치형 데이터만을 처리할 수 있기 때문에 자연어나 범주형 데이터를 처리하기 위해선 이를 수치형 데이터로 변환시켜주는 작업이 필요하다.

- 다양한 인코딩 방법 중 데이터의 특성에 맞춰 정보의 손실을 최소화할 수 있는 적합한 방법을 적용하는 것이 중요

- category_encoders은 범주형 데이터(Categorical data)을 인코딩하는 함수를 제공

 

1) 범주형 데이터의 종류
명목형 데이터 (Nominal) : 항목 간 순서가 없는 데이터 (예. 성별 남/여)
순서형 데이터 (Ordinal) :  항목 간 순서가 있는 데이터 (예. 학점 A/B/C/D/F)

출처 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kimjungg&logNo=221238887930

 

2) 인코딩 방법의 종류

  • One-Hot Encoding
  • Binary Encoding
  • Label Encoding
  • Ordinal Encoding
  • Helmert Encoding
  • Frequency Encoding
  • Mean Encoding
  • Weight of Evidence Encoding
  • Probability Ratio Encoding

 

3) Embedding 임베딩 vs 인코딩 Encoding
- 임베딩이란 자연어와 이미지처럼 수치화되어 있지 않는 데이터를 특징 추출을 통해 컴퓨터가 처리할 수 있는 벡터 형태로 수치화해주는 방법
- 임베딩을 통해 단어를 벡터화 => 인코딩을 통해 단어 벡터를 수치화
- 인코딩을 임베딩 과정에 활용할 수 있다. 대표적으로 짧은 문장들에 대해선 One-hot Encoding을 사용한 임베딩이 자주 사용된다.

 

※ 참고 : train data와 test data에서 encoding 차이

- train data에서 fit을 통해 인코딩 사전을 만들고, transform으로 변형까지 진행

- test data에서는 train에서 만든 인코딩 사전을 이용해 transform만 진행한다.

# 인코더 생성
encoder = OneHotEncoder()

# train data : 인코딩 사전 학습 (대응 관계 생성)
train = encoder.fit_transform(train)

# test data : 이미 만든 인코더를 그대로 적용
test = encoder.transform(test)

 

 

 

 

 

2. One-Hot Encoding 원 핫 인코딩

- 0과 1을 사용해 주어진 데이터가 범주의 어떤 항목에 속하는지 표현한다. 데이터가 속하는 항목인 경우 1을, 그렇지 않은 항목인 경우 0을 성분으로 두어 어떤 항목에 속하는지 표현한다.
- 항목의 개수와 같은 크기의 벡터를 사용한다. 즉 범주형 변수의 항목이 N개라면 1개의 변수가 N개의 변수로 전환된다.
- 가장 널리 사용되는 인코딩 기법으로, 예를 들어 회귀분석에서 범주형 종속 변수를 수치화할 때 사용되는 것이 있다.

- 단점 : 범주가 너무 넓거나 복잡한 경우 0이 대부분인 매우 sparse한 형태의 고차원 벡터로 표현되기 때문에 메모리 낭비 및 계산 복잡도가 커져 성능이 저해다.

(참고 post : 2023.08.01 - [deep daiv./추천시스템 스터디] - [추천시스템 스터디] 1주차 : 콘텐츠 기반 필터링)

 

- OneHotEncoder 클래스를 사용하거나 pd.get_dummies를 사용해 구현할 수 있다.

# 방법 1 : OneHotEncoder 클래스 이용
from category_encoders import OneHotEncoder
OneHot = OneHotEncoder(cols='행정동명', use_cat_names=True)
OneHot_df = OneHot.fit_transform(df)

# 방법 2 : pd.get_dummies method 이용
OneHot_df_3 = pd.get_dummies(df, columns = ['행정동명'], dtype=int)
OneHot_df_3

직접 실행한 예시

 

 

3. Binary Encoding 바이너리 인코딩

- 범주형 변수의 항목들을 이진법으로 구분할 수 있도록 변환해주는 인코딩 방법이다.
- 원핫 인코딩과 유사하게 1과 0으로만 값을 표현하지만, 1 자체가 해당 항목에 속한다는 의미를 가지진 않는다. encoding 결과의 이진법 표현이 같은 경우, 기존 범주형 변수에서 같은 항목에 속했던 데이터라고 해석할 수 있다.
- 1개의 encoding 변수 추가는 표현가능한 항목 수의 수를 2배로 늘려준다.

  (예 : 4개의 encoding 변수로 변환하면 최대 16개 항목을 구분하여 표현할 수 있다.)

- 원핫 인코딩의 단점 개선 : 인코딩 과정에서 새롭게 생성되는 변수가 적어 학습 속도가 더 빠르다.

 

- BinaryEncoder 클래스를 사용해 구현할 수 있다.

from category_encoders import BinaryEncoder
Binary = BinaryEncoder(cols='행정동명')
Binary_df = Binary.fit_transform(df)

직접 실행한 예시

 

 

4. Label Encoding 라벨 인코딩

- 문자열 데이터의 각 항목을 정수에 대응시켜 수치형으로 인코딩하는 방법
- 문자열 변수의 항목이 N개일 때, 각 항목에 0~N-1의 숫자를 부여하는 인코딩 방식이다.

- 영어는 알파벳 순으로, 한글은 ㄱㄴㄷ 순으로 0부터 대응시킨다.


- 단점 : 실제로는 범주간 순서관계가 없더라도 컴퓨터가 순서관계가 있는 것으로 인식할 수 있다. 예를 들어, 2가 1의 2배라고 생각하는 등 부여된 숫자들 사이에서는 관계성이 자동적으로 부여될 수 있다.

 

- sklearn의 LabelEncoder 클래스를 이용해 구현할 수 있다.

from sklearn.preprocessing import LabelEncoder

Label = LabelEncoder()
df["행정동명_인코딩"] = Label.fit_transform(Label_df["행정동명"])

직접 실행한 예시

 

 

 

5. Ordinal Encoding 오디널 인코딩

- 순서형 변수를 1~N의 숫자로 인코딩 하는 방법이다.

- 적용되는 범주가 명확하고 자연스러운 순서를 갖는다고 가정한다.

- 라벨 인코딩과 유사하게 각 범주에 1~N의 숫자를 부여하는데, 이때 순서 정보를 포함한다는 차이점이 있다. 
- 하나의 인코딩 변수로만 대체되기 때문에 원핫 인코딩에 비해 요구되는 메모리나 계산 복잡도가 적다.

- 단점 : 순서형 변수가 아닌 경우에도 컴퓨터가 인코딩 결과 변수에 자동적으로 (강제적으로) 순서 관계를 부여하여 인식하기 때문에 이로 인한 오류나 성능 저하가 나타날 수 있다. 따라서 데이터에 의미 있는 순서가 없는 경우 적합하지 않다.

 

- OrdinalEncoder 클래스 혹은 map 함수 사용해 구현할 수 있다.
- mapping 속성 : mapping을 사용하지 않으면 인코더가 임의로 순서를 부여한다. (보통 먼저 나온 항목부터 오름차순으로 값을 부여한다) 정확한 순서 부여를 위해 mapping 조건을 설정하여 사용하는 것이 좋다.

# 방법 1. OrdinalEncoder 이용
from category_encoders import OrdinalEncoder

size_mapping = [{
    "col":"넓이",    
    "mapping": {
        'small': 1,
        'medium': 2,
        'large': 3, 
        'extra large' : 4, 
        'NA': np.nan
    }}]
    
Ordinal = ce.OrdinalEncoder(mapping = size_mapping, return_df=True)
Ordinal_df = Ordinal.fit_transform(df)


# 방법 2. map 함수 이용
size_dict = {'small': 1, 'medium': 2, 'large': 3, 'extra large' : 4}
Ordinal_df["넓이_인코딩"] = df['넓이'].map(size_dict)

직접 실행한 예시

 

 

 

 

Jupyter Notebook

 

 

 

Reference

https://conanmoon.medium.com/%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B3%BC%ED%95%99-%EC%9C%A0%EB%A7%9D%EC%A3%BC%EC%9D%98-%EB%A7%A4%EC%9D%BC-%EA%B8%80%EC%93%B0%EA%B8%B0-%EC%9D%BC%EA%B3%B1%EB%B2%88%EC%A7%B8-%EC%9D%BC%EC%9A%94%EC%9D%BC-7a40e7de39d4
https://dacon.io/codeshare/4525
https://beausty23.tistory.com/223

https://dkfl8151.tistory.com/12
https://velog.io/@73syjs/Categorical-Feature-Encoing-Methods
https://contrib.scikit-learn.org/category_encoders/index.html
https://velog.io/@jiazzang/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%9D%B8%EC%BD%94%EB%94%A9Label-encoding-One-Hot-encoding

https://machinelearningmastery.com/one-hot-encoding-for-categorical-data/
https://leochoi146.medium.com/how-and-when-to-use-ordinal-encoder-d8b0ef90c28c
https://www.projectpro.io/recipes/encode-ordinal-categorical-features-in-python