์ฌ์ ํ๋ จ๋ ๋จ์ด ์๋ฒ ๋ฉ ์ด์ฉํ๊ธฐ
5์ฅ์์ ๋ค์ ๋จ์ด ์๋ฒ ๋ฉ์ ํ์ตํ๋ CBOW ๋ชจ๋ธ์ ๋ํด ๊ฐ๋ตํ๊ฒ ๊ณต๋ถํ ์์ ์ด์ง๋ง, ์ค์ง์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ์๋ก์ด ๋จ์ด ์๋ฒ ๋ฉ ํ์ต ์๊ณ ๋ฆฌ์ฆ์ ๋ง๋ค ์ผ์ ๊ฑฐ์ ์๊ธฐ ๋๋ฌธ์, ๊ธฐ์กด์ ์ ๋ง๋ค์ด์ง ๋จ์ด ์๋ฒ ๋ฉ์ ๊ฐ์ ธ์ ๋ชจ๋ธ์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณผ ๊ฒ์
๋๋ค.
ย
์ธํฐ๋ท์ ๋ฌด๋ฃ๋ก ๊ณต๊ฐ๋์ด์๋ ๋ค์ํ ๋จ์ด ์๋ฒ ๋ฉ ์ค, ์คํ ํฌ๋ ๋ํ๊ต์ GloVe ์๋ฒ ๋ฉ์ ์ด์ฉํด๋ณด๊ฒ ์ต๋๋ค.
GloVe ์๋ฒ ๋ฉ ๋ค์ด๋ฐ๊ธฐ
์คํ ํฌ๋ ๋ํ๊ต์ ์นํ์ด์ง์์ Download pre-trained word vectors ์ค ๋ง์์ ๋๋ ๊ฒ์ ์ ํํด ๋ค์ด๋ก๋ํฉ๋๋ค. ์ ๋ ๊ฐ์ฅ ์ฉ๋์ด ์ ์ glove.6B.zip์ ์ ํํ์ต๋๋ค.
ย
Google Colab์์ ๋จ์ด ์๋ฒ ๋ฉ ํ์ผ ๋ก๋ํ๊ธฐ
๊ตฌ๊ธ Colab์์ ๋จ์ด ์๋ฒ ๋ฉ์ ๋ถ๋ฌ์ ์ฝ๋๋ฅผ ์คํํ ์ ์๊ฒ ํ๋ ๋จ๊ณ์
๋๋ค. ๋ก์ปฌํ๊ฒฝ์์ ์ฝ๋๋ฅผ ์คํํ๋ ๊ฒฝ์ฐ์๋ ํ์์๋ ๊ณผ์ ์
๋๋ค.
ย
๋จผ์ ๋ค์ด๋ฐ์ ์๋ฒ ๋ฉ ํ์ผ์ ๊ตฌ๊ธ ๋๋ผ์ด๋ธ์ ์
๋ก๋ํด์ค๋๋ค. ์ ๋ GloVe ํด๋ ์งธ๋ก Colab Notebooks์ ๋ฃ์ด์ฃผ์์ต๋๋ค.
ย
๋ค์, ๊ตฌ๊ธ ๋๋ผ์ด๋ธ์ colab์ ์ฐ๊ฒฐํด์ค๋๋ค.
from google.colab import drive drive.mount('/content/gdrive')
ย
๊ทธ ๋ค์, file_path์ ๋ด๊ฐ ๋ฐฉ๊ธ ๋ฃ์ด์ค ํ์ผ์ ์ฃผ์๋ฅผ ์ ์ด์ค๋๋ค.
file_path = '/content/drive/MyDrive/Colab Notebooks/glove/glove.6B.100d.txt'
ํ์ผ ์ฃผ์๋ ์ผ์ชฝ ํด๋ ํญ์ผ๋ก ๋ค์ด๊ฐ์ ํ์ผ์ ์ ํํ๋ฉด ์ฝ๊ฒ ๊ฒฝ๋ก ๋ณต์ฌ๋ฅผ ํ ์ ์์ต๋๋ค ๐
ย
์ด์ ํ์ผ๋ช
๋์ ,
file_path
๋ฅผ ์ ๋ฌํด์ฃผ๋ฉด ํด๋น ํ์ผ์ colab์์๋ ํ์ฉํ ์ ์์ต๋๋ค!ย
Colab์ ๊ธฐ์ค์ผ๋ก ์ค๋ช
ํ๊ฒ ์ต๋๋ค. ์ฐ์ , annoy ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํด์ค๋๋ค. annoy ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Approximate Nearest Neighbors Oh Yeah ์ ์ค์๋ง๋ก, ๊ณต๊ฐ ๋ด์์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฒกํฐ๋ฅผ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ์
๋๋ค. ์ค์ ๋ก spotify ์์ ์์
์ ์ถ์ฒํ ๋ ํ์ฉ๋์ด์ง๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์
๋๋ค.
!pip install annoy
ย
์๋ ์ฝ๋์ ๊ฐ์ด,
PreTrainedEmbeddings
๋ฅผ ์ ์ํด์ค๋๋ค.import numpy as np from annoy import AnnoyIndex class PreTrainedEmbeddings(object): def __init__(self, word_to_index, word_vectors): self.word_to_index = word_to_index self.word_vectors = word_vectors self.index_to_word = {v: k for k, v in self.word_to_index.items()} self.index = AnnoyIndex(len(word_vectors[0]), metric = 'euclidean') for _, i in self.word_to_index.items(): self.index.add_item(i, self.word_vectors[i]) self.index.build(50) # ๋จ์ด๋ฅผ ์ ๋ ฅํ๋ฉด ๋จ์ด ์๋ฒ ๋ฉ ๊ฐ(ํ๋ ฌ๊ฐ)์ ์ถ๋ ฅ def get_embedding(self, word): return self.word_vectors[self.word_to_index[word]] # ๋ฒกํฐ๋ฅผ ์ ๋ ฅํ๋ฉด ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฒกํฐ๋ฅผ ํ๋ ์ฐพ์ def get_closest_to_vector(self, vector, n=1): nn_indices = self.index.get_nns_by_vector(vector, n) return [self.index_to_word[neighbor] for neighbor in nn_indices] # ๋จ์ด 3๊ฐ๋ฅผ ์ ๋ ฅํ๋ฉด, word1, word2์ ๋์ผํ ๊ด๊ณ๋ฅผ ๊ฐ๋ word3์ ๋จ์ด์ word4๋ฅผ ์ฐพ์์ ์ถ๋ ฅ def compute_and_print_analogy(self, word1, word2, word3): vec1 = self.get_embedding(word1) vec2 = self.get_embedding(word2) vec3 = self.get_embedding(word3) spatial_relationship = vec2 - vec1 vec4 = vec3 + spatial_relationship closest_words = self.get_closest_to_vector(vec4, n=4) existing_words = set([word1, word2, word3]) closest_words = [word for word in closest_words if word not in existing_words] if len(closest_words) == 0: print("๊ณ์ฐ๋ ๋ฒกํฐ์ ๊ฐ์ฅ ๊ฐ๊น์ด ์ด์์ ์ฐพ์ ์ ์์ต๋๋ค!") return for word4 in closest_words: print("{} : {} :: {} : {}".format(word1, word2, word3, word4)) @classmethod def from_embeddings_file(cls, embedding_file): word_to_index = {} word_vectors = [] with open(embedding_file) as fp: for line in fp.readlines(): line = line.split(" ") word = line[0] vec = np.array([float(x) for x in line[1:]]) word_to_index[word] = len(word_to_index) word_vectors.append(vec) return cls(word_to_index, word_vectors)
ย
์ด์ , ๋ค์ด๋ก๋ํ GloVe ํ์ผ์ ์ด์ฉํด ํ์ต์ ์งํํ๋ฉด ์ ํ๋ จ๋ ๋จ์ด ์๋ฒ ๋ฉ์ ์ฐ๋ฆฌ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
embeddings = PreTrainedEmbeddings.from_embeddings_file(file_name)
ย
ย
๋ช ๊ฐ์ง ์ฌ๋ฏธ์๋ ์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
compute_and_print_analogy
๋ฉ์๋๋ฅผ ํตํด 3๊ฐ์ง ๋จ์ด๋ฅผ ์
๋ ฅํ์ ๋ word1, word2์ ๊ด๊ณ์ ๋์ผํ ๊ด๊ณ๋ฅผ ๊ฐ๋ word3์ ์, word4๋ฅผ ์ถ๋ ฅํด๋ณผ ์ ์์ต๋๋ค. ย
embeddings.compute_and_print_analogy('man', 'he', 'woman') >>> output man : he :: woman : she embeddings.compute_and_print_analogy('fly', 'plane', 'sail') >>> output fly : plane :: sail : ship embeddings.compute_and_print_analogy('cat', 'kitten', 'dog') >>> output cat : kitten :: dog : puppy embeddings.compute_and_print_analogy('blue','color', 'dog') >>> output blue : color :: dog : pets embeddings.compute_and_print_analogy('food', 'delicious', 'cat') >>> output food : delicious :: cat : adorable
ย
์ ์์์์ man์ he๋ผ๊ณ ํ๋ค๋ฉด woman์ she๋ผ๊ณ ํ๋ค๋ ๊ฒ์ ์ ํ์
ํ๊ณ ์์ต๋๋ค.
blue๊ฐ color์ ํฌํจ๋๋ค๋ ๊ด๊ณ๋ฅผ ์ ์ดํดํ๊ณ dog๊ฐ pets์ ํฌํจ๋๋ค๊ณ ์ถ๋ ฅํ๋ ๊ฒ๋ ๋ณผ ์ ์์ต๋๋ค.
food๊ฐ deliciousํ๋ค๊ณ ํ ๋, cat์ adorableํ๋ค๊ณ ํ๋ฉฐ, ์์ ๊ด๊ณ๋ ์ ํ์
ํ๊ณ ์์์ ์ ์ ์์ต๋๋ค.
ย
๋ฌผ๋ก ํ๋ก๊ทธ๋จ์ด ์ด ๋จ์ด๋ค์ ์๋ฏธ์ ๊ด๊ณ๋ฅผ ๋ชจ๋ ์๊ณ ์ด๋ฌํ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋ ๊ฒ์ ์๋๋๋ค. ํ์ต ๊ณผ์ ์์ ๋จ์ด๋ค์ด ์์ฃผ ๊ฐ์ด ๋ฑ์ฅํ ์๋ก ๋จ์ด๋ผ๋ฆฌ์ ์ ์ฌ๋๊ฐ ๋๋ค๊ณ ํ๋จํ๋ฉฐ ์๋ฒ ๋ฉ ๋ฒกํฐ ๊ณต๊ฐ ๋ด์์ ์ ์ฌํ ์๋ฏธ๋ฅผ ๊ฐ๋๋ก(๊ฐ๊น์ด ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ๋๋ก) ๋จ์ด๋ค์ ๋ฐฐ์นํฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ํตํด ํ์ตํ๋ฉด์ ๋จ์ด ๋ฒกํฐ๊ฐ์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ ์กฐ์ ํ์ฌ ๋ฐ์ดํฐ๋ค์ ๊ฐ์ฅ ์ ๋ํ๋ด๋ ์์น์ ๋๊ฒ ๋๊ณ , ์ด๋ฅผ ๋ฐํ์ผ๋ก ๋จ์ด ๊ฐ์ ๊ด๊ณ๋ฅผ ์ถ๋ ฅํ๊ฒ ๋ฉ๋๋ค.
ย
๊ทธ๋ฌ๋, ์ด๋ฌํ ์๋ฒ ๋ฉ์ ์ฌ์ฉํ ๋๋ ์ฃผ์ํด์ผ ํ๋ ๋ถ๋ถ์ด ํ๋ ์์ต๋๋ค. ์ธํฐ๋ท์ด๋ ๋ฌธ์ํ๋ ๊ธ๋ค์ ํ์ต๋ฐ์ดํฐ๋ก ํ์ฉํ๊ธฐ ๋๋ฌธ์, ์ธํฐ๋ท ๊ธ ๋ฑ์ ํฌํจ๋์ด ์๋ ์ ๋ฐ์ ์ธ ์ธ์ด์ฌ์ฉ์๋ค์ ๊ณ ์ ๊ด๋
์ด๋ ํธ๊ฒฌ์ด ์๋ฒ ๋ฉ ๊ณผ์ ์ ๋ฐ์๋์ด ๋ํ๋ ์ ์์ต๋๋ค. ์๋์ ์์์ฒ๋ผ ํ์ต ๋ฐ์ดํฐ์ ํธ๊ฒฌ์ ์ํด ๋ํ๋๋ man-doctor / woman-nurse ์ ๊ฐ์ ํธํฅ์ฑ์ ์ ์ํด์ผ ํฉ๋๋ค.
ย
embeddings.compute_and_print_analogy('man', 'doctor', 'woman') >>> output man : doctor :: woman : nurse man : doctor :: woman : pregnant
ย
์ด๋ฌํ ํธํฅ์ฑ์ ์ด๋ป๊ฒ ์ ๊ฑฐํด์ผ ํ ๊ฒ์ธ๊ฐ ์ญ์ NLP ๋ถ์ผ๊ฐ ๋ ์ค๋ฅด๋ฉด์ ํจ๊ป ์ฃผ๋ชฉ๋ฐ๊ณ ์๋ ํฅ๋ฏธ๋ก์ด ์ฐ๊ตฌ ๋ถ์ผ ์ค ํ๋์
๋๋ค.
ย
์ด์ ๊ธ ์ฝ๊ธฐ
๋ค์ ๊ธ ์ฝ๊ธฐ
ย