09_DL(Deep_Learning)

26-1_Word2Vec 학습

chuu_travel 2025. 5. 8. 00:39
728x90
Word2Vec 학습

 

from gensim.models import Word2Vec  # 이전에는 anaconda에 포함돼있지 않았으나 현재는 포함돼있음
from konlpy.tag import Komoran
import time
import pandas as pd

 

df = pd.read_csv("./data/nsmc/ratings.txt", sep="\t")
df = df.dropna()
df.head()

 

 

komoran = Komoran()

 

df.shape
(199992, 3)

 

 

%%time
# 문장 단위로 명사만 추출해 학습 입력 데이터로 만듦
docs = df["document"].map(lambda x: komoran.nouns(x))
CPU times: total: 1min 30s
Wall time: 1min 26s

 

# 명사만 추출되었음을 확인
docs
0                                                       [때]
1         [디자인, 학생, 외국, 디자이너, 전통, 발전, 문화, 산업, 사실, 우리나라, ...
2                                    [폴리스, 스토리, 시리즈, 뉴, 최고]
3                                [연기, 것, 라고, 생각, 몰입, 영, 화지]
4                                        [안개, 밤하늘, 초승달, 영화]
                                ...                        
199995                                         [포켓, 몬스터, 짜]
199996                                                   []
199997                            [완전, 사이코, 영화, 마지막, 영화, 질]
199998                                          [라따뚜이, 스머프]
199999                       [포, 풍, 저그, 가나, 신다영, 차영, 차영, 차]
Name: document, Length: 199992, dtype: object

 

# word2vec 모델 학습
model = Word2Vec(sentences = docs, vector_size = 256, window = 4, min_count = 2, sg = 1)

 

● word2vec 의 주요 하이퍼파라미터

        ■ sentences: Word2Vec 모델 학습에 필요한 문장 데이터

        ■ vector_size: 단어 임베딩 벡터의 차원(크기)

        ■ window: 주변 단어 윈도우의 크기

        ■ min_count: 단어 최소 빈도 수 제한(설정된 min_count 빈도 수 미만의 단어들은 학습하지 않음)

        ■ sg: 0(CBOW 모델), 1(skip-gram 모델)

 

 

# 모델 저장
model.save("./model/nsmc_w2v.model")

 

# 학습된 말뭉치 개수, 코퍼스 내 전체 단어 개수
print("corpus_count : ", model.corpus_count)
print("corpus_total_words: ", model.corpus_total_words)
corpus_count :  199992
corpus_total_words:  1076840

 

 

모델 활용

# 모델 불러오기
model = Word2Vec.load("./model/nsmc_w2v.model")
model.corpus_total_words
1076840

 

# "사랑"이란 단어로 생성한 단어 임베딩 벡터
print(model.wv["사랑"])
[ 5.03551140e-02 -1.20940499e-01 -4.54437397e-02  2.49469146e-01
  2.19402254e-01 -1.59107521e-01  3.47351655e-03 -5.05665690e-03
  1.65108204e-01  2.98138350e-01 -4.14108992e-01  1.89114302e-01
  5.11656292e-02  3.32701057e-01 -1.71698377e-01  1.04631618e-01
 -2.31582612e-01  3.00946891e-01 -3.49055022e-01  4.00409341e-01
 -1.55769642e-02 -1.83839753e-01  4.60104132e-03 -3.22306484e-01
 -1.56971455e-01  2.50645578e-02  1.72172248e-01  4.24253382e-02
 -1.73420057e-01 -1.60913855e-01  3.43990862e-01  1.30702741e-02
 -2.72381723e-01  1.58343136e-01 -1.73336759e-01  4.27142859e-01
  1.01685353e-01 -4.78130244e-02  5.86877652e-02 -8.18799585e-02
 -3.81644428e-01  3.76871794e-01 -1.54766336e-01  5.07218465e-02
  2.66992629e-01  2.60089487e-01 -2.03638300e-02  1.95819333e-01
  2.45752230e-01 -1.75882638e-01 -2.39247009e-01 -1.14789158e-01
  3.50525141e-01  1.08401552e-01  1.64726853e-01  2.17004627e-01
  3.46328728e-02  2.56802607e-02  1.18470728e-01  5.74136734e-01
  1.42950162e-01 -8.47630575e-02  1.47848025e-01  1.74800217e-01
  1.05233826e-02  3.32968861e-01  2.48884439e-01  3.68773669e-01
  ...

 

● 모델을 학습할 때 설정한 vector_size 하이퍼파라미터만큼 단어 임베딩 벡터 차원 크기가 결정됨

 

# 단어 유사도 계산
print("일요일 = 월요일", model.wv.similarity(w1 = "일요일", w2 = "월요일"))
일요일 = 월요일 0.89313704

 

print("안성기 = 배우", model.wv.similarity(w1 = "안성기", w2 = "배우"))
안성기 = 배우 0.6845103

 

print("대기업 = 삼성", model.wv.similarity(w1 = "대기업", w2 = "삼성"))
대기업 = 삼성 0.88802123

 

print("일요일 = 삼성", model.wv.similarity(w1 = "일요일", w2 = "삼성"))
일요일 = 삼성 0.6485236

 

print("히어로 = 삼성", model.wv.similarity(w1 = "히어로", w2 = "삼성"))
히어로 = 삼성 0.45890898

 

● model.wv.similarity(): 두 단어 간의 유사도를 계산

 

# 가장 유사한 단어 추출
print(model.wv.most_similar("안성기", topn = 5))
[('최강희', 0.9393807649612427), ('정려원', 0.9355235695838928), ('김하늘', 0.9333276152610779), ('이준기', 0.9326339364051819), ('한석규', 0.9323666095733643)]

 

print(model.wv.most_similar("시리즈", topn = 5))
[('포터', 0.8140829205513), ('엑스맨', 0.7996651530265808), ('스타워즈', 0.7993466258049011), ('반지의 제왕', 0.793843686580658), ('미이라', 0.7783376574516296)]

 

● wv.most_similar() 함수: 인자로 사용한 단어와 가장 유사한 단어를 리스트로 반환

        ■ 벡터 공간에서 가장 가까운 거리에 있는 단어들을 반환

        ■ topn: 반환되는 유사한 단어 수

 

유사도가 1에 가까울 수록 두 단어는 동일한 의미이거나 문법적으로 관련이 있을 가능성이 높음

 

import gensim
sentences = gensim.models.word2vec.Text8Corpus("./data/text8.txt")
model = gensim.models.word2vec.Word2Vec(sentences, vector_size = 256)

 

model.wv.most_similar(positive = ["king", "woman"], negative = ["man"])
[('queen', 0.6227017641067505),
 ('consort', 0.5332034826278687),
 ('prince', 0.5330978035926819),
 ('elizabeth', 0.5307813286781311),
 ('throne', 0.529766857624054),
 ('princess', 0.5238737463951111),
 ('daughter', 0.51668381690979),
 ('husband', 0.5154788494110107),
 ('son', 0.5131805539131165),
 ('isabella', 0.5114434361457825)]
728x90

'09_DL(Deep_Learning)' 카테고리의 다른 글

28_문답데이터_감정분류  (0) 2025.05.08
27_텍스트 유사도  (1) 2025.05.08
26_임베딩  (0) 2025.05.08
25_토크나이징  (1) 2025.05.07
24_전이학습(transfer learning)_keras  (0) 2025.05.07