단어를 벡터로 바꾸는 법: BOW·TF-IDF부터 Word2Vec CBOW·Skip-gram까지

빈도 기반 BOW·TF-IDF와 추론 기반 Word2Vec(CBOW·Skip-gram)의 차이를 비교하고, 검색·감성분석·기계번역에서 임베딩이 어떻게 쓰이는지 정리한다.

2026-08-13 · 최초 발행 2025-05-23

같은 '사과'라는 단어라도 그것을 숫자로 옮기는 방식이 다르면 검색 결과도, 챗봇의 감정 판단도, 번역 품질도 달라진다. Word Embedding은 인간의 언어를 컴퓨터가 처리할 수 있는 수치 형태로 바꾸는 자연어 처리의 기반 기술이며, 텍스트를 벡터 공간에 밀집된 형태로 표현함으로써 의미적·구문적 관계를 수학적으로 모델링한다.

밀집 벡터가 희소 벡터와 다른 점

Dense Representation은 단어나 문장을 밀집된 실수 벡터로 표현하는 방식이다. 기존의 희소 표현(Sparse Representation)과 달리 모든 차원이 의미를 갖는 밀집 벡터를 생성한다.

  • 특징: 저차원(일반적으로 50~300차원), 연속적인 실수값, 의미적 관계 보존
  • 장점: 차원 감소, 일반화 성능 향상, 계산 효율성 증대
  • 응용: 문서 분류, 감성 분석, 기계 번역, 챗봇 등 다양한 NLP 작업

빈도를 세는 방식: BOW·Count Vector·TF-IDF

통계적 방법을 활용해 단어의 출현 빈도나 분포 정보를 기반으로 벡터를 만드는 접근이 횟수 기반 임베딩(Frequency-based Embedding)이다.

BOW(Bag of Words)는 문서 내 단어의 등장 여부나 빈도만을 고려하는 가장 기본적인 표현 방식이다.

# BOW 예시
from sklearn.feature_extraction.text import CountVectorizer

corpus = ["나는 사과를 좋아한다", "나는 바나나를 싫어한다", "사과와 바나나는 과일이다"]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names_out())
print(X.toarray())

결과:

['과일이다', '나는', '바나나는', '바나나를', '사과와', '사과를', '싫어한다', '좋아한다']
[[0 1 0 0 0 1 0 1]
 [0 1 0 1 0 0 1 0]
 [1 0 1 0 1 0 0 0]]

한계점:

  • 단어 순서 정보 손실
  • 의미적 유사성 반영 어려움
  • 희소 벡터(sparse vector) 생성으로 차원의 저주 문제 발생

Count Vector는 BOW와 유사하지만 각 단어의 출현 빈도를 명시적으로 계산한다.

TF-IDF(Term Frequency-Inverse Document Frequency)는 단순 빈도 계산의 한계를 보완하기 위해 단어의 중요도를 반영한다. TF(Term Frequency)는 특정 문서 내에서 단어의 등장 빈도이고, IDF(Inverse Document Frequency)는 전체 문서 집합에서 해당 단어를 포함한 문서의 비율에 로그를 취한 후 역수를 계산한 값이다.

# TF-IDF 예시
from sklearn.feature_extraction.text import TfidfVectorizer

corpus = ["나는 사과를 좋아한다", "나는 바나나를 싫어한다", "사과와 바나나는 과일이다"]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names_out())
print(X.toarray())

장점:

  • 문서 집합 내 단어의 상대적 중요도 반영
  • 불용어(stopwords) 영향 감소
  • 정보 검색 및 문서 유사도 측정에 효과적

예측으로 학습하는 방식: Word2Vec의 CBOW와 Skip-gram

신경망 기반 학습을 통해 단어의 의미적 관계를 포착하는 접근이 추론 기반 임베딩(Prediction-based Embedding)이다. Word2Vec은 Google에서 2013년 발표한 모델로, 대규모 텍스트 데이터에서 단어의 의미적 관계를 학습한다.

CBOW(Continuous Bag of Words)는 주변 단어들을 통해 중심 단어를 예측하는 방식이다.

주변 단어 1Hidden Layer주변 단어 2주변 단어 n중심 단어
  • 입력: 중심 단어의 전후 문맥 단어들
  • 출력: 중심 단어
  • 특징: 일반적인 단어에 대해 높은 정확도, 학습 속도가 빠름

