반응형

단어표현방법(word representation)

  • DTM: Document-Term Matrix (문서 단어 행렬)
  • LSA: Latent Semantic Analysis (잠재 의미 분석)

  • N-gram : N(숫자)가 2라면 2글자씩 토큰으로 만든다.
  • Glove : Count랑 Word2Vec이랑 합친것
  • LSA : 문서 전체에서 count하는 방법

 

Bag of Words (BoW)

  • 단어들의 순서는 전혀 고려하지 않고, 단어들의 출현 빈도를 활용하는 단어 표현 방법
  • 단어들의 가방이라는 뜻으로 모든 단어를 가방에 넣어서 표현한다는 의미
  • BoW를 만드는 과정
    1. 각 단어에 고유한 정수 인덱스를 부여
      → one hot vector에서 처음에 vocab을 생성했던 부분과 동일
    2. 각 인덱스의 위치에 단어 토큰의 등장 횟수를 기록한 벡터를 생성

예시

 

Bag of Words 실습

  • 형태소 분석기 활용
!pip install konlpy

from konlpy.tag import Kkma

import nltk
from nltk.tokenize import sent_tokenize

nltk.download('punkt')

class Tokenizer:
  def __init__(self):
    self.kkma = Kkma()

  def make_vocab(self, documents):
    word2index = {'<unk>':0}
    for document in documents:
      tokens = self.tokenize(document)
      for voca in tokens:
        if voca not in word2index.keys(): # voca가 key 리스트에 없으면 리스트에 추가
          word2index[voca] = len(word2index)
    self.vocab = word2index

	# 형태소 분석
  def tokenize(self, document):
    morphs = []
    sentences = sent_tokenize(document)

    for sentence in sentences:
      sentence_morphs = self.kkma.pos(sentence)
      morphs.extend([morph[0] + '/' + morph[1] for morph in sentence_morphs])

    print(morphs)
    return morphs
  
	# BOW
  def bag_of_words(self, sentence):
    morphs = self.tokenize(sentence)
    vector = [0] * len(self.vocab)
    for morph in morphs:
      if morph not in self.vocab.keys():
        morph = '<unk>'
      vector[self.vocab[morph]] += 1
    
    return vector

→ 형태소 분석까지 다 한 다음

 

tokenizer = Tokenizer()
texts = ['안녕하세요', '안녕하십니까', '오늘은 날씨가 좋네요', '기분이 좋아요']
tokenizer.make_vocab(texts) # texts 리스트로 vocab을 만듬

print(tokenizer.vocab) # vocab 출력

tokenizer.bag_of_words('오늘은 날씨가 어떨 것 같으세요') # 문장의 벡터가 됨

→ 0 인덱스의 unk : 5개 , 6 인덱스의 '오늘' : 1개 , 7 인덱스의 '은' : 5개 , 8 인덱스의 '날씨' : 1개 , 9 인덱스의 '가' : 1개

 

 


DTM (Document Term Matrix)

  • 다수의 문서에서 등장하는 각 단어들의 빈도를 행렬로 표현한 것
  • 각 문서에 대한 BoW를 하나의 행렬로 만든 것과 동일

 

TF-IDF (Term Frequency-Inverse Document Frequency)

  • 단어의 빈도와 역 문서 빈도를 사용하여 각 단어들마다 중요한 정도를 가중치로 주는 방법
  • tf(d, t) : 특정 문서 d에서의 특정 단어 t의 등장 횟수
  • df(t) : 특정 단어 t가 등장한 문서의 수
  • idf(d, t) : df(t) 에 반비례하는 수

n : 총 문서 수

 

  1. DTM을 생성
  2. TF 는 각 문서에서 특정 단어 등장 횟수
    tf(문서1, 사과) → 1
    df(사과) → 1
    idf(d, 사과) → log(4/2) → log2
  3. tf(문서1, 사과) → 1
    tf(문서3, 바나나) → 2
    df(사과) → 1
    df(바나나) → 2
  4. '과일이' idf = log(4/1+1)
    '바나나' idf = log(4/1+2)
  5. TF-IDF = 각 문서에서 특정 단어 등장 횟수 (tf 값) 에 idf 값을 곱한 값

 

Tf-idf 실습

from sklearn.feature_extraction.text import TfidfVectorizer

documents = {
    'you knew I want your love',
    'I like you',
    'what should I do',
}

vectorizer = TfidfVectorizer().fit(documents)

print(vectorizer.transform(documents).toarray())

 

  • 검색할때 TF IDF 스코어를 활용을 하기 때문에 TF IDF 같이 나옴
