17-1. 들어가며


학습 목표

  • 원-핫 인코딩
  • Word2Vec의 CBoW, Skip-gram
  • Negative Sampling
  • FastText, GloVe

학습 내용

  • 벡터화

    • 텍스트 데이터의 벡터화 방법 학습
    • 벡터화 실습 : 원-핫 인코딩
  • 워드 임베딩

    • 희소 벡터 특징 및 문제점 학습
  • Word2Vec

    • 분포 가설
    • CBoW(Continuous Bag of words)
    • Skip-gram
    • Negative Sampling
    • 영어 Word2Vec 실습
    • OOV(Out Of Vocabuary) 문제
  • 임베딩 벡터 시각화

  • FastText

  • Glove


사전 준비

$ mkdir -p ~/aiffel/word_embedding


17-2. 벡터화


Bag of words

  • 단어 순서 고려하지 않음 ➡️ 단어 등장 빈도(frequency)로 벡터화

단점

  1. Sparsity
  • 단어 집합의 크기가 커질수록 발생하는 다차원 행렬에서 대부분의 값이 0으로 채워지는 문제
  1. Frequent words has more power
  • 자주 등장하는 단어가 과도한 가중치를 가지는 문제
  1. Ignoring word orders
  • 단어의 순서가 완전히 무시됨

4(Q). Out of Vocabulary?
A. 단어장에 없는 단어가 등장하여 대처할 수 없는 난감한 문제


DTM(Document-Term Matrix)

  • 문서 단어 행렬(문서가 행, 단어가 열)
  • Document-Term Matrix

Document
1 : you know I want your love
2 : I like you
3 : what should I do

  • DTM
    • 전처리 : 단어 길이가 1인 데이터 제거
    • 희소 벡터 : DTM의 벡터는 대부분 0의 값을 가짐
      • 문서 수 또는 단어 수가 많아질수록 문제가 됨
    • 열 개수 : 전체 텍스트 중 1번이라도 등장한 단어 개수
      • 중복을 제거하여 포함함
    • 단어장 : 중복을 제거한 단어 집합
    • V : 단어장 크기

TF-IDF

  • 단어마다 중요 가중치를 다르게 설정

What is Term Frequency?

  • TF measures how frequently a term occurs in a document
  • 단어들의 원-핫 벡터 합 / 문장 단어 개수와 같음

Why Term Frequency?

  • If a term occurs more times than other terms in a document, the term has more relevance than other terms for the document

