순서형 범주형 변수 인코딩

CHOI CHOI·2024년 6월 7일
0

파이썬 중급

목록 보기
16/30

레이블 인코딩

Label Encoding은 범주형 변수의 각 범주(카테고리)에 고유한 정수를 할당함으로써, 기계 학습 모델이 이해할 수 있는 형태로 데이터를 변환하는 것을 의미

Label Encoding 방법 및 scikit-learn 라이브러리 활용하여 구현하기

Label Encoding은 범주형 변수의 각 범주(카테고리)에 고유한 정수를 할당함으로써, 기계 학습 모델이 이해할 수 있는 형태로 데이터를 변환하는 것을 의미합니다.

-> 이 과정은 scikit-learn라이브러리의 preprocessing모듈에 있는 labelencoder 클래스를 통해 쉽게 구현 가능

각 범주를 알파벳 순 또는 데이터에 처음 나타나는 순서에 따라 정렬한 후, 0부터 시작하는 연속적인 정수 값으로 변환합니다. 이때, 할당되는 정수의 범주의 총 개수에 따라 결정됩니다.

인코딩 예시

from sklearn.preprocessing import LabelEncoder
import numpy as np

categorical_var = ['Brand',  'Model', '정비 이력등급']

label_encoders = {}

for col in categorical_var:
    le_train = LabelEncoder()

    train_used_car[col] = le_train.fit_transform(train_used_car[col])
    label_encoders[col] = le_train
    
display(train_used_car.head())

# 인코딩을 어떻게 수행했는지 확인
for col in categorical_var:
    display(f"{col} :")
    for i in range(len(label_encoders[col].classes_)):
        display(f"{label_encoders[col].classes_[i]} ({i})")

코드설명

1.for cal in categorical_var: 'categorical_var'에 저장된 각 열 이름을 반복
2.le_train = LabelEncoder() 'sklearn.preprocessing'모듈의 'LabelEncoder'의 새로운 인스턴스를 생성, 'LabelEncoder'는 범주형 값을 숫자 값으로 변환하는데 사용
3.train_used_cal[col] = le_train.fit_transfrom(train_used_car[col]) fit_transform 메서드는 해당 열 col의 고유 값을 LabelEncoder에 학습시키고, 이러한 값을 정수로 변환
변환된 값은 train_used_car 데이터셋의 해당 열에 다시 할당
label_encoders[col] = le_train 이 줄은 학습된 'LabelEncoder'인스턴스를 'label_encoders'사전에 열 이름'col'을 키로 사용하여 저장

테스트 데이터에 적용하기

test_ex1 = test_used_car.copy()

for col in categorical_var:
    
    try :
        test_ex1[col] = label_encoders[col].transform(test_ex1[col])
    except Exception as e:
         print(f"label_encoders {col} Error: {e}")
        
    
display(test_ex1.head())
display(test_ex1[categorical_var].dtypes) 
  1. for col in categorical_var: 리스트에 저장된 각 열 이름을 반복한다.
  2. try:
    test_ex1[col] = label_encoders[col].transform(test_ex1[col])
    except Exception as e:
    print(f"label_encoders {col} Error: {e}")
  • try 블록 내에서, label_encoders 사전에 저장된 LabelEncoder를 사용하여 test_ex1의 각 범주형 열을 변환합니다.
    • label_encoders[col].transform(test_ex1[col])는 train_used_car 데이터셋을 변환할 때 사용된 동일한 LabelEncoder를 사용하여 test_ex1[col]의 값을 변환합니다.
    • 변환된 값은 다시 test_ex1 데이터프레임의 해당 열에 저장됩니다.
  • 만약 예외가 발생하면, except 블록이 실행되어 오류 메시지를 출력합니다. 예외가 발생하면 transform 메서드가 실패했음을 의미합니다.

Label Encoding 적용시의 문제점 및 주의 사항

  • Label Encoding을 명목형 변수에 적용시 문제점
    'Brand'나 'Model'과 같은 명목형 변수는 고유 범주값에 순서나 등급에 의미가 없다. 이들에게 임의의 숫자를 할달하는 라벨 인코딩은 실제로 데이터에 없는 정보, 즉 숫자 간의 순서나 중요도를 부여하는 문제를 일으킬 수 있다. 예를 들어 'Ford'가 0,'Honda'가 1, 'Toyota'가 2로 인코딩이 되면 모델은 숫자에 따라 'Toyota'보다 'Honda'가 더 중요하거나 더 큰 것으로 잘못 해석할 수 있다.

  • Label Encoding을 순서형 변수에 적용할 때 문제점
    더 중요한것은 '정비 이력등급'과 같은 순서형 변수의 처리입니다. 만일 도메인 관점에서, '정비 이력등급'에 차에 대한 관리 수준 혹은 관리 등급 의미를 담아 수동으로 인코딩을 한다면, '없음' : 0, '보통' : 1, '정기적' :2의 순서일 것입니다. 하지만 scikit-learn의 LabelEncoder()를 사용하면,LabelEncoder의 인코딩 메카니즘에 기안하여 '보통' : 0, '없음':1, '정기적':2 으로 인코딩 되어버려 결과적으로 '없음'이 '보통'보다 높은 등급을 의미하는 것처럼 잘못 해석할 수 있다.

순서형 범주형 변수답게 인코딩 하기

Direct Mapping 통한 인코딩

train_ex2 = train_income.copy()
education_map = {'Preschool' : 0, 
                 '1st-4th' : 1, 
                 '5th-6th' : 2, 
                 '7th-8th' : 3,
                 '9th' : 4,
                 '10th' : 5,
                 '11th' : 6, 
                 '12th': 7, 
                 'HS-grad' : 8,
                 'Some-college' : 9,
                 'Assoc-voc' : 10,
                 'Assoc-acdm' : 11,
                 'Bachelors' : 12,
                 'Masters' : 13,
                 'Prof-school' : 14,
                 'Doctorate': 15 } 

train_ex2['education'] = train_ex2['education'].replace(education_map)
display(train_ex2.head())
display(train_ex2['education'].dtype)
display(train_ex2['education'].unique())

직접적으로 하나하나 맵핑을 해주는 방법!

Ordinary Encoder를 활용한 인코딩

scikit-learn 의 OrdinalEncoder를 사용

from sklearn.preprocessing import OrdinalEncoder

train_ex3 = train_income.copy()

# OrdinalEncoder 초기화 및 범주 순서 지정
encoder_train = OrdinalEncoder(categories=[['Preschool', '1st-4th', '5th-6th', '7th-8th', '9th', '10th', '11th', '12th', 
     'HS-grad', 'Some-college', 'Assoc-voc', 'Assoc-acdm', 'Bachelors', 'Masters', 
     'Prof-school', 'Doctorate']])

# 'education' 컬럼에 OrdinalEncoder 적용
train_ex3['education'] = encoder_train.fit_transform(train_ex3[['education']]).astype(int)

# 인코딩 순서 확인하기
display(encoder_train.categories_)

# 인코딩된 결과 확인
display(train_ex3.head())
display(train_ex3['education'].dtype)
display(train_ex3['education'].unique())
profile
뭐가 됐든 데이터분석가

0개의 댓글