ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AI] 단어표현방법 (Bag of Words, Word2Vec, One-hot Vector 등) 설명 및 실습
    machine learning 2023. 3. 28. 14:06
    728x90
    반응형

    단어표현방법(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

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

    728x90
    반응형
Designed by Tistory.