What is IDF?

  • Inverse document frequency
  • Log(Total # of Docs / # of Docs with the term in it
  • Log(Total # of Docs / # of Docs with the term in it + 1) ➡️ For smoothing(avoid division by zero)

TF-IDF, DTM 공통점

  • 문서 벡터 크기 == 단어장 크기(V)
  • 문서 벡터, 단어 벡터 여전히 희소벡터

원-핫 인코딩(one-hot encoding)

  • 모든 단어의 관계를 독립 정의
  • 텍스트 데이터를 이용해 단어장을 만듦 ➡️ 단어장의 모든 단어를 대상으로 1 ~ V까지 정수 부여(인덱스)
  • 단어 : V차원 벡터(그 단어 인덱스 위치만 1, 나머지는 0)

  • Document(단어장 크기 : 5)

    1 : 강아지, 고양이, 강아지
    2 : 애교, 고양이
    3 : 컴퓨터, 노트북

⬇️

  • 고유 정수 부여(빈도수가 높은 단어들부터 낮은 숫자)

    강아지 : 1번
    고양이 : 2번
    애교 : 3번
    컴퓨터 : 4번
    노트북 : 5번
    +추가 전처리 : 정수가 큰 숫자 제거 등을 할 수도 있음

⬇️

각 단어를 V차원 벡터로 표현
강아지 : [1, 0, 0, 0, 0]
고양이 : [0, 1, 0, 0, 0]
애교 : [0, 0, 1, 0, 0]
컴퓨터 : [0, 0, 0, 1, 0]
노트북 : [0, 0, 0, 0, 1]

  • 이렇게 원-핫 인코딩으로 얻은 벡터가 원-핫 벡터(one-hot vector)


17-3. 벡터화 실습: 원-핫 인코딩 구현해보기

패키지 설치

$ pip install konlpy
  • 라이브러리 import
import re
from konlpy.tag import Okt
from collections import Counter
  • 원본 텍스트
text = "임금님 귀는 당나귀 귀! 임금님 귀는 당나귀 귀! 실컷~ 소리치고 나니 속이 확 뚫려 살 것 같았어."
text

전처리

  • 정규 표현식으로 특수문자 제거

  • [^ㄱ-ㅎㅏ-ㅣ가-힣 ]

    • 한글, 공백 제외 모든 문자 표현 regex
reg = re.compile("[^ㄱ-ㅎㅏ-ㅣ가-힣 ]")
text = reg.sub('', text)
print(text)


토큰화

  • KoNLPy 내장 Okt 형태소 분석기 사용
okt=Okt()
tokens = okt.morphs(text)
print(tokens)
['임금님', '귀', '는', '당나귀', '귀', '임금님', '귀', '는', '당나귀', '귀', '실컷', '소리', '치고', '나니', '속이', '확', '뚫려', '살', '것', '같았어']

단어장

  • 빈도수 높음 ➡️ 정수 작게
  • Counter 서브클래스로 빈도수 카운트
vocab = Counter(tokens)
print(vocab)
Counter({
	'귀': 4,
	'임금님': 2,
    '는': 2,
    '당나귀': 2,
    '실컷': 1,
    '소리': 1,
    '치고': 1,
    '나니': 1,
    '속이': 1,
    '확': 1,
    '뚫려': 1,
    '살': 1,
    '것': 1,
    '같았어': 1
})
  • most_common()
    • 상위 빈도수 단어만 리턴
    • 5개만 단어장에 저장
vocab_size = 5
vocab = vocab.most_common(vocab_size)
print(vocab)

  • 인덱스 부여
word2idx={word[0] : index+1 for index, word in enumerate(vocab)}
print(word2idx)

최종 단어장 : word2idx


원-핫 벡터

  • one_hot_encoding
    • 단어의 원-핫 벡터 리턴해주는 함수
def one_hot_encoding(word, word2index):
       one_hot_vector = [0]*(len(word2index))
       index = word2index[word]
       one_hot_vector[index-1] = 1
       return one_hot_vector
  • 임금님 단어 원-핫 벡터 보기
one_hot_encoding("임금님", word2idx)


keras one-hot encoding

  • Tenserflow Keras API 사용
    • Tokenizer : 단어장을 만듦
    • to_categorical : 원-핫 인코딩 도구
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.utils import to_categorical
  • 문서 3개 -> text에 저장
text = [['강아지', '고양이', '강아지'],['애교', '고양이'], ['컴퓨터', '노트북']]
text

  • Keras Tokenizer
    • 주어진 텍스트로부터 단어장 생성 & 정수 매핑
t = Tokenizer()
t.fit_on_texts(text)
print(t.word_index)

  • vocab_size
    • 단어장 크기 저장
    • +1을 하는 이유 : 0번 단어가 특별 토큰으로 추가되는 경우가 많기 때문(0번은 패딩 토큰으로 주로 사용)
vocab_size = len(t.word_index) + 1

현재 vocab_size는 6

  • 정수 시퀀스로 변환
sub_text = ['강아지', '고양이', '강아지', '컴퓨터']
encoded = t.texts_to_sequences([sub_text])
print(encoded)

  • to_categorical()
    • 원-핫 벡터 시퀀스로 변환
one_hot = to_categorical(encoded, num_classes = vocab_size)
print(one_hot)

결과 : 각 단어가 단어장 크기(6)인 6차원 벡터로 변환됨



17-4. 워드 임베딩


희소 벡터(Sparse Vector)의 문제점


빅데이터: 큰 용량의 역습 – 차원의 저주 (Curse of dimensionality)

  • 차원이 커질수록 ➡️ 훨씬 더 많은 데이터를 가지더라도 높은 성능을 내지 못함
    • 고차원 데이터(많은 양의 정보)일수록 그 데이터로부터 모델을 학습하기 어려워지고, 훨씬 더 많은 데이터양이 필요해짐

원-핫 벡터 문제점


워드 임베딩(Word Embedding)

  • 기계가 단어장 크기보다 적은 차원 밀집 벡터를 학습하는 것
    • 밀집 벡터 : 다양한 실수값 == 임베딩 벡터
  • 한 단어를 벡터로 바꾸는 것은 동일하나, 벡터 길이를 일정하게 정함
  • 단어가 많다는 것이 벡터 길이의 연장을 말하지 않음
  • 희소 벡터 ↔️ 밀집 벡터

밀집 벡터

  • 벡터 길이가 단어장 크기보다 매우 작음
  • 각 벡터 값에 정보 축약
  • 대부분 값이 0이 아님
  • 많은 의미를 함축

워드 임베딩의 단어 특성 계산 방법

  1. 특징 계산
  • 단어 간의 관계나 의미를 수식으로 나타내어 내적을 활용해 유사도 계산
  • 비슷한 의미의 단어는 내적이 크고, 반대되는 단어는 내적이 작도록 조정
  1. 통계 기반 방법
  • 초기 : 통계학을 이용한 복잡한 수식을 활용해 벡터 계산
  1. 신경망 기반 방법
  • 최근에는 인공 신경망을 학습시키는 과정에서 단어 벡터 값을 최적화함
  • 딥러닝처럼 손실 값을 기준으로 단어 벡터를 반복 조정하여 의미에 맞는 표현을 학습함(최적 벡터 학습)
//      [둥근,빨간,단맛,신맛]
사과  : [0.8, 0.7, 0.7, 0.1] // 0.8만큼 둥글고, 0.7만큼 빨갛고, 0.7만큼 달고, 0.1만큼 신 것은 사과다
바나나: [0.1, 0.0, 0.8. 0.0] // 0.1만큼 둥글고, 0.0만큼 빨갛고, 0.8만큼 달고, 0.0만큼 신 것은 바나나다
귤    : [0.7, 0.5, 0.6, 0.5] // 0.7만큼 둥글고, 0.5만큼 빨갛고, 0.6만큼 달고, 0.5만큼 신 것은 귤이다

워드 임베딩의 핵심 2가지

  1. 한 단어를 길이가 짧은 밀집 벡터로 구성하기
  2. 밀집 벡터는 단어의 의미, 단어 간 관계 등을 모두 내포함

Q. 임베딩 벡터 값이 얻어지는 방식
A. 신경망 모델이 단어 의미와 문맥을 자동으로 학습해 벡터 값이 조정됨
(답안): 훈련 데이터로부터 Language Model을 학습하는 과정에서 자동으로 얻어짐


워드 임베딩 모델

논문: A Neural Probabilistic Language Model

  • NPLM(Neural Probabilistic Language Model)

    • 2003년 요수아 벤지오 교수 제안
    • 학습 속도가 느린 단점
  • Word2Vec

    • 2013년 구글에서 NPLM 개선(정밀도, 속도 향상)
  • 그 이후, FastText 나 GloVe 등의 임베딩 방법 추가 제안



17-5 ~ 8. Word2Vec


(1) 분포 가설

  • Korean Word2Vec
    • 한국어 데이터로 Word2Vec 학습이 가능한 데이터
    • 연산 결과 제공

Q. 박찬호 - 야구 + 축구 결과는?
A. 호나우두/Noun



Word2Vec 메커니즘

What is Encoding?

  • Convert text to number

What is One Hot Encoding?

  • Convert text to vector

One Hot Encoding doesn't have similarity

  • every distances is same to each other

  • cosine similarity also 0 since angle is 90 degree


Embedding

  • dense vector with similarity

Word2Vec

  • word embedding Similarity comes from neighbor words

Word2Vec data generation(skipgram)

  • "king brave man"
  • "queen beautiful woman"
  • window size=1

  • window size=2


Word2Vec deep learning model input and target


Word2Vec training


hidden layer is the word2Vec


Word2Vec is hidden layer after train


because input is one hot encoding, hidden layer works as lookup table


Word2Vec gives similarity in vector representation



분포 가설(Distributional Hypothesis)

  • Word2Vec의 핵심 아이디어
  • "You shall know a word by the company it keeps"
    • 곁에 오는 단어들을 살펴보면 -> 그 단어를 파악할 수 있음
  • 비슷한 문맥에 같이 등장하는 경향이 있는 단어들의 경우, 유사한 의미를 가질 것이라는 가설
  • 분포 가설을 따르는 Word2Vec
    • 자주 함께 등장하는 단어들 간에 벡터 유사도를 높임
    • 강아지, 애교, 귀여운 : 의미적으로 비슷한 단어들이 비슷한 벡터로 표현됨


(2) CBoW(Continuous Bag of words)

  • 주변에 있는 단어들로 ➡️ 중간에 있는 단어 예측

"I like natural language processing."

CBoW의 역할

  • {"i", "like", "language", "processing"}로 ➡️ "natural" 예측
  • "natural" : 중심 단어
  • 예측에 사용되는 단어 : 주변 단어

Window

  • 중심 단어 예측을 위한 앞, 뒤 단어 개수 결정
  • ex) 윈도우 크기 1, 중심 단어 "language"
    • 앞에 있는 단어 1개 : "natural"
    • 뒤에 있는 단어 1개 : "processing"
  • 즉, 윈도우 크기가 m -> 주변 단어 개수는 2m

sliding window

  • 윈도우 크기를 정하고, 윈도우를 계속 움직여 주변 단어와 중심 단어를 바꿔가면서 학습 데이터셋 생성하는 방법

윈도우 크기가 1일 때, 하나의 샘플 문장에 대한 데이터셋 생성 과정((주변 단어의 셋), 중심 단어)

  • ((like), I), ((I, natural), like), ((like, language), natural), ((natural, processing), language), ((language), processing)
  • 각각의 단어가 원-핫 인코딩됨 ➡️ 원-핫 벡터가 됨
  • 원-핫 벡터가 ➡️ CBoW or Skip-gram 입력이 됨

CBoW

  • 원-핫 벡터로 표현된 주변 단어들을 사용해, 그에 맞는 중심 단어를 예측하는 메커니즘
  • 목적 : 윈도우 크기가 m인 경우, 2m개의 주변 단어로 1개의 중심 단어 예측 과정에서의 2개의 가중치 행렬 학습
  • 2개의 가중치 행렬
    • WW : 첫번째 가중치 행렬(주황)
    • WW' 두번쨰 가중치 행렬(초록)
  • 입력층, 은닉층, 출력층의 3개 층으로만 구성된 인공신경망

    Word2Vec은 은닉층이 1개이기 때문에 얕은 신경망 학습이라고 봐야함!

  • 입력층 : 주변 단어 원-핫 벡터
  • 출력층 : 중심 단어 원-핫 벡터

  • 입력층 및 출력층 크기 : V로 고정(원-핫 벡터 표현이기 때문)
  • 은닉층 크기 : 사용자 정의 하이퍼파라미터(N)

  • 입력층에서 은닉층으로 가는 과정(가중치 행렬 크기 (5x4)의 룩업 테이블)
    • 단어장 크기 5, 은닉층 크기 4
    • 주변 단어 원-핫 벡터 = 첫번째 가중치 행렬과 곱해짐
    • 가중치 행렬 크기 : V x N
    • 원-핫 벡터 및 가중치 행렬과의 곱 == 가중치 행렬 i 행을 가져오는 것

은닉층 연산

  • 룩업 테이블을 통해 생긴 2m개 주변 단어 벡터 : 크기 N
  • cBoW는 벡터의 총합 or 평균값을 최종 은닉층 결과로 도출
  • 최종 은닉층 결과 역시 N차원 벡터가 됨
    • 은닉층에서의 활성화 함수 or 편향(bias) 더하는 연산 안함 == 투사층(projection layer)이라고 불리는 이유

은닉층 ➡️ 출력층 과정 & 출력층 연산

  • 은닉층의 N차원 벡터 -> 두번쨰 가중치 행렬과 곱함
    • 가중치 행렬 크기가 N×V이니 곱셈 결과 벡터 차원은 V
  • 출력층 : 활성화 함수로 softmax 사용하기 때문에 결과적으로, 모든 차원 총합이 1인 벡터로 바뀜

CBoW의 핵심

  • 출력층 벡터중심 단어의 원-핫 벡터 손실을 최소화하는 방식으로 학습
    • WW, WW' 업데이트
    • 학습 완료 : N차원 크기를 갖는 WW 행 or WW' 열 중에서 사용할 임베딩 벡터를 결정
      • WW, WW'의 평균치를 선택하기도 함

정리

  • 주변 단어를 통해 중간 단어 예측
    • 한계
      • OOV
      • Polysemy
      • 문맥 파악 어려움


(3) Skip-gram과 Negative Sampling

Skip-gram

  • 중심 단어로부터 주변 단어 예측
  • CBoW와 데이터셋 구성이 다름
    • (중심 단어, 주변 단어)로 가정
    • (i, like) (like, I), (like, natural), (natural, like), (natural, language), (language, natural), (language, processing), (processing, language)

CBoW와의 차이점

  • 중심 단어로부터 주변 단어 예측
  • 은닉층에서 다수 벡터의 덧셈, 평균을 구하는 부분이 없음

공통점

  • 가중치 행렬 WW 행 또는 WW' 열에서 임베딩 벡터를 얻음

네거티브 샘플링(negative sampling)

  • 대부분의 Word2Vec은 SGNS(Skip-Gram with Negative Sampling) 사용

    • 연산량 감소를 통한 효율적 사용을 할 수 있음
  • 기존 다중 클래스 분류 문제 ➡️ sigmode 함수를 사용하는 이진 분류 문제

    • softmax 함수를 사용한 V개 중의 1개를 고름
    • 중심 단어, 주변 단어가 입력값 ➡️ 이웃 관계라면 ➡️ 1 or 0 출력하도록 변경

  • Skip-gram 학습 과정
    • 출력층에서 softmax 함수를 통과한 V차원 벡터, V차원 주변 단어 원-핫 벡터의 오차를 구함
    • 역전파로 모든 단어 임베딩 벡터 조정
    • 작업이 매우 느린 이슈가 있음

  • 예시로 확인해보기

    "Thou shalt not make a machine in the likeness of a human mind"

  • 윈도우 크기: 2, input word: 중심 단어, target word: 주변 단어

  • 레이블 지정

    • 슬라이딩 윈도우를 거친 정상 데이터셋은 1
    • 실제 이웃 관계가 아닌 경우 0(중심 단어와 주변 단어 관계가 아닌 경우)
    • 즉, 랜덤으로 단어장의 단어를 가져와 target word 거짓 데이터셋을 만들어 0으로 레이블링하는 것
  • 거짓 데이터셋 생성 관정

  • 중심 단어 및 주변 단어 내적 + 출력층 시그모이드 함수를 통과 = 1 or 0 레이블로부터 오차 구하기 및 역전파 수행



(4) 영어 Word2Vec 실습과 OOV 문제

영어 Word2Vec 실습

  • gensim : 토픽 모델링 NLP 패키지
  • NLTK 제공 코퍼스
$ pip install nltk
$ pip install gensim
  • NLTK 내장 코퍼스 다운로드
import nltk
nltk.download('abc')
nltk.download('punkt')

  • corpus 변수에 저장
from nltk.corpus import abc
corpus = abc.sents()
print(corpus[:3])
[['PM', 'denies', 'knowledge', 'of', 'AWB', 'kickbacks', 'The', 'Prime', 'Minister', 'has', 'denied', 'he', 'knew', 'AWB', 'was', 'paying', 'kickbacks', 'to', 'Iraq', 'despite', 'writing', 'to', 'the', 'wheat', 'exporter', 'asking', 'to', 'be', 'kept', 'fully', 'informed', 'on', 'Iraq', 'wheat', 'sales', '.'], ['Letters', 'from', 'John', 'Howard', 'and', 'Deputy', 'Prime', 'Minister', 'Mark', 'Vaile', 'to', 'AWB', 'have', 'been', 'released', 'by', 'the', 'Cole', 'inquiry', 'into', 'the', 'oil', 'for', 'food', 'program', '.'], ['In', 'one', 'of', 'the', 'letters', 'Mr', 'Howard', 'asks', 'AWB', 'managing', 'director', 'Andrew', 'Lindberg', 'to', 'remain', 'in', 'close', 'contact', 'with', 'the', 'Government', 'on', 'Iraq', 'wheat', 'sales', '.']]
  • 코퍼스 크기 확인
print('코퍼스의 크기 :',len(corpus))

  • Word2Vec 훈련
    • vector size : 학습 후 임베딩 벡터 차원
    • window : context window 크기
    • min_count : 단어 최소 빈도수 제한
    • workers : 학습 프로세스 수
    • sg : 0(CBoW), 1(Skip-gram)
from gensim.models import Word2Vec

model = Word2Vec(sentences = corpus, vector_size = 100, window = 5, min_count = 5, workers = 4, sg = 0)
print("모델 학습 완료!")

  • model.wv.most_similar
    • 코사인 유사도가 높은 단어 출력
model_result = model.wv.most_similar("man")
print(model_result)
[('woman', 0.9233373999595642), ('skull', 0.911032497882843), ('Bang', 0.9056490063667297), ('asteroid', 0.9051957130432129), ('third', 0.9020178318023682), ('baby', 0.8993921279907227), ('dog', 0.8985978364944458), ('bought', 0.8975234031677246), ('rally', 0.8912491798400879), ('disc', 0.8888981342315674)]
  • 모델 저장 & 로드
from gensim.models import KeyedVectors

model.wv.save_word2vec_format('~/aiffel/word_embedding/w2v') 
loaded_model = KeyedVectors.load_word2vec_format("~/aiffel/word_embedding/w2v")
print("모델  load 완료!")

  • 로드한 모델 확인
model_result = loaded_model.most_similar("man")
print(model_result)
[('woman', 0.9233373999595642), ('skull', 0.911032497882843), ('Bang', 0.9056490063667297), ('asteroid', 0.9051957130432129), ('third', 0.9020178318023682), ('baby', 0.8993921279907227), ('dog', 0.8985978364944458), ('bought', 0.8975234031677246), ('rally', 0.8912491798400879), ('disc', 0.8888981342315674)]

Word2Vec의 OOV 문제

  • 사전에 없는 단어 overacting ➡️ KeyError
loaded_model.most_similar('overacting')

  • 오타가 있는 경우
    • memory의 오타인 memorry
loaded_model.most_similar('memorry')



17-9. 임베딩 벡터의 시각화


임베딩 프로젝터(embedding projector)

  • 구글이 공개한 임베딩 벡터 시각화 오픈 소스
  • 군집 확인, 특정 임베딩 벡터와의 유클리드 거리, 코사인 유사도 확인 가능
  • 저장된 모델 필요

파일 생성

  • w2v 모델(저장한 모델)을 이용해 벡터값 지정 파일 및 메타 파일 얻기
    • w2v_metadata.tsv, w2v_tensor.tsv
$ python -m gensim.scripts.word2vec2tensor --input ~/aiffel/word_embedding/w2v --output ~/aiffel/word_embedding/w2v

임베딩 프로젝터에 tsv 파일 업로드

  1. Load 클릭 > w2v_tensor.tsv, w2v_metadata.tsv 업로드

  2. Search 버튼 or 그래프 포인트로 원하는 단어 선택 > neighbors로 이웃 개수 지정

  • distance : COSINE or EUCLIDEAN으로 거리 측정 메트릭 지정



17-10. FastText


FastText

  • 페이스북에서 개발
  • Word2Vec 이후의 워드 임베딩 방법
  • 문자 단위 n-gram(character-level n-gram) 표현 학습

Word2Vec vs FastText

  • Word2Vec : 단어를 더 이상 깨질 수 없는 단위로 구분
  • FastText : 단어 내부의 내부 단어(subwords) 학습

  • n-gram
    • n : 단어 분리 결정 하이퍼파라미터
      • ex) n=3인 경우
        • 시작 : <, 끝 : > 도입 ➡️ <pa, par, art, rti, tia, ial, al> + 기존 단어에 <>를 붙인 <partial>

  • 실제 사용 시에는 n의 최솟값 및 최댓값 범위 설정 가능

    • gensim 패키지 디폴트 값 : 3, 6
  • 이렇게 생성된 단어들 각각에 대한 Word2Vec을 수행함

