🤖 AI/ML

Word2Vec

워드투벡

단어를 벡터로 표현하는 임베딩 기법. CBOW, Skip-gram 방식. 현대 NLP의 기초.

📖 상세 설명

Word2Vec은 2013년 Google의 Tomas Mikolov가 발표한 단어 임베딩 기법으로, 단어를 고정 차원의 밀집 벡터(Dense Vector)로 표현합니다. "비슷한 맥락에서 나타나는 단어는 비슷한 의미를 가진다"는 분포 가설에 기반하여, 대규모 텍스트 코퍼스에서 단어 간 의미적 관계를 학습합니다.

Word2Vec 이전에는 원-핫 인코딩(One-Hot Encoding)이 주로 사용되었습니다. 하지만 원-핫 벡터는 차원이 어휘 크기와 같고, 단어 간 유사도를 표현할 수 없습니다. Word2Vec은 수백 차원의 벡터로 단어를 표현하며, "왕 - 남자 + 여자 = 여왕"처럼 벡터 연산으로 의미적 관계를 포착할 수 있습니다.

Word2Vec은 두 가지 학습 방식을 제공합니다. CBOW(Continuous Bag of Words)는 주변 단어로 중심 단어를 예측하고, Skip-gram은 중심 단어로 주변 단어를 예측합니다. Skip-gram은 희귀 단어에 강하고, CBOW는 학습 속도가 빠릅니다. Negative Sampling으로 학습 효율을 높이며, 수억 단어도 CPU로 학습할 수 있습니다.

실무에서 Word2Vec은 현재 BERT, GPT 같은 문맥 임베딩에 비해 성능이 낮아 직접 사용은 줄었지만, 개념적으로 매우 중요합니다. FastText(하위 단어 처리), GloVe(전역 통계 활용) 등이 Word2Vec을 발전시켰고, 현대 임베딩의 기초가 되었습니다. 교육 목적과 가벼운 프로젝트에서 여전히 사용됩니다.

💻 코드 예제

from gensim.models import Word2Vec
from gensim.models import KeyedVectors
import numpy as np

# 1. 샘플 데이터 (토큰화된 문장 리스트)
sentences = [
    ["인공지능", "머신러닝", "딥러닝", "연구"],
    ["자연어", "처리", "NLP", "텍스트", "분석"],
    ["머신러닝", "알고리즘", "학습", "데이터"],
    ["딥러닝", "신경망", "GPU", "학습"],
    ["인공지능", "자연어", "처리", "챗봇"],
]

# 2. Word2Vec 모델 학습
model = Word2Vec(
    sentences,
    vector_size=100,    # 임베딩 차원
    window=5,           # 컨텍스트 윈도우 크기
    min_count=1,        # 최소 출현 빈도
    sg=1,               # 1=Skip-gram, 0=CBOW
    workers=4,          # 병렬 스레드 수
    epochs=100          # 학습 에포크
)

# 3. 단어 벡터 확인
vector = model.wv["인공지능"]
print(f"'인공지능' 벡터 차원: {vector.shape}")
print(f"벡터 (처음 10개): {vector[:10]}")

# 4. 유사 단어 검색
similar = model.wv.most_similar("머신러닝", topn=5)
print("\n'머신러닝'과 유사한 단어:")
for word, score in similar:
    print(f"  {word}: {score:.4f}")

# 5. 단어 간 유사도
similarity = model.wv.similarity("딥러닝", "신경망")
print(f"\n딥러닝 - 신경망 유사도: {similarity:.4f}")

# 6. 벡터 연산 (Word Analogy)
# A:B = C:? -> ? = B - A + C
try:
    result = model.wv.most_similar(
        positive=["딥러닝", "자연어"],
        negative=["머신러닝"],
        topn=3
    )
    print("\n딥러닝 - 머신러닝 + 자연어 =")
    for word, score in result:
        print(f"  {word}: {score:.4f}")
except KeyError as e:
    print(f"단어 없음: {e}")

# 7. 모델 저장 & 로드
model.save("word2vec.model")
loaded_model = Word2Vec.load("word2vec.model")

# 벡터만 저장 (경량)
model.wv.save_word2vec_format("word2vec.txt", binary=False)


# === 사전학습 모델 사용 (실무 권장) ===
# Google News 300차원 (약 3GB)
# https://drive.google.com/file/d/0B7XkCwpI5KDYNlNUTTlSS21pQmM

# pretrained = KeyedVectors.load_word2vec_format(
#     "GoogleNews-vectors-negative300.bin", binary=True
# )
# print(pretrained.most_similar("king"))


# === 한국어: FastText 사용 권장 ===
# from gensim.models import FastText
#
# model_ko = FastText(
#     sentences,
#     vector_size=100,
#     window=5,
#     min_count=1,
#     sg=1
# )
# # FastText는 OOV(미등록 단어)도 처리 가능

🗣️ 실무에서 이렇게 말하세요

💬 회의에서

"검색 개선에 Word2Vec 기반 유사어 확장을 적용해볼까요? 사용자가 '노트북' 검색하면 '랩탑', '컴퓨터'도 함께 검색되게요. 다만 요즘은 Sentence-BERT 같은 문장 임베딩이 더 정확해요."

💬 면접에서

"Word2Vec과 BERT 임베딩의 차이가 뭔가요?" - "Word2Vec은 단어 하나에 고정된 벡터를 부여해요. 'bank'가 '은행'이든 '강둑'이든 같은 벡터죠. 반면 BERT는 문맥에 따라 다른 벡터를 생성하는 문맥 임베딩이라 동음이의어도 구분합니다."

💬 기술 토론에서

"Word2Vec의 '왕 - 남자 + 여자 = 여왕' 연산이 사실 항상 정확하진 않아요. 데이터 편향이 반영되어서 의도치 않은 결과가 나오기도 합니다. 그래도 단어 의미의 벡터 공간 표현이라는 아이디어 자체가 혁신적이었죠."

⚠️ 흔한 실수 & 주의사항

작은 코퍼스로 학습

Word2Vec은 수백만~수십억 단어의 대규모 코퍼스가 필요합니다. 작은 데이터로 학습하면 품질이 낮습니다. Google News, Wiki 등 사전학습 모델을 사용하거나, 도메인 코퍼스로 추가 학습(Continual Training)하세요.

OOV(미등록 단어) 무시

Word2Vec은 학습에 없던 단어를 처리할 수 없습니다. "인공지능들" 같은 변형어도 별도 단어로 취급됩니다. 한국어처럼 형태소가 다양한 언어에서는 FastText(하위 단어 처리 지원)가 더 적합합니다.

현대 프로젝트에서는 문맥 임베딩 사용

실제 NLP 프로젝트에서는 BERT, Sentence-BERT 등 문맥 임베딩을 사용하세요. Word2Vec은 교육/연구 목적이나 리소스가 극히 제한된 환경에 적합합니다.

🔗 관련 용어

📚 더 배우기