[ํ ์คํธ๋ง์ด๋] Word2Vec Modeling ์ค์ต
Word2Vec ์ด๋ก
one-hot encoding์ ๋จ์ด๋ฅผ ๋ฒกํฐ๋ก ๋ํ๋ผ ๋ ์ด ๋จ์ด ์๋งํผ์ ๊ธธ์ด์ ๋ฒกํฐ์์ ๋ค๋ฅธ ๋ชจ๋ ๊ฐ์ 0์ผ๋ก ํ๊ณ ๋จ์ด ๋ฒํธ์ ํด๋นํ๋ ์์๋ง 1๋ก ํ์ํ๋ค. 'ํ ๋ผ', '๋์๊ด', '๋ฌผ' 3 ๋จ์ด๋ง ์๊ณ ์์๋๋ก 1~3๋ฒ์ด๋ผ๋ฉด ํ ๋ผ๋(1,0,0), ๋์๊ด์(0,1,0), ๋ฌผ์(0,0,1)๋ก ๋ํ๋๋ค. ๋จ์ด์ ์๋ฏธ๋ฅผ ๊ณ ๋ คํ์ง ์์ผ๋ฉฐ ๋ฒกํฐ์ ๊ธธ์ด๊ฐ ์ด ๋จ์ด ์๊ฐ ๋๋ฏ๋ก ํฌ๋ฐํ ํํ๊ฐ ๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋จ์ด์ ์๋ฏธ๋ฅผ ๊ณ ๋ คํ์ฌ ์กฐ๋ฐํ ์ฐจ์์ ๋จ์ด๋ฅผ ๋ฒกํฐ๋ก ํํํ๋ ๊ฒ์ ๋จ์ด ์๋ฒ ๋ฉ์ด๋ผ๊ณ ํ๋ค. ๋จ์ด ์๋ฒ ๋ฉ์ ๋จ์ด์ ์๋ฏธ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํํํ๊ธฐ ๋๋ฌธ์ one-hot encoding๋ณด๋ค ํ์ต ์ฑ๋ฅ์ ๋์ผ ์ ์๋ค. ๋จ์ด ์๋ฒ ๋ฉ์ ์ข ๋ฅ์๋ LSA, Word2Vec, GloVe, FastText ๋ฑ์ด ์๋ค.
Word2Vec์ ๋จ์ด๋ฅผ ๋ฒกํฐ๋ก ๋ณํํด ์ค๋ค. ์ ์ฐจ์ ๋ฒกํฐ๋ฅผ ๊ฐ์ง๊ณ ๋ค์ฐจ์ ๊ณต๊ฐ์ ๋ฒกํฐํํด์ ์ ์ฌ์ฑ์ ํํํ ์ ์๋ค.
ํ์ง๋ง ๋ฌธ๋งฅ์ ํํ์ ์ ๋๋ค. ์ฆ, ๋จ์ด(๋ชจ์)์ ์ถํ์ด์ง ๋จ์ด(์๋ฏธ)์ ์ถํ์ ์๋๋ค.
(์์ ์ฒจ๋ถ๋ ๋ธ๋ก๊ทธ๋ค์ ๊ธ์ ์ ๋ฆฌํ์ฌ ์์ฑํ์ต๋๋ค)
Word2Vec Modeling ์ค์ต
1. ํจํค์ง ๋ฐ ๋ฐ์ดํฐ ํ์ผ ๋ถ๋ฌ์ค๊ธฐ
- ํจํค์ง ๋ถ๋ฌ์ค๊ธฐ
import pandas as pd
import re
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
from gensim.models import Word2Vec
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
- ํ์ผ ๋ถ๋ฌ์ค๊ธฐ
en_data = pd.read_csv('wos_ai_.csv', encoding='euc-kr')
en_data_abstract = en_data['ABSTRACT']
3. ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
- ๋น ๋ฐ์ดํฐ์ ์ค๋น
en_doc = []
en_word_joined = []
en_word = []
- ๋ฌธ์๋ฉด - ๋์ ๊ณต๋ฐฑ ๋ฃ๊ธฐ
for doc in en_data_abstract :
if type(doc) != float :
en_doc.append(doc.replace("-"," "))
- ๋ถ์ฉ์ด, ์ด๊ฐ์ถ์ถ ์ฌ์ ์ ์
en_stopwords = set(stopwords.words("english"))
en_stemmer = PorterStemmer()
- ์ํ๋ฒณ๋ง ๋จ๊ธฐ๊ธฐ, ์๋ฌธ์ํ, ํ ํฐํ, ๋ถ์ฉ์ด ์ ๊ฑฐ, ์ด๊ฐ์ถ์ถ
for doc in en_doc :
en_alphabet= re.sub(r"[^a-zA-Z]+", " ", str(doc))
en_tokenized = word_tokenize(en_alphabet.lower())
en_stopped = [ w for w in en_tokenized if w not in en_stopwords]
en_stemmed = [en_stemmer.stem(w) for w in en_stopped]
en_word_joined.append(' '.join(en_stemmed))
en_word.append(en_stemmed)
3. word2Vec ๋ถ์ ๋ฐ word ์ขํ ํ์ธ
- Word2Vec ์ค์
en_w2v_model = Word2Vec(en_word, vector_size=300, window=20, min_count=10, workers=4)
Word2Vec ํ์ดํผํ๋ผ๋ฏธํฐ
- vector_size : ์๋ ๋ฒกํฐ์ ํฌ๊ธฐ (์๋ฒ ๋ฉ ๋ ๋ฒกํฐ์ ์ฐจ์) -> Word2Vec, Doc2Vec์ ๊ฒฝ์ฐ ์ฐจ์ ์ฌ์ด์ฆ๋ฅผ 300~500 ์ฌ์ด๋ก ํ๋ ๊ฒ์ด ๊ฒฐ๊ณผ๊ฐ ๊น๋ํ๊ฒ ๋์จ๋ค๊ณ ๊ตฌ๊ธ์ด ์ ์ํ๋ค.
- window : ์ปจํ ์คํธ ์๋์ฐ ํฌ๊ธฐ (๊ณ ๋ คํ ์๋ค ๋จ์ด)
- min_count : ๋จ์ด ์ต์ ๋น๋ ์ ์ ํ
- workers : ํ์ต์ ์ํ ํ๋ก์ธ์ค ์ (๋์์ ์ฒ๋ฆฌํ ์์ ์)
- ๋ชจ๋ธ ๊ฒฐ๊ณผ๊ฐ ํ์ธ
print(en_w2v_model.wv['algorithm'])
๋ชจ๋ธ ๊ฒฐ๊ณผ์์ ๋จ์ด์ ์๋ ์ฐจ์ ๊ฐ ํ์ธ
(6 * 50 => 300์ฐจ์)
print(en_w2v_model.wv.most_similar('learn'))
- wv.most_similar() : ๊ฐ์ฅ ์ ์ฌํ ๋จ์ด ์ถ์ถ
print(en_w2v_model.wv.most_similar(['learn', 'deep']))
๋ ๋จ์ด์ ์กฐํฉ๊ณผ ๊ฐ์ฅ ๊ฐ๊น์ด 300์ฐจ์์์ ์์น๊ฐ ์ ์ฌ๋๋ก ๊ณ์ฐ๋๋ค.
print(en_w2v_model.wv.similarity('deep', 'learn'))
- wv.similarity : ๋ word vector์ ์ ์ฌ๋ ๋น๊ต
4. TSNE ๋ก ์ฐจ์ ์ถ์ ํ ์๊ฐํ
def tsne_plot(model) :
labels = [] # ์ด๋ฆ
tokens = [] # ์ขํ๊ฐ
for word in model.wv.vocab :
tokens.append(model[word])
labels.append(word)
tsne_modle = TSNE(perplexity=30, n_components=2, init='random', n_iter=250, random_state=23)
new_valus = tsne_model.fit_transform(tokens)
x = []
y = []
for value in new_values :
x.append(value[0])
y.append(value[1])
plt.figure(figsize = (16,16))
for i in range(len(x)) :
plt.scatter(x[i], y[i])
plt.annotate(labels[i],
xy = (x[i], y[i]),
xytext =( 5,2),
textcoords = 'offset points',
ha = 'right',
va = 'bottom')
plt.show()
TSNE
TSNE๋ ๊ณ ์ฐจ์ ๋ฐ์ดํฐ๋ฅผ ์๊ฐํํ๋ ๋๊ตฌ์ด๋ค. ์๊ฐํ๊ฐ ํธ๋ฆฌํ 2์ฐจ์์ด๋ 3์ฐจ์์ผ๋ก ์ฐจ์ ์ถ์๋ฅผ ์งํํ ํ, ์ค์ feature๊ฐ ์๋ ์ถ์๋ ์ฃผ์ฑ๋ถ์ ๊ธฐ์ค์ผ๋ก ๋ถํฌ๋ฅผ ๊ฐ์ ์ ์ผ๋ก ์๊ฐํํ๋ค.
TSNE ํ์ดํผํ๋ผ๋ฏธํฐ
- n_components : ์๋ฒ ๋ฉ ๊ณต๊ฐ์ ์ฐจ์
- perplexity : ํ์ต์ ์ํฅ์ ์ฃผ๋ ์ ๋ค์ ๊ฐ์ ์กฐ์
- init : ์ด๊ธฐํ ๋ฉ์๋
- n_iter : ์ต์ ํ์ ์ต๋ ๋ฐ๋ณต ํ์
- random_state : ๋์ ์์ฑ๊ธฐ ๊ฒฐ์
- ๊ทธ๋ํ
tsne_plot(en_w2v_model)
300์ฐจ์์ ๊ทธ๋ฆผ์ 2์ฐจ์์ผ๋ก ์์ถํ ๊ทธ๋ํ๋ก ์ฃผ์ฐจ์์ ์ํด ๋จ์ด๋ค์ด ๋ชฐ๋ ค์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค.
area, defin, two ... ์์๋ผ์ด์ด, ์ฆ ์ด์์น ๊ฐ์ผ๋ก ๊ด๊ณ๊ฐ ์ฝํ ๋จ์ด๋ค์ด๋ค. ํน์ ๋ ผ๋ฌธ์๋ง ์ฐ์๋ค๊ณ ํด์ํ ์ ์๋ค.
์ฐธ๊ณ ๊ฐ์ : ๋์๋ INSPIRE - python ํ ์คํธ๋ง์ด๋ 22๊ฐ Word2Vec Modeling ์ค์ต