partial = <pa + par + art + rti + ita + ial + al> + <par + arti + rtia + tial + ial> + <part + ...중략...  + <partial>

FastText의 학습 방법

  • 네거티브 샘플링을 통해 학습
    • Word2Vec과의 차이점 : 중심 단어에 속한 문자 단위 n-gram 단어 벡터 모두 업데이트함

OOV와 오타에 대한 대응

  • 오타에 robust하기 떄문에, 단어장에 단어가 없어도 n-gram이 다른 단어에 있다면 ➡️ 벡터값을 구할 수 있음

  • FastText 학습

from gensim.models import FastText
fasttext_model = FastText(corpus, window=5, min_count=5, workers=4, sg=1)
print("FastText 학습 완료!")

  • FastText 모델에 입력
    • overacting과 코사인 유사도가 높은 단어 보기
fasttext_model.wv.most_similar('overacting')

  • 오타 단어 : memoryy
fasttext_model.wv.most_similar('memoryy')

유사 단어로 memory 출력


한국어에서의 FastText

  • 음절 단위 FastText

    • n = 3일 경우 텐서플로우 트라이그램 벡터 구성
      • <텐서, 텐서플, 서플로, 플로우, 로우>, <텐서플로우>
  • 자소 단위 FastText

    • 초성, 중성, 종성 분리(종성이 없는 경우는 _를 사용)
    • <ㅌㅔ,ㅌㅔㄴ,ㅔㄴㅅ,ㄴㅅㅓ,ㅅㅓ_, ...중략... >


