[kakao x goorm] 생성 AI 응용 서비스 개발자 양성 과정/회고록

[kakao x goorm] 텍스트 정제와 단어 임베딩, BoW부터 Word2Vec까지

Hoonia 2025. 5. 16. 14:03

자연어처리(NLP)에서 문장을 형태소 단위로 나누는 것만으로는 충분하지 않다. 텍스트는 기계가 이해하기 어려운 특성과 노이즈를 가진 데이터다. 따라서 형태소 분석 이후에는 불필요한 정보를 제거하고 의미 있는 정보만을 남기는 정제 작업, 그리고 이를 수치화하는 임베딩 작업이 뒤따라야 한다.

이번 포스팅에서는 BoW 방식부터 Word2Vec까지, 자연어를 모델에 입력하기 위한 대표적인 변환 기법을 정리했다.

텍스트 정제(Cleaning)의 역할

형태소 분석을 마친 문장도 여전히 기계가 처리하기엔 복잡하거나 불필요한 정보를 포함하고 있다. 그래서 정제는 단순히 앞단 작업이 아닌, 토큰화 이후에도 계속적으로 반복 수행되어야 하는 과정이다.

이 정제 작업에는 특별한 정답이 없다. 문맥과 목적에 따라 “이 정도면 충분하다”는 합의점을 설정하는 것이 중요하다.

대표적인 정제 작업

  1. 동일 의미 표현 통합
    예: U.S.A., USA, us 등은 목적에 따라 US로 통합할 수 있다.
  2. 대소문자 통일
    보통 소문자로 통일하지만, us(우리)와 US(미국)처럼 의미가 달라지는 경우는 구분 유지
  3. 불용어(stopwords) 제거
    분석에 영향을 주지 않는 단어들은 제거해 모델의 학습 효율을 높임
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
import nltk

nltk.download('punkt')
nltk.download('stopwords')

text = "This is an example sentence demonstrating stopword removal."
tokens = word_tokenize(text)
filtered = [w for w in tokens if w.lower() not in stopwords.words("english")]
print(filtered)

이처럼 정제는 단어 수를 줄이고, 의미 있는 토큰만 남겨 모델이 더 나은 패턴을 학습할 수 있도록 도와준다.

단어 표현 방식의 두 갈래

텍스트를 숫자로 표현하는 데는 크게 국소 표현(Local Representation)연속 표현(Continuous Representation) 두 가지 방식이 존재한다.

표현 방식 설명  대표 예시
국소 표현 단어 자체에 집중, 의미 관계 고려 없음 BoW, TDM, One-hot
연속 표현 단어 간 의미적 유사성 반영 Word2Vec, GloVe, FastText

국소 표현은 단순하지만 해석과 구현이 쉬우며, 연속 표현은 학습 비용이 크지만 단어 간 의미를 반영한 고차원 벡터를 만들어낼 수 있다.

Bag-of-Words (BoW): 가장 기본적인 표현 방식

BoW는 문서에서 등장한 단어의 빈도만을 고려하여 벡터화하는 방식이다. 문장 구조나 단어 순서를 고려하지 않기 때문에 정보 손실이 있지만, 간단한 통계 분석에서는 여전히 많이 사용된다.

장점

  • 구현이 쉽고 빠름
  • 단어 출현 빈도 기반으로 해석 용이

단점

  • 어순 정보 손실
  • 동음이의어, 중의성 처리 불가
  • 단어 수가 많아지면 희소 행렬(Sparse Matrix) 발생
from sklearn.feature_extraction.text import CountVectorizer

corpus = ["I love machine learning.", "You love deep learning."]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names_out())
print(X.toarray())

출력 결과는 단어 목록과 각 문서에서 해당 단어가 몇 번 등장했는지를 나타내는 배열로 구성된다.

Term-Document Matrix와 희소 행렬의 한계

BoW 결과는 단어-문서 행렬(Term-Document Matrix, TDM)로 표현된다. 하지만 문서마다 사용하는 단어 수가 제한적인 반면, 전체 단어 사전은 수천~수만 개에 이르기 때문에 대부분의 셀은 0으로 채워진다.

이러한 희소성은 모델 학습 속도를 저하시키고, 중요한 단어를 제대로 반영하지 못할 수 있다. 예를 들어, 여러 문서에 공통으로 등장하는 the 같은 단어는 중요하지 않음에도 높은 빈도로 인해 문서 간 유사도를 왜곡시킬 수 있다.

이 한계를 극복하고자 등장한 개념이 바로 단어 임베딩(word embedding)이다.

희소 표현 vs 밀집 표현

희소 표현 (Sparse Representation)

  • 대표: One-hot encoding
  • 단어 수만큼 벡터의 차원이 커짐
  • 대부분의 값이 0
  • 정보량이 적고 계산 비효율적

밀집 표현 (Dense Representation)

  • 대표: Word2Vec, GloVe
  • 실수값 벡터로 의미 정보 포함
  • 차원을 적절하게 조정 가능
  • 연산 효율성과 의미 해석력 모두 향상

Word2Vec: 의미를 담은 벡터 표현

Word2Vec은 비지도학습 기반 임베딩 기법으로, 단어 간의 문맥적 유사성을 벡터 공간에 반영할 수 있도록 설계되었다.

두 가지 학습 방식이 있다:

  • CBOW (Continuous Bag-of-Words)
    주변 단어로 중심 단어를 예측
    → 전체 데이터에 대한 평균적 정보를 반영
  • Skip-gram
    중심 단어로 주변 단어를 예측
    → 희귀 단어에도 강하고, 세밀한 문맥 분석 가능

Word2Vec을 통해 학습된 단어 벡터는 단어 간 유사도, 유추 관계(예: "왕 - 남자 + 여자 = 여왕") 등의 연산도 가능하게 한다.

오늘의 회고

형태소 분석과 토큰화가 문장을 분해하는 작업이라면, 정제와 임베딩은 유의미한 정보만 추려내고 이를 숫자로 표현하는 작업이라 할 수 있다. 데이터의 품질은 전처리에서 결정된다는 말을 다시 한 번 실감하게 되었다.

특히 BoW나 One-hot처럼 단순한 수치화는 구조 파악에는 유용하지만, 문맥이나 의미를 고려한 분석에는 한계가 분명하다. 반대로 Word2Vec과 같은 임베딩 기법은 단어의 의미적 맥락을 학습하고 반영할 수 있어, 보다 정교한 NLP 모델에 필요한 기반을 제공한다.

앞으로 자연어 처리 기반 모델을 설계할 때는 단순한 텍스트 분석을 넘어서, 단어 간 의미 관계와 문맥까지 반영할 수 있는 임베딩 기법을 적극적으로 활용해야겠다는 생각이 들었다.