명목형 범주형 변수 인코딩

CHOI CHOI·2024년 6월 7일
0

파이썬 중급

목록 보기
17/30
post-thumbnail

One-Hot Encoding

scikit-learn 라이브러리 활용하여 구현하기

import pandas as pd
from sklearn.preprocessing import OneHotEncoder  

train_ex1 = train_used_car.copy()

encoder = OneHotEncoder(sparse_output = False)
train_encoded = encoder.fit_transform(train_ex1[['Brand','Model']]) 

encoded_columns = encoder.get_feature_names_out(['Brand', 'Model'])
train_encoded_df = pd.DataFrame(train_encoded, columns=encoded_columns)

train_ex1 = pd.concat([train_ex1, train_encoded_df], axis=1).drop(['Brand', 'Model'], axis=1)

display(encoded_columns)
display(train_ex1.head())

코드설명

import pandas as pd 
from sklearn.preprocessing import OneHotEncoder

pandas 라이브러리와 sklearn의 OneHotEncoder클래스를 불러온다.
pandas는 데이터 처리를 위한 라이브러리이며, OneHotEncoder는 범주형 변수를 위한 원-핫 인코딩으로 변환하는 데 사용

train_ex1 = train_used_car.copy():

train_used_car 데이터 프레임의 복사본을 생성하여 train_ex1에 할당
이렇게 작업하면 원본데이터는 변경되지 않고 복사본에서 작업가능

encoder = OneHotEncoder(sparse_output = False)

OneHotEncoder객체를 생성
sparse_output = False는 인코딩된 데이터를 밀집 배열 형태로 반환하도록 설정

train_encoded = encoder.fit_transform(train_ex1[['Brand','Model']]

Brand와 Model컬럼에 대해 원-핫 인코딩을 수행
fit_transform 메소드는 먼저 인코더를 데이터에 맞추고(fit), 그 다음 데이터를 변환(transform)

encoded_colums = encoder.get_feature_names_out(['Brand','Model'])

인코딩된 데이터의 컬럼 이름을 가져옴
이 이름들은 나중에 데이터프레임에 추가

train_encoded_df = pd.DataFrame(train_encoded, columns=encoded_columns)

인코딩된 데이터를 pandas데이터프레임으로 변환
이때, 앞서 얻은 컬럼 이름을 사용

train_ex1 = pd.concat([train_ex1, train_encoded_df],axis=1).drop(['Brand','Model'],axis=1)

원본 데이터프레임과 인코딩된 데이터프레임을 합침(concat)
그리고 Brand와 Model컬럼은 더 이상 필요하지 않으므로 삭제(drop)

학습데이터에 없는 범주 올바르게 처리하기

"Error : Found unknown categories ['Chevrolet'] in column 0 during transform"

이 요류는 데스트 데이터셋의 'Brand'컬럼에 'Chevrolet'이라는 학습데이터셋에는 존재하지 않는 새로운 범주가 있기 때문에 발생

OneHotEncoder 클래스의 handle_unknown='ignore' 매개변수

앞서 발생한 문제를 해결하기 위해, OneHotEncoder 클래스의 handle_unknown='ignore' 옵션을 활용
이 설정은 학습 데이터셋에 존재하지 않는 새로운 범주를 만나더라도 오류 없이 처리하도록 도와준다. 실제 데이터 처리 과정에서 예상치 못한 새로운 범주가 등장하는 상황에 대비해, handle_unknown='ignore' 설정을 사용하는 것이 바람직

encoder_ex2 = OneHotEncoder(sparse_output = False, handle_unknown ='ignore' )

원-핫 엔코딩과 컬럼수 증가의 영향

원-핫 인코딩으로 인한 컬럼 수의 증가가 데이터 분석 및 모델링에 부정적인 영향을 미치지는 않을까?하는 의문점! -> 컬럼수가 많아진다면 바이너리인코딩

Binary Encoding

고유 범주의 갯수가 많은 명복형 변수를 인코딩할 수 있는 대표적인 기법이 바이너리 인코딩. 이 기법은 데이터의 차원을 효과적으로 줄이면서 각 범주를 명확하게 표현할 수 있는 장점을 가지고 있다.

바이너리 인코딩은 각 범주를 레이블 인코딩으로 변환한 후, 이진수로 표현하여 범주의 수에 비례하지 않는 고정된 길이의 열을 생성한다. 이는 차원의 증가를 상당히 제한하며, 동시에 각 범주를 효율적으로 표현할 수 있게 된다.

category_encoders 라이브러리의 BinaryEncoder클래스는 이러한 바이너리 인코딩 과정을 간편하게 수행할 수 있게 해준다. 이 라이브러리는 각 범주를 자동으로 레이블 인코딩하고, 이를 이진수 형태로 변환하여 새로운 열을 생성한다.

import category_encoders as ce

train_ex5 = train_income.copy()

train_ex5['occupation'].fillna('Unknown', inplace=True)

# Creating a BinaryEncoder instance
encoder_ex5 = ce.BinaryEncoder(cols=['occupation'])

# Fitting and transforming the 'occupation' column
train_encoded_ex5 = encoder_ex5.fit_transform(train_ex5['occupation'])

encoded_columns_ex5 = train_encoded_ex5.columns

# Creating a DataFrame from the binary encoded data
train_encoded_df5 = pd.DataFrame(train_encoded_ex5, columns=encoded_columns_ex5)
train_ex5 = pd.concat([train_ex5, train_encoded_df5], axis=1).drop(['occupation'], axis=1)

display(encoded_columns_ex5)
display(train_ex5.head())

결론

범주형 변수의 인코딩은 데이터 전처리에서 중요한 단계이다.
특히 많은 범주를 가진 명목형 변수의 경우, 매우 신중하게 고유 카테고리의 영향도 및 분석 과정이 매우 중요!

  • 범주의 간소화 : 데이터탐색(EDA)과 도메인 전문지식을 활용하여 유사한 범주를 통합하고 빈도가 낮은 범주를 병합하는 접근법은 범주의 수를 효과적으로 줄일 수 있다. 이러한 방법은 단순히 모델의 복잡성을 감소시키는것을 넘어, 인코딩 기법 자체가 미치는 영향보다 더 큰 향상을 모델 성능에 가져올 수 있다.

  • 바이너리 인코딩 적용 : 간소화된 범주 구조를 가진 후에는 바이너리 인코딩 방식을 적용하는 것이 권장된다. 바이너리 인코딩은 다수의 범주를 가진 변수에 대해 원-핫 인코딩에 비해 더 메모리 효율적이며, 이진 수 조합을 통해 각 범주를 표현함으로써 생성되는 새로운 변수의 수를 최소화한다.

  • 고급 인코딩 기법 고려 : 타깃 인코딩과 같은 고급 인코딩 기법도 주목해야 한다. 이러한 기법은 종속변수(타깃)와의 관계를 기반으로 각 범주를 인코딩하는 인기있는 기법으로 자주 사용된다

profile
뭐가 됐든 데이터분석가

0개의 댓글