17-11. GloVe


글로브(Global Vectors for Word Representation, GloVe)

  • 2014년 미국 스탠포드 대학에서 개발(워드 임베딩 방법론)
  • 카운트 기반, 예측 기반 모두 사용

잠재 의미 분석(LSA, Latent Semantic Analysis)

  • 단어-문서행렬(Word-Document Matrix), 단어-문맥행렬(window based co-occurrence matrix) 등의 입력 데이터에 특이값 분해 수행 ➡️ 차원수 축소로 계산 효율성 UP

  • truncated SVD 사용

    • Σ 행렬 특이값(대각 원소) 중 상위 t개만 골라냄
    • 원본 행렬은 복구 불가하나, 근사 가능

Q. 행렬 A에 대해 특이값 분해 변형인 thin SVD, compact SVD, Truncated SVD을 사용했을 경우 중 행렬 A 복구가 가능한 특이값 분해는?
A. Thin SVD, Compact SVD(Truncated SVD의 경우에는 근사 복원까지만 가능함)


LSA 요약

  • DTM에 특이값 분해를 사용해 잠재 의미를 찾는 방법론
    • 결과 행벡터를 통해 임베딩 벡터를 얻음
  • 카운트 기반 임베딩 방법에 속함

한계점 2가지

  • 차원 축소의 재사용 불가 : 새 단어 추가시 DTM을 다시 만들어 다시 차원 축소를 해야함
  • 단어 벡터간 유사도 계산 측면 : Word2Vec보다 성능 떨어짐

