1"""
202. Word2Vec과 GloVe - 단어 임베딩 예제
3
4단어 임베딩 학습과 활용
5"""
6
7import numpy as np
8
9print("=" * 60)
10print("단어 임베딩")
11print("=" * 60)
12
13
14# ============================================
15# 1. 코사인 유사도
16# ============================================
17print("\n[1] 코사인 유사도")
18print("-" * 40)
19
20def cosine_similarity(v1, v2):
21 """두 벡터의 코사인 유사도"""
22 dot = np.dot(v1, v2)
23 norm = np.linalg.norm(v1) * np.linalg.norm(v2)
24 return dot / norm if norm > 0 else 0
25
26# 예시 벡터
27vec_king = np.array([0.5, 0.3, 0.8, 0.1])
28vec_queen = np.array([0.5, 0.4, 0.7, 0.2])
29vec_apple = np.array([-0.2, 0.9, 0.1, 0.5])
30
31print(f"king-queen 유사도: {cosine_similarity(vec_king, vec_queen):.4f}")
32print(f"king-apple 유사도: {cosine_similarity(vec_king, vec_apple):.4f}")
33
34
35# ============================================
36# 2. 간단한 임베딩 레이어 (PyTorch)
37# ============================================
38print("\n[2] PyTorch 임베딩 레이어")
39print("-" * 40)
40
41try:
42 import torch
43 import torch.nn as nn
44
45 # 임베딩 레이어
46 vocab_size = 100
47 embed_dim = 64
48 embedding = nn.Embedding(vocab_size, embed_dim)
49
50 # 입력: 단어 인덱스
51 input_ids = torch.tensor([1, 5, 10, 20])
52 embedded = embedding(input_ids)
53
54 print(f"입력 shape: {input_ids.shape}")
55 print(f"출력 shape: {embedded.shape}")
56 print(f"임베딩 가중치 shape: {embedding.weight.shape}")
57
58except ImportError:
59 print("PyTorch 미설치")
60
61
62# ============================================
63# 3. Gensim Word2Vec
64# ============================================
65print("\n[3] Gensim Word2Vec")
66print("-" * 40)
67
68try:
69 from gensim.models import Word2Vec
70
71 # 샘플 코퍼스
72 sentences = [
73 ["i", "love", "machine", "learning"],
74 ["machine", "learning", "is", "fun"],
75 ["deep", "learning", "is", "great"],
76 ["i", "love", "deep", "learning"],
77 ["neural", "networks", "are", "powerful"],
78 ["deep", "neural", "networks", "learn", "features"],
79 ]
80
81 # Word2Vec 학습
82 model = Word2Vec(
83 sentences,
84 vector_size=50, # 임베딩 차원
85 window=3, # 컨텍스트 윈도우
86 min_count=1, # 최소 빈도
87 sg=1, # Skip-gram (0=CBOW)
88 epochs=100
89 )
90
91 # 유사 단어
92 print("'learning' 유사 단어:")
93 similar = model.wv.most_similar("learning", topn=3)
94 for word, score in similar:
95 print(f" {word}: {score:.4f}")
96
97 # 벡터 가져오기
98 vec = model.wv["learning"]
99 print(f"\n'learning' 벡터 shape: {vec.shape}")
100
101 # 저장/로드
102 model.save("word2vec_demo.model")
103 loaded = Word2Vec.load("word2vec_demo.model")
104 print("모델 저장/로드 완료")
105
106 # 정리
107 import os
108 os.remove("word2vec_demo.model")
109
110except ImportError:
111 print("gensim 미설치 (pip install gensim)")
112
113
114# ============================================
115# 4. 사전학습 임베딩 사용
116# ============================================
117print("\n[4] 사전학습 임베딩 적용")
118print("-" * 40)
119
120try:
121 import torch
122 import torch.nn as nn
123
124 # 가상의 사전학습 임베딩 (실제로는 GloVe 등 로드)
125 pretrained_embeddings = torch.randn(1000, 100) # vocab_size=1000, dim=100
126
127 # 임베딩 레이어에 적용
128 embedding = nn.Embedding.from_pretrained(
129 pretrained_embeddings,
130 freeze=False, # True면 학습 안 함
131 padding_idx=0
132 )
133
134 print(f"사전학습 임베딩 shape: {pretrained_embeddings.shape}")
135 print(f"freeze=False: 파인튜닝 가능")
136
137 # 분류 모델에 적용
138 class TextClassifier(nn.Module):
139 def __init__(self, pretrained_emb, num_classes):
140 super().__init__()
141 self.embedding = nn.Embedding.from_pretrained(pretrained_emb, freeze=False)
142 self.fc = nn.Linear(pretrained_emb.shape[1], num_classes)
143
144 def forward(self, x):
145 embedded = self.embedding(x) # (batch, seq, embed)
146 pooled = embedded.mean(dim=1) # 평균 풀링
147 return self.fc(pooled)
148
149 model = TextClassifier(pretrained_embeddings, num_classes=2)
150 print(f"분류 모델 생성 완료")
151
152except ImportError:
153 print("PyTorch 미설치")
154
155
156# ============================================
157# 5. 단어 유추 (Word Analogy)
158# ============================================
159print("\n[5] 단어 유추")
160print("-" * 40)
161
162def word_analogy(word_a, word_b, word_c, embeddings, word2idx, idx2word, topk=3):
163 """
164 a : b = c : ?
165 예: king : queen = man : woman
166 """
167 # 벡터 가져오기
168 vec_a = embeddings[word2idx[word_a]]
169 vec_b = embeddings[word2idx[word_b]]
170 vec_c = embeddings[word2idx[word_c]]
171
172 # 유추 벡터: b - a + c
173 target = vec_b - vec_a + vec_c
174
175 # 유사도 계산
176 similarities = np.dot(embeddings, target) / (
177 np.linalg.norm(embeddings, axis=1) * np.linalg.norm(target)
178 )
179
180 # 상위 k개 (a, b, c 제외)
181 exclude = {word2idx[word_a], word2idx[word_b], word2idx[word_c]}
182 results = []
183 for idx in np.argsort(similarities)[::-1]:
184 if idx not in exclude:
185 results.append((idx2word[idx], similarities[idx]))
186 if len(results) >= topk:
187 break
188
189 return results
190
191# 예시 (가상 데이터)
192vocab = ["king", "queen", "man", "woman", "prince", "princess", "boy", "girl"]
193word2idx = {w: i for i, w in enumerate(vocab)}
194idx2word = {i: w for i, w in enumerate(vocab)}
195
196# 가상 임베딩 (실제로는 학습된 임베딩 사용)
197np.random.seed(42)
198embeddings = np.random.randn(len(vocab), 50)
199# 의미적 관계 시뮬레이션
200embeddings[word2idx["queen"]] = embeddings[word2idx["king"]] + np.array([0.1] * 50)
201embeddings[word2idx["woman"]] = embeddings[word2idx["man"]] + np.array([0.1] * 50)
202
203result = word_analogy("king", "queen", "man", embeddings, word2idx, idx2word)
204print(f"king : queen = man : ?")
205for word, score in result:
206 print(f" {word}: {score:.4f}")
207
208
209# ============================================
210# 정리
211# ============================================
212print("\n" + "=" * 60)
213print("단어 임베딩 정리")
214print("=" * 60)
215
216summary = """
217핵심 개념:
218 - 분산 표현: 단어를 밀집 벡터로 표현
219 - Word2Vec: Skip-gram, CBOW
220 - GloVe: 동시 출현 통계 기반
221
222사용법:
223 # Gensim Word2Vec
224 model = Word2Vec(sentences, vector_size=100, window=5)
225 similar = model.wv.most_similar("word", topn=5)
226
227 # PyTorch 임베딩
228 embedding = nn.Embedding.from_pretrained(vectors, freeze=False)
229
230단어 연산:
231 king - queen + man ≈ woman
232"""
233print(summary)