[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

🛠 기타/Data & AI

워드 임베딩 - GloVe 기초활용

inu 2020. 7. 28. 12:09
반응형

기존방법의 문제점

  • Word2Vec은 중심단어로 주변단어를 예측하거나 주변단어로 중심단어를 예측하는 과정에서 단어를 벡터로 임베딩했다.
  • 하지만 이는 말뭉치의 전체적인 통계정보를 담지 못한다.
  • LSA는 단어의 빈도수를 카운트해 이를 기반으로 단어를 임베딩한다.
  • 이는 유사 단어 관계의 의미 유추 등에서 성능이 떨어진다.

GloVe

  • 두 단어 벡터의 내적이 말뭉치 전체에서의 동시 등장확률 로그값이 되도록 목적함수를 정의했다.
  • '임베딩된 단어벡터 간 유사도 측정을 수월하게 수행하고 동시에 말뭉치 전체의 통계 정보를 잘 반영해보자'가 Glove가 지향하는 핵심 목표라고 할 수 있다.

  • 위 표는 Glove 연구진이 예시로 든 것이다. 각 단어의 관계성에 따라 수치를 나타내고, P(solid |ice)/P(solid|steam)과 같은 값들은 상대적 수치를 나타낸다.
  • 특정 단어 k가 주어졌을 때 임베딩된 두 단어벡터의 내적이 두 단어의 동시등장확률 간 비율이 되게끔 임베딩한다. 즉, solid라는 단어가 주어지면 ice와 steam 사이의 내적값이 8.9가 되도록 하는 것이다.
  • Pik를 P(k|i)로 정의하여, i번째 단어 주변(윈도우 크기는 사용자 지정)에 k번째 단어가 등장할 조건부확률이라는 뜻으로 사용했다. (사용자가 미리 정한 윈도우 내에서 i번째 단어와 k라는 단어가 동시 등장한 빈도수를 i가 등장한 빈도수로 나누어준 값)
  • 즉, $F(wi,wj,wk~)=PikPjk$식을 만족하는 함수 F를 찾아내는 것이 연구진의 목표였다.
  • 자세한 원리를 알고 싶으면 아래 링크들을 참고해보자.
  • 참고1 : https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/04/09/glove/
  • 참고2 : https://wikidocs.net/22885

사용 예제

import csv
import re

def open_csv():
    # csv파일을 연다!
    f = open('IMDBDataset.csv', 'r', encoding='utf-8')
    csvreader = csv.reader(f)

    doc_list = []

    next(csvreader)
    for f in csvreader:
        line = re.compile("[^\w]").sub(' ', f[0].lower())
        doc_list.append(line.split())

    return doc_list

doc_list = open_csv()
  • IMDB 데이터셋(혹은 임의의 데이터셋)으로부터 값을 불러온다.
from glove import Corpus, Glove

corpus = Corpus()
# 주변 단어의 기준 5로 설정
corpus.fit(doc_list, window=5)
  • Corpus를 통해 데이터를 가공하여 동시 등장 행렬을 생성한다. 이를 기반으로 glove 모델을 학습시킬 것이다.
# 경사하강법 학습률 0.05, 아웃풋 벡터의 차원 100
glove = Glove(no_components=100, learning_rate=0.05)
# 쓰레드 개수는 4개, 훈련 횟수는 20번, verbose (설명) True
glove.fit(corpus.matrix, epochs=20, no_threads=4, verbose=True)
# 유사도 검색을 위한 행렬의 index 정보 입력
glove.add_dictionary(corpus.dictionary)
  • Glove의 no_components 옵션을 통해 아웃풋 벡터(임베딩 결과)의 차원를 결정한다.
  • fit의 verbose 옵션을 True로 설정하면 자세한 처리과정을 출력하여 확인시켜준다. (Epoch ...)
  • corpus 내부에는 dictionary로 각 단어의 index 정보가 저장되어 있는데, 최종적인 검색을 위해 이를 glove 모델에 추가해준다.
model_result1 = glove.most_similar("man")
print(model_result1)
==결과==
[('woman', 0.9621753707315267), ('guy', 0.8860281455579162), ('girl', 0.8609057388487154), ('kid', 0.8383640509911114)]
  • 최종적으로 벡터가 유사한 값들을 이와 같이 출력할 수 있다.
반응형