즉, 카운트 기반 및 예측 기반 방식을 모두 사용해 Word2Vec보다 나은 임베딩 방법인 Glove 제안


윈도우 기반 동시 등장 행렬(Window based Co-occurrence Matrix)

Example corpus(윈도우 크기 1)

  • I like deep learning.
  • I like NLP.
  • I enjoy flying.
  • 행, 열을 단어장 단어들로 구성
  • i 단어의 윈도우 크기 내 k 단어 등장 숫자를 i행 k열에 기재한 행렬
    • 전치해도 동일 행렬이 되는 특징이 있음!

동시 등장 확률(Co-occurrence Probability)

  • 동시 등장 확률 P(ki)P(k|i)
    • i : 중심 단어, k : 주변 단어
    • 동시 등장 행렬의 특정 단어 i에 대한 전체 등장수를 카운트
    • 특정 단어 i가 등장했을 때의 단어 k가 등장한 횟수를 카운트 및 계산한 조건부 확률
    • ex) ice 등장 -> solid 등장 확률 : large, stream 등장 -> solid 등장 확률 : small
      • 의미상 얼음이라는 의미를 갖는 ice와 더 자주 등장할 것이기 때문
      • P(solidice)P(solidstream))P(solid|ice) \over P(solid|stream)) 계산값은 1보다 매우 큰 값
        • P(solid|ice) 값을 크고, P(solid|stream)는 작음


