딥러닝의 범주형 변수 설계: 미지 카테고리 할당처를 학습시키는 방법
요약
본 기사는 표 형식 데이터의 회귀/분류 모델에서 범주형 변수를 처리하는 방법을 다룹니다. 특히 저빈도 카테고리와 미지 카테고리를 동일한 `__OTHER__`로 통합하여 학습에 사용하는 설계 방식을 제시합니다. One-Hot Encoding과 Embedding 중 어떤 것을 선택할지는 특징량의 특성과 크기에 따라 결정해야 합니다.
핵심 포인트
- 저빈도/미지 카테고리는 `__OTHER__`로 통합하는 것이 효과적입니다.
- One-Hot은 적은 어휘 수에, Embedding은 많은 어휘 수에 유리합니다.
- 국가 코드처럼 순서가 없는 명목형 변수에는 One-Hot 또는 Embedding을 사용해야 합니다.
- 결측값과 저빈도 카테고리는 성질이 다르므로 별도로 검증해야 합니다.
서론
범주형 변수를 신경망에 입력할 때는 One-Hot Encoding과 Embedding 중 어떤 것을 선택할지 결정하는 것 외에도, 추론 시 처음 나타나는 값(미지값)을 어떻게 처리할지 결정해야 합니다. 이후부터는 One-Hot Encoding을 One-Hot으로 표기하겠습니다.
handle_unknown="ignore"
설정을 하면 미지 카테고리로 인해 변환 처리가 멈추는 것은 피할 수 있습니다. 하지만 그 입력에 대해 모델이 어떻게 예측할지는 별개의 문제입니다.
본 기사에서는 표 형식 데이터의 회귀/분류 모델을 대상으로, 저빈도 카테고리와 미지 카테고리를 동일한 __OTHER__로 할당하고, 이 표현을 학습 때부터 사용하는 설계를 정리합니다. 카테고리 수가 적은 특징량에는 One-Hot을, 입력 차원이 커지는 특징량에는 Embedding을 비교 후보로 삼겠습니다.
대상 독자는 MLP 등의 범주형 특징량을 설계하는 분들입니다. 공식 API의 사양을 확인하고 작은 데이터로 변환 결과를 검증해야 합니다. 모델의 정확도 비교는 수행하지 않았으므로, 채택 방침은 실제 데이터에서의 평가가 필요한 설계 후보로 제시합니다.
저빈도・미지・결측값의 차이점
다음 세 가지는 발생 시점과 의미가 다릅니다.
| 상태 | 의미 | 본 기사에서의 처리 |
|---|---|---|
| 저빈도 카테고리 | 학습 데이터에 있지만, 출현 건수가 적은 값 | __OTHER__로 집약할 후보 |
| 미지 카테고리 | 학습 시의 어휘(vocabulary)에 없는 값 | __OTHER__에 할당 |
| 결측값 (Missing) | 값 자체가 존재하지 않음 | 학습 데이터에 있다면 __MISSING__으로 분리 |
여기서 말하는 어휘는 학습 데이터로부터 확정된 카테고리의 집합입니다. 저빈도 판정 기준 역시 학습 데이터에서 정하고, 검증 및 추론 시에는 동일한 규칙을 사용합니다.
학습 시 결측값이 없었던 경우, 추론 시의 결측값을 __OTHER__에 할당하는 설계도 생각해 볼 수 있습니다. 다만, __OTHER__에 할당된 학습 샘플이 존재한다는 것이 전제입니다. 결측값과 저빈도 카테고리의 성질이 반드시 가깝다고 할 수는 없으므로, 이는 잠정적인 처리로 검증합니다.
One-Hot과 Embedding을 어떻게 선택할까
명목형 카테고리(Nominal Category)의 수치 입력과 Embedding의 인덱스를 구분하기
국가 코드를 JP → 0, US → 1, FR → 2와 같이 변환하여 수치 특징량으로 입력하면, 모델에는 수치로서의 순서와 거리가 부여됩니다. 국가 코드의 의미에 그 관계가 없다면 불필요한 가정을 도입하게 됩니다.
One-Hot을 사용하면 카테고리별로 다른 열을 사용할 수 있습니다.
JP → [1, 0, 0]
US → [0, 1, 0]
FR → [0, 0, 1]
정수 ID를 Embedding 테이블의 행 번호로 사용하는 경우는 각 ID에 대응하는 학습 가능한 벡터를 추출합니다. 이는 ID의 크기 관계를 수치 특징량으로 입력하는 방법과는 다릅니다. PyTorch의 nn.Embedding은 이러한 참조를 수행하는 레이어입니다. 공식 구현과 API 설명을 통해 입력/가중치의 형태를 확인할 수 있습니다.
참고로, 실제로 순서가 있는 카테고리에서는 순서를 반영한 수치 표현도 후보가 될 수 있습니다. 본 기사의 대상은 주로 명목형 카테고리입니다.
비교하는 것은 카테고리 수만은 아니다
| 관점 | One-Hot | Embedding |
|---|---|---|
| 1특징량의 출력 차원 | 어휘 수 K | 지정한 차원 d |
| 표현 학습 | 후단 레이어에서 학습 | 테이블과 후단 레이어에서 학습 |
| 초기 후보 | 어휘 수가 적고, 입력 차원을 관리하기 쉬운 경우 | 어휘 수가 많고, 밀집된 입력을 작게 하고 싶은 경우 |
| 미지값 대응 | 할당할 열을 결정함 | 할당할 ID를 결정함 |
Entity Embedding은 카테고리를 예측 태스크와 함께 학습하는 벡터로 변환하는 기법입니다. Guo・Berkhahn의 논문에서는 표 형식 데이터에 대한 적용 사례가 제시되었습니다. 논문의 결과만으로 모든 데이터에서 One-Hot보다 우월하다고 할 수는 없습니다.
본 기사에서는
Embedding은 1개 샘플의 출력이 64차원이라 하더라도, 테이블에는 640만 개의 파라미터를 가집니다. float32 가중치만으로 약 25.6 MB이며, 기울기(gradient)나 최적화 알고리즘 상태를 저장하는 메모리는 별도로 필요합니다.
One-Hot을 희소 행렬(sparse matrix)로 유지할 경우, 비제로 요소와 그 위치를 저장하므로, 샘플당 10만 요소의 밀집 배열(dense array)을 저장할 필요는 없습니다. 밀집된 완전 연결층(fully connected layer)에 연결하는 경우에는 해당 층의 파라미터 수도 확인해야 합니다.
One-Hot에 바이어스 없는 선형 변환을 적용하는 연산은 대응하는 가중치 벡터를 가져오는 Embedding과 동일하게 작성할 수 있습니다. Embedding에서는 참조 방법과 출력 차원을 설계할 수 있으며, 파라미터 수는 어휘 크기(vocabulary size)와 출력 차원의 곱으로 결정됩니다.
미지 카테고리 할당처 학습시키기
모든 제로 입력이 의미하는 것
OneHotEncoder(handle_unknown="ignore")는 미지 카테고리에 대해 해당 특징의 출력을 모두 0으로 만듭니다. 이는 scikit-learn 공식 사양에 명시되어 있습니다.
drop=None으로, 학습 시 반드시 한 열이 1이었던 경우, 모든 제로는 학습 시 나타나지 않은 패턴입니다. 모든 제로 상태에서도 모델은 바이어스나 다른 특징으로부터 예측할 수 있습니다. 따라서 미지 카테고리를 모두 제로로 만든 경우의 예측 성능을 검증합니다.
__OTHER__에 통합하기
저빈도(low-frequency) 카테고리를 예를 들어, 출현 횟수가 다음과 같은 특징을 가진다고 가정해 봅시다.
| 값 | 학습 데이터 건수 | 변환처 |
|---|---|---|
| A | 5,000 | A |
| ... | ||
추론 시 새로운 값 G가 나타나더라도, 동일한 __OTHER__에 할당합니다. 미지값은 D・E・F의 학습에서 사용된 표현을 공유합니다. |
학습 시: D / E / F ─┐
├→ __OTHER__ → One-Hot 전용 열 / Embedding 전용 행
추론 시: G / H ─────┘
다만, D・E・F의 합계 14건으로 충분히 학습할 수 있는지, G가 가진 특성을 대표할 수 있는지는 별도로 평가가 필요합니다. 할당처를 학습에 사용하는 것과 미지값에 대해 고정밀도가 되는 것은 동의어가 아닙니다.
저빈도 카테고리가 없는 경우
__OTHER__를 어휘(vocabulary)에 추가하는 것만으로는 해당 상태에 대응하는 예측을 학습할 수 없습니다. Embedding에서도 행이 존재한다는 것과 그 행이 예측 손실(prediction loss)을 통해 학습된다는 것은 다릅니다.
이 경우, 미지값의 처리를 별도로 결정합니다. 예를 들어, 알려진 카테고리를 학습 시 일정 확률로 __OTHER__에 대체하고, 다른 특징으로부터 예측하는 훈련을 수행하는 방법이 고려될 수 있습니다. 대체율은 검증에서 선택하며, 알려진 카테고리의 성능 저하도 확인해야 합니다. 이는 추가적인 실험 후보이며, 개선이 보장되지는 않습니다.
또한, 가질 수 있는 값이 사양으로 제한되어 있고 미지값이 데이터 불일치를 의미하는 경우에는 오류나 입력 검사(input validation)에서 감지하는 설계가 적절합니다.
구현: 학습 데이터로부터 어휘 고정하기
여기서는 하나의 문자열 카테고리 특징을 다룹니다. 결측값은 None으로 하고, NaN이나 공백 문자열의 정규화는 상위 단계에서 수행하는 것을 전제로 합니다. 내부 토큰은 원본 데이터와 충돌하지 않도록 구현에서는 예약어를 입력 검사로 거부합니다.
먼저 데이터를 학습/검증으로 분할하고, 학습 데이터에서 출현 횟수를 집계하여 어휘를 확정하고 인코더를 학습시킵니다. 교차 검증(cross-validation)에서도 분할마다 학습 측 데이터로 다시 만듭니다. 목적 변수(target variable)를 사용하지 않는 변환이라도, 검증 측을 포함한 fit은 평가 조건을 바꿉니다. scikit-learn의 전처리 관련 주의점도 참조하십시오.
카테고리 정규화 및 저빈도 판별
아래 코드는 Python, NumPy, scikit-learn을 사용합니다. sparse_output을 사용하므로, scikit-learn 1.2 이상을 전제로 합니다.
본 기사의 코드는 Python 3.11.11, NumPy 2.3.1, scikit-learn 1.8.0, PyTorch 2.7.1로 실행 확인했습니다. 최소 버전에서의 실행 확인은 진행하지 않았습니다.
from collections import Counter
from dataclasses import dataclass
import numpy as np
...
여기서는 카테고리 변환 처리가 모든 값을 고정 어휘에 할당하기 때문에, 인코더는 handle_unknown="error"로 설정했습니다. 이는 전처리 불일치를 감지하기 위한 선택입니다. 운영상 ignore
계속 진행한다면, 예상치 못한 전(全) 제로 입력을 모니터링합니다.
sparse_output=False
은 작은 예시 표시용입니다. 다수의 카테고리에 적용할 경우에는, 밀집 배열의 메모리와 후단 모델이 수신 가능한 형식을 확인해야 합니다.
변환 결과
출력은 다음과 같습니다.
['A', 'B', '__OTHER__', '__MISSING__']
['A', '__OTHER__', '__MISSING__', '__OTHER__']
[[1. 0. 0. 0.]
...
미지의 NEW
와 저빈도(rare_1)는 같은 열에 할당됩니다. 결측은 학습 시 존재했기 때문에 별도의 열입니다.
결측이 없는 학습 데이터라도, 저빈도 카테고리가 있다면 추론 시의 결측을 __OTHER__
에 할당합니다.
schema_no_missing = fit_schema(["A", "A", "rare"], min_count=2)
print(schema_no_missing.transform([None, "NEW"]))
# ['__OTHER__', '__OTHER__']
한편, fit_schema(["A", "A", "B", "B"], min_count=2)
은 예외가 됩니다. 이 구현에서는, __OTHER__
에 할당할 학습 샘플이 없는 경우 예외를 발생시킵니다.
scikit-learn의 내장 집계 사용 선택지
결측의 독립적인 관리가 필요하지 않다면, 내장 기능도 후보입니다.
auto_encoder = OneHotEncoder(
min_frequency=2,
handle_unknown="infrequent_if_exist",
...
다만, 저빈도 카테고리 그룹이 fit
시에 만들어지지 않으면, 미지값은 전(全) 제로가 됩니다. 이 조건은 OneHotEncoder의 사양에 명시되어 있습니다. 결측을 출현 빈도와 관계없이 독립적인 카테고리로 만들려면, 전단 카테고리 변환 처리에서 제어해야 합니다.
같은 어휘를 Embedding에 사용하기
어휘를 ID로 변환하면, 같은 방침을 Embedding에 적용할 수 있습니다. 다음 코드는 앞서의 schema
와 mapped
에 이어서 실행합니다.
import torch
from torch import nn
vocabulary = list(schema.vocabulary)
...
이 코드는 ID와 형태 확인까지만입니다. 표현을 학습시키려면, 후단 네트워크에 연결하고 목적 변수에 대한 손실로 최적화해야 합니다.
__OTHER__
는 예측에 사용할 학습 가능한 행으로 취급합니다. PyTorch의 padding_idx
는 보통 지정된 행에 대한 기울기 업데이트를 억제하므로, __OTHER__
를 학습시킬 경우에는 그 ID를 지정하지 않습니다. Embedding 설명을 참조하십시오.
회귀・분류 모두 입력 측 설계는 공통화할 수 있습니다. 출력층과 손실함수는 태스크에 따라 선택합니다.
고찰: 설계의 효과와 한계
할당처 학습만으로는 미지값의 성질을 파악할 수 없다
변환 예시에서 확인할 수 있는 것은, 미지값이 고정된 학습 시의 표현에 할당된다는 것입니다. 신상품이 저빈도 상품의 평균적인 성질에 가까운지는 알 수 없습니다.
본 기사의 설계에서는, 미지의 ID는 모두 __OTHER__
과 같은 표현이 됩니다. 상품이라면 브랜드, 카테고리, 가격 등 추론 시에도 취득할 수 있는 속성을 병용하는 방법이, 신규 ID에 학습된 표현이 없는 콜드 스타트(cold start)에 대한 대책 후보입니다. 그 유효성은, 신상품을 포함한 검증 데이터로 평가합니다.
개수 임계값은 검증 조건과 함께 결정해야 한다
예시의 min_count=2
는 동작 설명용입니다. 임계값을 크게 하면 어휘를 줄일 수 있지만, 소수 카테고리 고유 정보도 손실합니다. 업무상 중요한 카테고리를 개별적으로 남기는 설계도 고려할 수 있습니다.
전체 지표 외에, 기지(既知)・저빈도・미지・결측별 건수와 지표를 비교합니다. 신규 ID가 문제라면 ID 단위의 분할, 미래 카테고리 추가가 문제라면 시간 경과에 따른 분할 등, 추론 조건에 가까운 평가를 수행합니다. 검증 결과로 임계값을 선택한 후에는, 독립적인 테스트 데이터에서 최종 확인을 합니다.
Target Encoding은 다른 비교 후보
One-Hot은 목적 변수를 사용하지 않고, Embedding은 모델의 학습을 통해 목적 변수에 따른 표현을 획득합니다. Target Encoding은 카테고리별 목적 변수의 통계량을 전처리 과정에서 특징량으로 변환하기 때문에, 정보 유출(information leakage)을 방지하는 설계가 별도로 필요합니다.
학습/검증 분리 외에도, 학습 행(row) 자체의 목적 변수가 그 행의 특징량에 포함되지 않도록 교차 적합(cross fitting) 등을 고려해야 합니다. scikit-learn의 TargetEncoder는 학습 데이터에 대한 fit_transform을 통해 교차 적합을 수행하므로, fit(...).transform(...)과는 처리 방식이 다릅니다. 공식 API를 참조하십시오.
시계열(time series)이나 그룹 제약이 있는 데이터에서는 분할 방법 또한 평가 조건과 일치시켜야 합니다. Target Encoding을 무조건 제외할 필요는 없지만, 본 기사의 초기 설계와는 별개로 비교합니다.
운영 환경에서는 전처리 과정도 모델과 함께 저장해야 함
어휘의 순서가 바뀌면, 동일한 One-Hot 열이나 Embedding의 행이 다른 카테고리를 의미하게 됩니다. 학습 시 확정된 다음 정보를 모델과 함께 저장하고 추론 시 재사용합니다.
- 정규화 규칙, 저빈도 판별 기준, 결측치 처리 방식
- 어휘 및 그 순서, 카테고리에서 ID로의 대응 관계
- 학습된 인코더와 모델 가중치(weights)
- 전처리/모델 버전과 사용 라이브러리 버전
미지값(unknown)과 저빈도값은 변환 후에는 구별할 수 없습니다. 모니터링용으로는, 학습 시 관측한 원본 카테고리의 집합도 저장하여, 변환 전에 미지율/결측률을 기록해야 합니다. 변환 후의 __OTHER__ 비율과는 별개로 보는 것이 신규 카테고리 증가와 결측치 증가를 구분하기 쉽습니다.
__OTHER__ 비율의 증가만으로는 원인을 단정할 수 없습니다. 신상품 추가, 입력 표기 변경, 어휘 업데이트 누락 등을 조사하는 계기로 사용합니다.
요약
카테고리 변수 설계에서는 One-Hot과 Embedding 중 무엇을 선택할지 외에도, 미지값과 결측치를 어떤 학습 시 표현에 할당할지를 결정해야 합니다.
저빈도 카테고리를 __OTHER__로 묶고, 미지 카테고리에도 같은 표현을 사용하는 방법은 초기 설계의 후보가 될 수 있습니다. 다만, 할당 대상에 학습 샘플이 존재한다는 점과, 그 샘플이 미래의 미지값을 대표할 수 있다는 점을 분리하여 확인해야 합니다.
어휘와 전처리 과정을 고정하고, 미지/저빈도/결측 조건별로 평가함으로써 변환 처리와 예측 성능 양쪽을 검증할 수 있습니다.
참고 정보
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn ML의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기