실제 데이터에는 "남성", "여성" 이나 "서울", "부산" 처럼 문자형(범주형) 데이터가 자주 존재합니다.
하지만 머신러닝 모델은 오직 숫자만 입력으로 처리할 수 있기 때문에, 범주형 데이터를 수치형으로 변환하는 과정이 필요합니다.
이를 인코드(Encoding)이라고 하며, 데이터 전처리에서 중요한 단계입니다.
왜 인코딩이 필요한가?
위에서 말했다 싶이 머신러닝 모델은 오직 숫자만 입력으로 처리할 수 있기 때문에 문자열을 직접 모델에 넣을 수가 없습니다.
예를 들어 gneder="남성"은 수치적 연산 불가한 셈입니다.
그리고 범주형 변수끼리는 크기 비교가 불가능합니다.
"서울" > "부산"을 같은 비교는 의미가 없습니다.
문제 상황 | 예시 |
문자열을 직접 모델에 넣을 수 없음 | gender = "남성"은 수치적 연산 불가 |
범주형 변수끼리의 크기 비교가 불가능 | "서울" > "부산" 같은 비교는 의미 없음 |
모델 입력으로 변환 필요 | XGBoost, LogisticRegression 등 모든 모델은 숫자형만 처리 가능 |
그럼 인코딩을 진행해야하는데 인코딩에는 세 가지 방식이 있습니다.
1. Label Encoding (레이블 인코딩)
- Label Encoding은 각 범주형 값을 고유한 정수로 매핑하는 방식입니다.
예를 들어 남성은 0, 여성은 1로 매핑을 할 수 있습니다.
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['gender_encoded'] = le.fit_transform(df['gender'])
- 장점
- 간단하고 메모리를 효율적으로 사용
- 단점
- 숫자의 크기/순서가 의미를 가짐 → 선형 모델에서는 "여성" > "남성" 으로 오해 가능
- 범주 간 순서가 없는 변수에는 적절하지 않음
2. One-Hot Encoding (원-핫 인코딩)
각 범주를 0과 1로만 이루어진 새로운 열로 분리하여 표현합니다.
도시 | 서울 | 부산 | 대구 |
서울 | 1 | 0 | 0 |
부산 | 0 | 1 | 0 |
대구 | 0 | 0 | 1 |
# pandas 방식
df_encoded = pd.get_dummies(df, columns=['city'])
# scikit-learn 방식
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder(sparse=False)
encoded = ohe.fit_transform(df[['city']])
- 장점
- 범주 간 순서 정보가 없을 때 적합
- 대부분의 모델에서 가장 안정적이고 널리 사용됨장
- 단점
- 열(column)이 급격히 많아질 수 있음
- 100개 카테고리 → 100개 열
- 차원의 저주 문제 가능성
- 열(column)이 급격히 많아질 수 있음
3. Ordinal Encoding (순서형 인코딩)
- 범주 간에 명확한 순서가 있는 경우, 그 순서를 반영하여 정수로 변환합니다.
예를들어 학력이라는 column이 있다고 한다면, 고졸은 0, 대졸은 1, 대학원 졸업은 2로 변화할 수 있습니다.
학력 | Ordinal Encoding |
고졸 | 0 |
대졸 | 1 |
대학원 졸업 | 2 |
from sklearn.preprocessing import OrdinalEncoder
encoder = OrdinalEncoder(categories=[['고졸', '대졸', '대학원 졸업']])
df['education_encoded'] = encoder.fit_transform(df[['education']])
- 장점
- 순서 정보를 반영할 수 있음
- 단점
- 순서가 없는데도 순서를 부여하면 모델이 잘못된 해석을 할 수 있음
인코딩 방식 | 대상 변수 유형 | 결과 형태 | 특징 / 주의점 |
Label Encoding | 명목형/순서형 둘 다 가능 | 단일 숫자열 | 순서 없는 변수에는 부적합 |
One-Hot Encoding | 명목형 (순서 없음) | 다중 열 (0/1) | 열이 많아질 수 있음 |
Ordinal Encoding | 순서형 (등급 등) | 단일 숫자열 (순서 유지) | 순서 지정 필수 |
이제 한번 실제 데이터를 활용해서 진행해보도록 하겠습니다.
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OrdinalEncoder
df = pd.read_csv('Titanic-Dataset.csv')
# 성별: Label Encoding
df['Sex_encoded'] = LabelEncoder().fit_transform(df['Sex'])
# 승선항구: One-Hot Encoding
df = pd.get_dummies(df, columns=['Embarked'], prefix='Port')
# 좌석 등급: Ordinal Encoding
df['Pclass_str'] = df['Pclass'].astype(str)
encoder = OrdinalEncoder(categories=[[1, 2, 3]]) # 오름차순 지정
df['Pclass_encoded'] = encoder.fit_transform(df[['Pclass']])
Titanic 데이터 셋은 전형적인 구조의 범주형 데이터를 포함하고 있습니다.
머신러닝 모델 학습 전에 반드시 수치형으로 변환해야 합니다.
1. 성별(Sex) - Label Encoding 사용이유
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['Sex_encoded'] = le.fit_transform(df['Sex'])
Sex는 male, female 두 가지 명목형(Nominal) 범주로 구성되어 있습니다.
One-Hot Encoding으로 해도 되지만, 이진(binary) 변수일 경우 LabelEncoding이 더 간단하고 메모리를 효율적으로 사용합니다.
다만, 모델이 숫자의 크기 관계를 오해할 수 있는 경우(ex: 선형 회귀)에는
이진 변수라도 One-Hot Encoding이 더 안전할 수 있습니다.
2. 승선 항구(Embarked) - One-Hot Encoding 사용 이유
df = pd.get_dummies(df, columns=['Embarked'], prefix='Port')
Embarked는 C, Q, S처럼 3개 이상의 명목형 범주를 가집니다.
이들 사이에는 순서 의미가 없습니다. (ex: S > Q 같은 관계 없음)
따라서 Label Encoding을 하면 모델이 잘못된 순서성을 오해할 가능성이 있습니다.
One-Hot Encoding을 통해 순서 없이 고유하게 구분
Embarked | Port_C | Port_Q | Port_S |
S | 0 | 0 | 1 |
C | 1 | 0 | 0 |
Q | 0 | 1 | 0 |
3. 좌석 등급(Pclass) - Ordinal Encoding 사용 이유
from sklearn.preprocessing import OrdinalEncoder
encoder = OrdinalEncoder(categories=[[1, 2, 3]]) # 1등석 > 2등석 > 3등석
df['Pclass_encoded'] = encoder.fit_transform(df[['Pclass']])
Pclass는 1등석, 2등석, 3등석처럼 명확한 순서가 존재합니다.
1등석 승객이 일반적으로 생존율이 높으며, 객실 등급이 모델 예측에 영향을 줄 수 있는 순서형 변수
순서를 보존하는 인코딩이 필요하므로 Label 또는 One-Hot보다 Ordinal Encoding이 가장 적절합니다.
Pclass (원본) | Pclass_encoded |
1 | 0.0 |
2 | 1.0 |
3 | 2.0 |
인코딩 방식 선택 기준 정리
컬럼 | 범주형 유형 | 순서 존재 | 인코딩 방식 | 이유 |
Sex | 명목형 | ❌ | Label Encoding | 2개 범주만 존재할 경우 간단함 |
Embarked | 명목형 | ❌ | One-Hot Encoding | 순서 없음 → 오해 방지 |
Pclass | 순서형 | ✅ | Ordinal Encoding | 등급 순서 유지 필요 |
- 명목형 + 3개 이상 카테고리 → 무조건 One-Hot
- 이진 변수 → 상황 따라 Label / One-Hot 선택
- 순서형 → 반드시 Ordinal Encoding으로 순서 보존
- 숫자형인데 순서 있는 척 하는 변수 조심! (zip code, user ID 등은 순서형 아님!)
Exception Handling: 주의할 점
- One-Hot Encoding 후 컬럼 폭증: 변수 선택 또는 PCA 적용 필요
- 테스트셋에 없는 범주 등장 시 오류: .fit()은 학습셋만, .transform()은 테스트셋에 사용
- Label Encoding만 적용하고 순서 정보 고려 안 하면 → 모델이 잘못된 추론 수행
정리
범주형 변수는 반두시 숫자로 변환해야 하며, 적절한 인코딩 방식을 선택하는 것이 중요합니다.
One-Hot은 범주 간 순서가 없을 때, Ordinal은 순서가 있을 때 사용하는 것이 좋습니다.
Label Encoding은 간단하지만 잘못 쓰면 모델에 심각한 오해를 유발할 수 있습니다.
참고자료
'Data Analysis' 카테고리의 다른 글
중심 극한 정리 (Central Limit Theorem, CLT) (0) | 2025.05.27 |
---|---|
파생변수 생성 - Feature Engineering (0) | 2025.05.19 |
정규화(Normalization) vs 표준화(Standardization) (0) | 2025.05.14 |
이상치(Outliers) 탐지와 처리 방법 (0) | 2025.05.14 |
결측치(Missing Values) 처리 (0) | 2025.05.12 |