GloVe 손실 함수 설계

  • 동시 등장 행렬로 계산된 동시 등장 확률로 손실 함수 설계
    • "동시 등장 행렬의 사용" : 코퍼스의 전체 통계 정보 활용(카운트 기반)
    • "손실 함수 설계" : 예측 기반

"중심 단어 벡터, 주변 단어 벡터 내적 ➡️ 전체 코퍼스의 동시 등장 빈도 로그값이 되도록 한다."

  • 전체 코퍼스에서의 동시 등장 빈도 로그값, 중심 단어 벡터 - 주변 단어 벡터 내적값 최소화할 수 있도록 두 벡터 값을 학습

GloVe 변수 정의


GloVe 손실 함수

J=Σi,j=1Vf(Xij)(wiTw~j+bi+b~jlogXij)²J = Σ_{i,j=1}^{V} f(X_{ij}) (w_i^T w̃_j + b_i + b̃_j - log X_{ij})²

  • 중심 단어 - 주변 단어 벡터 내적 ➡️ 동시 등장 빈도 로그값 차이를 최소화하도록 설계

  • 동시 등장 행렬에서의 동시 등장 빈포 값 f(Xik)f(X_{ik})가 극히 낮은 경우
    • 유의미하지 않은 정보로 파악
    • 가중치 함수를 도입하여 불용어의 동시 등장 빈도수가 높은 경우의 지나친 가중을 막음
      • 지나친 가중치 방지를 위해 최댓값은 1로 설정


pre-trained GloVe 모델 실습

  • 최신 버전 파이썬에서는 GloVe 사용 불가
    • pre-trained된 GloVe 모델로 실습
      • 주의점 : 알파벳 소문자만 인식함

GloVe word vector

  • Common Crawl (42B tokens, 1.9M vocab, uncased, 300d vectors, 1.75 GB download)
  • Common Crawl (840B tokens, 2.2M vocab, cased, 300d vectors, 2.03 GB download)
  • Wikipedia 2014 + Gigaword 5 (6B tokens, 400K vocab, uncased, 300d vectors, 822 MB download)
  • Twitter (2B tweets, 27B tokens, 1.2M vocab, uncased, 200d vectors, 1.42 GB download)

  • Wikipedia 2014 + Gigaword 5 데이터셋 학습 모델 사용
import gensim.downloader as api
glove_model = api.load("glove-wiki-gigaword-50")
glove_model.most_similar("dog")

glove_model.most_similar('overacting')

glove_model.most_similar('memoryy')

GloVe 역시 OOV 문제가 있음

profile
언젠가 내 코드로 세상에 기여할 수 있도록, Data Science&BE 개발 기록 노트☘️

0개의 댓글

관련 채용 정보