Skip-gram은 중심 단어를 통해 주변 단어들을 예측하는 방식이다.

중심 단어Hidden Layer주변 단어 1주변 단어 2주변 단어 n
  • 입력: 중심 단어
  • 출력: 주변 단어들
  • 특징: 희귀 단어에 대해 좋은 성능, CBOW보다 계산 비용이 높음

Word2Vec은 단어 간 의미적 유사성을 포착하고, 벡터 연산을 통한 유추 관계 표현이 가능하다(예: '왕 - 남자 + 여자 = 여왕'). 저차원 벡터 공간에 단어 의미를 효과적으로 압축한다는 점도 특징이다.

검색·감성분석·번역에서 임베딩이 하는 일

검색 엔진 최적화에서는 사용자 쿼리와 문서 간의 의미적 유사성을 계산해 검색 결과의 정확도를 향상시킨다.

# 검색 시스템 구현 예시
from gensim.models import Word2Vec
import numpy as np

# 문서 집합과 쿼리
documents = ["인공지능 기술이 발전하고 있다", "딥러닝은 인공지능의 한 분야이다", "자연어 처리는 컴퓨터가 언어를 이해하는 기술이다"]
query = "머신러닝 알고리즘"

# 문서와 쿼리를 토큰화
tokenized_docs = [doc.split() for doc in documents]
tokenized_query = query.split()

# Word2Vec 모델 학습 (실제로는 대규모 코퍼스로 사전 학습된 모델 사용)
model = Word2Vec(sentences=tokenized_docs, vector_size=100, window=5, min_count=1, workers=4)

# 문서와 쿼리 벡터화
def doc_to_vec(doc, model):
    vec = np.zeros(model.vector_size)
    count = 0
    for word in doc:
        if word in model.wv:
            vec += model.wv[word]
            count += 1
    return vec / count if count > 0 else vec

doc_vecs = [doc_to_vec(doc, model) for doc in tokenized_docs]
query_vec = doc_to_vec(tokenized_query, model)

# 코사인 유사도 계산
from sklearn.metrics.pairwise import cosine_similarity
similarities = cosine_similarity([query_vec], doc_vecs)[0]
print(list(zip(documents, similarities)))

Word Embedding을 활용한 감성 분석은 텍스트의 감정적 톤을 파악하는 데 효과적이다.

# 감성 분석 예시
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense

# 데이터 준비
texts = ["이 영화는 정말 재미있었어요", "최악의 서비스였습니다", "보통이었어요"]
labels = [1, 0, 0.5]  # 1: 긍정, 0: 부정, 0.5: 중립

# 토큰화
tokenizer = Tokenizer()
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
padded_sequences = pad_sequences(sequences, maxlen=10)

# Embedding 레이어를 포함한 모델 구성
vocab_size = len(tokenizer.word_index) + 1
embedding_dim = 16

model = Sequential([
    Embedding(vocab_size, embedding_dim, input_length=10),
    LSTM(32),
    Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# 실제로는 더 많은 데이터로 학습 필요

Sequence-to-Sequence 모델을 쓰는 기계 번역 시스템에서는 소스 언어와 대상 언어 간의 의미적 대응을 학습하는 데 Word Embedding이 중요한 역할을 한다.

영어 입력Embedding LayerEncoderContext VectorDecoder한국어 출력

문맥화·다국어·멀티모달로 넘어가는 흐름

BERT, ELMo 등의 모델은 같은 단어라도 문맥에 따른 다양한 의미를 포착할 수 있는 동적 임베딩을 만든다. 다국어 임베딩은 다양한 언어 간 의미적 연결을 유지하는 공통 벡터 공간을 구축하는 방향이고, 도메인 특화 임베딩은 의료·법률 등 특정 분야에 최적화된 임베딩 모델을 개발하는 흐름이다. 텍스트·이미지·오디오 등 다양한 모달리티를 통합하는 멀티모달 임베딩 연구도 진행되고 있다.

Word Embedding은 컴퓨터가 인간 언어의 복잡한 구조와 의미를 이해하는 첫 단계다. 횟수 기반 방식에서 시작해 추론 기반 방식으로 발전했으며, 사용 목적·데이터 특성·계산 리소스를 종합적으로 고려해 적절한 임베딩 방식을 선택하는 것이 자연어 처리 시스템의 성능을 가르는 요소다.

자연어처리워드임베딩Word2VecTF-IDFNLP