DTM에서 TF-IDF의 차이는? 
DTM : Bag of Words 를 행렬로 나타낸 것
→ 모든 문서에서 등장한 단어는 특징이 없다고 의미될 수 있음
→ idf 값을 곱해줌으로써 자주 나오는 단어는 점수를 낮추고, 드물게 나오는 단어는 점수를 높이는 효과

DTM : 순수 단어 카운팅 TF-IDF : 모든 문서에서 등장하는 단어는 가중치를 낮추고, 드물게 나오는 단어는 가중치를 높이는 알고리즘

 

반응형

임베딩

희소표현 (Sparse Representation)

  • 원핫인코딩(one-hot encoding 방식) , tf-idf
  • 엄청 큰 메트릭스지만 특정부분에 하나씩만 사용
    → 숫자가 나오는것 자체가 희소하기 때문에 희소표현이라고 부름

밀집표현 (Dense Representation)

  • word2vec
  • 차원을 줄일때 사용자 설정값으로 줄이고, 벡터가 조밀해졌다고 해서 밀집벡터이라고 부름
  • 0보다는 거의 모든 케이스에 값이 다 들어있다

워드 임베딩

  • 밀집표현으로 벡터를 표현하는 방법
  • 임베딩 벡터 - 워드 임베딩 과정을 통해 나온 벡터
  • Word2Vec , Glove , FastText

 

Word2Vec

  • 비슷한 위치에서 등장하는 단어들은 비슷한 의미를 가진다라는 가정
    • ‘강아지’와 ‘고양이’는 주변에 서로 비슷한 단어가 나올 것
    • ‘강아지’와 ‘자연어’는 주변에 전혀 다른 단어가 나올 것
  • 중심 단어와 주변 단어로 학습하므로 라벨링이 필요 없음
    • 문장이 들어왔을때 tokenizer 한 다음에 해당 token들을 가지고 '강아지'라는 단어가 있을때 앞이나 뒤에 있는 단어들을 보고 학습
    • → 비지도학습(unsupervised learning)
  • CBOW(Continuous Bag of Words), Skip-gram 방식

 

CBOW (Continuous Bag of Words)

  • 주변에 있는 단어로부터 중심 단어를 예측하는 방법
  • 중심 단어를 예측하기 위해서 앞, 뒤로 몇 개의 단어를 볼지에 대한 범위를 윈도우(window)라고 함

→ Projection layer 모델은 복잡할 수 있음

→ set 이라는 단어를 예측하기 위해서는 fat , cat , on , the 라는 단어들을 가지고 예측을 한다.

→ 윈도우가 3개면 앞에 3단어 , 뒤에 3단어로 학습

 

Skip-gram

  • CBOW와 반대되는 개념 - 입력과 아웃풋이 반대
  • 중심단어에서 주변단어를 예측하는 방식

 

네거티브 샘플링 (Negative Sampling)

  • one-hot encoding으로 모든 단어에 대해서 cross entropy를 계산하고 weight를 조정하려면 단어 개수에 따라서 무거운 작업이 될 수 있음

→ 만약 단어가 10만개가 있다면 10만에 대한 cross entropy를 계산을 해야하는데 너무 오래 걸릴 수가 있다. 단어 갯수가 많아질수록 무거워진다.

→ 그래서 sampling 샘플링을 해준다.

  • 주변 단어-중심 단어 관계를 가지고 지정한 윈도우 사이즈 내에 존재하면 1, 그렇지 않으면 0으로 이진분류 문제로 변경하여 학습하면 더 빠르게 학습할 수 있음
    → cross entropy는 binary에 대해서만 계산하면 되고 , weight도 두개만 업데이트하면 됨
  • 전체 단어가 아니라, 일부에 대해서만 학습하도록 샘플링
Word2Vec 같은 경우 비지도 학습이다 보니 방대한 양의 데이터 학습 가능
→ 데이터가 너무 많기 때문에 네거티브 샘플링처럼 샘플링을 해서 연관이 있는지 학습

 

코사인 유사도 (Cosine Similarity)

  • 두 특성 벡터간의 유사정도를 코사인 값으로 표현한 것
  • 코사인 유사도는 -1에서 1까지의 값을 가지며, -1은 서로 완전히 반대, 0은 서로 독립, 1은 서로 같은 경우를 의미

그 외의 유사도 평가 방법 유클리드 거리(Euclidean Distance) , 자카드 유사도(Jaccard Similarity)

 

Word Analogy

  • 유추를 통한 평가로 유추에 대한 데이터가 존재해야 테스트를 할 수 있음
  • 명사뿐만이 아니라 형용사, 동명사에서도 똑같이 비슷하게 나오기도 함

→ man - woman + king = queen

→ 한국 - 서울 = 일본 - 도쿄

반응형

+ Recent posts