원핫인코딩은 범주형 데이터를 머신러닝 모델이 처리할 수 있도록 0과 1로 이루어진 여러 개의 컬럼으로 변환하는 방법이다.
예를 들어 pclass에 값이 1, 2, 3 세 종류라면:
pclass
1
2
3
원핫인코딩 후:
pclass_1 pclass_2 pclass_3
1 0 0
0 1 0
0 0 1
처럼 변환된다.
즉 행의 개수는 그대로 유지되고, 카테고리 종류만큼 열의 개수가 증가할 수 있다.
인코딩 전 : (712, 1)
인코딩 후 : (712, 3)
⠀
1. 인코딩할 컬럼 분리
cols_encoding = ["pclass", "sex", "embarked", "sibsp", "parch"]
tmp_tr = train[cols_encoding]
tmp_te = test[cols_encoding]
tmp_tr, tmp_te에는 원핫인코딩할 컬럼만 따로 저장한다.
반대로 age, fare처럼 인코딩하지 않고 그대로 사용할 컬럼은 별도로 저장한다.
⠀
cols = ["age", "fare"]
features_tr = train[cols]
features_te = test[cols]
정리하면:
features_tr, features_te
→ 인코딩하지 않을 컬럼
tmp_tr, tmp_te
→ 인코딩할 컬럼
⠀
2. OneHotEncoder 생성
encoder = ce.OneHotEncoder(use_cat_names=True)
use_cat_names=True를 사용하면 인코딩 후 컬럼 이름에 실제 카테고리 값이 포함되어 결과를 확인하기 쉽다.
예:
pclass_1.0
pclass_2.0
pclass_3.0
⠀
3. 인코딩 결과를 담을 빈 DataFrame 생성
enco_tr = pd.DataFrame()
enco_te = pd.DataFrame()
처음에는 아무 데이터도 없기 때문에:
enco_tr.shape
# (0, 0)
이다.
이후 각 컬럼을 인코딩한 결과를 enco_tr, enco_te에 계속 추가한다.
⠀
4. 컬럼을 하나씩 인코딩
for col in tmp_tr.columns:
tmp_tr의 컬럼을 하나씩 col에 넣으며 반복한다.
예:
1회차 → pclass
2회차 → sex
3회차 → embarked
4회차 → sibsp
5회차 → parch
따라서:
tmp_tr[col]
은 반복할 때마다 현재 처리 중인 컬럼을 의미한다.
⠀
5. astype('category')
tmp_tr[col].astype('category')
astype()은 데이터 타입을 변경하는 함수이다.
현재 처리 중인 컬럼 전체를 category 타입으로 변환
category 타입인 값만 선택하는 것이 아니라, 해당 컬럼 전체의 타입을 바꾸는 것이다.
⠀
6. Train 데이터는 fit_transform()
_enco = encoder.fit_transform(
tmp_tr[col].astype('category')
)
fit_transform()은 두 작업을 동시에 수행한다.
fit
→ 어떤 카테고리가 존재하는지 학습
transform
→ 학습한 규칙으로 실제 데이터를 변환
예를 들어 pclass에 1, 2, 3이 있다면 이를 학습한 후:
pclass_1
pclass_2
pclass_3
세 개의 컬럼으로 변환한다.
⠀
7. 인코딩 결과를 기존 결과에 추가
enco_tr = pd.concat([enco_tr, _enco], axis=1)
axis=1은 컬럼 방향으로 옆에 붙인다는 의미이다.
처음에는:
enco_tr → (0, 0)
_enco → (712, 3)
이므로 합친 후:
enco_tr → (712, 3)
이 된다.
다음 컬럼을 인코딩하면 기존 enco_tr 뒤에 새로운 컬럼이 계속 추가된다.
기존 enco_tr → (712, 3)
새로운 _enco → (712, 2)
결과 enco_tr → (712, 5)
⠀
8. Test 데이터는 transform()만 사용
_enco = encoder.transform(
tmp_te[col].astype('category')
)
Test 데이터에는 fit_transform()을 사용하지 않는다.
Train 데이터에서 이미 인코딩 규칙을 학습했기 때문에, Test 데이터는 Train에서 학습한 규칙 그대로 변환만 해야 한다.
Train
fit_transform()
→ 규칙 학습 + 변환
Test
transform()
→ Train에서 배운 규칙으로 변환
머신러닝에서는 Test 데이터를 이용해 새로운 규칙을 학습하지 않는 것이 중요하다.
❗데이터 누수
만약 Test 데이터에도 fit() 또는 fit_transform()을 사용하면, Test 데이터의 정보를 이용해 새로운 규칙을 학습하게 된다.
이렇게 Test 데이터의 정보가 학습 과정에 섞이는 현상을 데이터 누수(Data Leakage)라고 한다.
데이터 누수가 발생하면 모델의 성능이 실제보다 좋게 평가될 수 있고, 새로운 데이터에서는 성능이 떨어질 수 있다. = 과대적합
⠀
9. Test 인코딩 결과 누적
enco_te = pd.concat([enco_te, _enco], axis=1)
Train과 마찬가지로 Test의 인코딩 결과도 오른쪽으로 계속 붙인다.
최종적으로 예를 들어:
enco_tr → (712, 22)
enco_te → (179, 22)
처럼 만들어질 수 있다.
Train과 Test의 행 개수가 다른 이유는 처음부터 데이터를:
Train → 712개
Test → 179개
로 나눴기 때문이다.
인코딩 때문에 행 개수가 줄어든 것은 아니다.
⠀
10. 인덱스 초기화
features_tr = features_tr.reset_index(drop=True)
features_te = features_te.reset_index(drop=True)
enco_tr = enco_tr.reset_index(drop=True)
enco_te = enco_te.reset_index(drop=True)
reset_index(drop=True)는 행 순서는 그대로 유지하면서 인덱스를 0부터 다시 부여하는 것이다.
예:
기존 인덱스
331, 733, 382, 704 ...
↓
reset_index(drop=True)
0, 1, 2, 3 ...
나중에 features_tr과 enco_tr을 concat()할 때 인덱스가 서로 맞도록 하기 위해 사용한다.
⠀
11. 인코딩하지 않은 데이터와 다시 합치기
df_tr = pd.concat([features_tr, enco_tr], axis=1)
df_te = pd.concat([features_te, enco_te], axis=1)
예를 들어:
features_tr → (712, 2)
enco_tr → (712, 22)
이면 최종 결과는:
df_tr → (712, 24)
가 된다.
행은 그대로 712개이고, 컬럼은 2 + 22 = 24개가 된다.
⠀
전체 흐름
원본 Train / Test
↓
인코딩할 컬럼과 하지 않을 컬럼 분리
↓
Train의 각 컬럼을 category 타입으로 변경
↓
fit_transform()
↓
인코딩 결과를 enco_tr에 누적
↓
Test는 Train에서 학습한 규칙으로 transform()
↓
인코딩 결과를 enco_te에 누적
↓
인덱스 초기화
↓
기존 수치형 데이터와 인코딩 결과 concat
↓
최종 학습용 데이터 생성
⠀
'개발 공부 > 머신러닝' 카테고리의 다른 글
| [Machine Learning] 데이터 스케일링 | StandardScaler, MinMaxScaler (1) | 2026.09.05 |
|---|---|
| [Machine Learning] One-Hot Encoding 정리 | Train/Test 전처리 (2) | 2026.09.05 |
| [Machine Learning] 인공지능·머신러닝·딥러닝과 학습 종류 정리 (0) | 2026.09.03 |
| [Machine Learning] 데이터 누수란? (0) | 2026.09.03 |
| [Machine Learning] 범주형 데이터 인코딩과 학습·테스트 전처리 (0) | 2026.09.03 |