들어가며
대부분 데이터를 다룬다고 하면 대부분 수치형 데이터를 생각할 것이다
하지만 실제 상황에서 데이터를 마주하게된다면 문자로된 데이터도 꽤나 마주하게 될 것이다
오늘은 이 텍스트 특성을 어떻게 처리하는 지 알아볼 것이다
텍스트 특성 다루기
우선 텍스트로된 특성을 한 번 보면 아래와 같다
housing_cat = housing[["ocean_proximity"]]
housing_cat.head(8)

이 예시는 텍스트 형태를 가진 범주형 특성이라고 보면된다
텍스트 특성을 처리하려면 대부분 머신러닝 알고리즘은 숫자를 다루기에
텍스트로된 데이터를 숫자로 변환해주어한다
이 과정을 사이킷런의 OrdinalEncoder 클래스가 제공해준다
from sklearn.preprocessing import OrdinalEncoder
ordinal_encoder = OrdinalEncoder()
housing_cat_encoded = ordinal_encoder.fit_transform(housing_cat)
이런식으로 객체를 생성 후 학습,변환한다
housing_cat_encoded[:8]
결과를 확인해보면
array([[3.],
[0.],
[1.],
[1.],
[4.],
[1.],
[0.],
[3.]])
이런식으로 인코딩된 것을 확인할 수 있다
categories_ 변수를 활용해 카테고리 리스트를 얻을 수 있다
ordinal_encoder.categories_
[array(['<1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'],
dtype=object)]
하지만 이 방식이 문제가 될 수 있는 부분은
알고리즘이 가까이 있는 두 값을 비슷하다고 생각한다는 점이다
예를 들어 0과1(<1H OCEAN과 INLAND)이 0과4(<1H OCEAN과 NEAR OCEAN)보다 비슷하다고 생각한다는 것이다
원-핫 인코딩
이 문제를 해결할 방법은 원-핫 인코딩을 사용하는 것이다
원-핫 인코딩은 쉽게 말해서 해당되는 한 값만 1로두고 나머지는 0으로 두어 구분하는 것이다
사이킷런의 OneHotEncoder 클래스에서 원-핫 인코딩을 활용할 수 있다
from sklearn.preprocessing import OneHotEncoder
cat_encoder = OneHotEncoder()
housing_cat_1hot = cat_encoder.fit_transform(housing_cat)
OneHotEncoder는 데이터를 넘파이 배열이 아닌 사이파이 희소 행렬로 출력한다
희소행렬은 내부적으로 0이 아닌 값과 그 위치만 저장하기에
0이 대부분인 행렬을 매우 효율적으로 표현하여 메모리를 절약하고 게산 속도를 높여준다
시각적으로 보기 편하도록 넘파이 배열로 바꾸려면 toarray()를 호출하면 된다
또는 OneHotEncoder 객체를 만들 때 sparse=False로 설정하면 넘파이 배열로 나오게된다
cat_encoder = OneHotEncoder(sparse_output=False)
housing_cat_1hot = cat_encoder.fit_transform(housing_cat)
housing_cat_1hot
array([[0., 0., 0., 1., 0.],
[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
...,
[0., 0., 0., 0., 1.],
[1., 0., 0., 0., 0.],
[0., 0., 0., 0., 1.]])
하지만 이 경우 희소행렬의 장점이 사라지기에 효율은 떨어진다
판다스에서는 get_dummies() 함수를 사용하여 원-핫 인코딩을 사용할 수 있도록 해준다
df_test = pd.DataFrame({"ocean_proximity": ["INLAND", "NEAR BAY"]})
pd.get_dummies(df_test)

OneHotEncoder vs get_dummies()
OneHotEncoder와 get_dummies()의 차이에 대해 알아볼 것이다
우선 OneHotEncoder는 어떤 카테고리로 훈련되었는지 기억한다는 특징이 있다
cat_encoder.transform(df_test)
array([[0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0.]])
위에서 만들어진 df_test를 OneHotEncoder의 객체인 cat_encoder에 적용했을 때
그 전에 학습했던 5개의 카테고리를 기억하여 5개의 열로 나타난 것을 알 수 있다
반면 get_dummies()는 순간 입력받은 데이터만 보고 열을 만들기에 2개만 만들어진다
또한 알 수 없는 카테고리를 get_dummies()에 주입 시 아무런 문제 없이 결과를 출력한다
df_test_unknown = pd.DataFrame({"ocean_proximity": ["<2H OCEAN", "ISLAND"]})
pd.get_dummies(df_test_unknown)

하지만 OneHotEncoder는 데이터를 기억하기 때문에 알 수 없는 데이터를 감지하고 예외를 발생시킨다
handle_unknown 매개변수를 "ignore"로 지정하면 알 수 없는 카테고리를 0으로 나타낼 수도 있다
cat_encoder.handle_unknown = "ignore"
cat_encoder.transform(df_test_unknown)
array([[0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0.]])
마치며
이번 글에서는 텍스트 특성을 다루는 방법에 대하여 알아보았다
그 방법은 텍스트를 숫자로 표현하면 되는 것이었다
get_dummies()와 OneHotEncoder의 차이를 보면 무조건 OneHotEncoder가 좋아보이지만
간단한 구현력과 데이터프레임 출력 형태 면에서 get_dummies()의 장점도 분명히 있어보여
상황에 맞춰 잘 선택해야될 것 같다고 생각했다
'AI > Machine Learning' 카테고리의 다른 글
| [AI] 방사 기저 함수(RBF)를 통한 유사도 측정으로 멀티모달 분포(multimodal distribution) 변환 (1) | 2026.02.08 |
|---|---|
| [AI] 특성 스케일링(정규화, 표준화) (0) | 2026.02.07 |
| [AI] 데이터 정제하기 (0) | 2026.02.04 |
| [AI] 테스트 세트 만들기 (0) | 2026.02.03 |
| [AI] 홀드아웃 검증(holdout validation), 교차 검증(cross-validation) (0) | 2026.01.21 |
