ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [자연어처리] 문자를 숫자로 변환하는 방법 (BOW, TF-IDF, Word-Embedding)
    자연어처리 공부 2024. 1. 2. 11:14

    자연어처리가 정말 빠른 속도로 발전을 하고 있으며, 현재 기술은 사람인지 컴퓨터인지 구별이 어려운 만큼 다양한 분야와 일상 생활 전반에 걸쳐 스며들고 있습니다. 저 또한 ChatGPT로 공부하고 글을 쓰고 수정을 맡기기도 하며, 구글 검색을 활용하고 있습니다. 또한 프로그래밍 코드도 도움받고 에러도 잡아줍니다. 번역도 해주는 등 일상적인 환경에서 효율적이고 스마트한 혜택을 얻고 있습니다. 그 변화는 혁명적이고 놀랍습니다. 이제는 시도 쓰고 소설도 쓰고 그림도 그리며 다양한 분야에서 인간의 능력을 뛰어넘는 성과를 이루고 있습니다. 컴퓨터는 어떻게 문자를 인식해서 번역도 하고, 감정을 분석하고, 정보를 추출하여 요약을 해주고, 질의에 대답을 해주며, 문장 생성 등의 작업을 할 수 있는 걸까요?

     

    자연어처리의 가장 기본은 문서의 집합인 Corpus라는 말뭉치에서 문자열을 작은 단위로 나눈 토큰화 과정을 거쳐 문자를 숫자로 바꾸는 것에부터 시작합니다. 컴퓨터는 문자 자체를 처리할 수 없기 때문에 숫자로 변환 후 처리하게 됩니다. 오늘 문자를 숫자로 변환하는 방법에 대해 알아보겠습니다.

     

    ▶︎ 이해를 돕기 위해 예제 문장은 간단히!!

    from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
    from keras.preprocessing.text import Tokenizer
    from tensorflow.keras.preprocessing.sequence import pad_sequences
    
    # 예제 문장들
    sentences = ['I like math class, math!', 'I like puppies like you']

     

    ▶︎ BOW (Bag of Words)

    개념 : 모든 문서를 토큰화하여 토큰 등장 횟수로 수치화하는 방법.

    → 특징 : 한 차원은 한 단어를 대표함

    문제점 

        1. 의미 없는 흔한 단어(불용어 같은)가 빈도수가 높은데, 의미없는 단어들이 문장/문단/문서의 유사도를 계산할 때 막대한 영향을 주게 됨

        2. 순서를 확인할 수 없음 (n-gram으로 일부 해결할 수 있지만, 차원의 수가 엄청 많아짐)

        3. 의미를 파악할 수 없음

    # BoW
    vectorizer = CountVectorizer()
    bow_matrix = vectorizer.fit_transform(sentences)
    
    print("Feature names:", vectorizer.get_feature_names_out())
    print("BoW Matrix:")
    print(bow_matrix.toarray())
    
    # Result
    Feature names: ['class' 'like' 'math' 'puppies' 'you']
    BoW Matrix:
    [[1 1 2 0 0]
     [0 2 0 1 1]]

     

    ▶︎ TF-IDF (Term Frequency-Inverse Document Frequency)

    개념 : BOW를 활용하여 해당 단어가 해당 문서에서 얼마나 중요한지 수치화하는 방법

    특징 : 많은 문서에 공통적으로 들어있는 단어면 큰 의미를 지니지 않고 문서 구별 능력이 없는 단어라고 생각하여 가중치를 축소하는 방법. 즉, 다른 문서에는 많이 등장하지 않고, 해당 문서에만 많이 등장할수록 중요함

     장점 

        1. 해석이 쉬움. 한 단어의 문서에서의 중요성을 숫자로 바로 알 수 있음. 계산이 간단함

     문제점 

        1. 순서를 확인할 수 없음 

        2. 의미를 파악할 수 없음

    # TF-IDF
    tfidf_vectorizer = TfidfVectorizer()
    tfidf_matrix = tfidf_vectorizer.fit_transform(sentences)
    
    print("\nTF-IDF Matrix:")
    print(tfidf_matrix.toarray())
    print("Feature names:", tfidf_vectorizer.get_feature_names_out())
    
    # Result 
    TF-IDF Matrix:
    [[0.4261596  0.30321606 0.8523192  0.         0.        ]
     [0.         0.70929727 0.         0.49844628 0.49844628]]
    Feature names: ['class' 'like' 'math' 'puppies' 'you']

     

    ▶︎ Word-Embedding

    필요성 : 단어 간의 유사성을 파악하지 못하는 문제를 해결하기 위해

    개념 : 단어 간의 의미적 유사성을 보존하면서(연관성있는 단어를 군집화하여) 벡터 공간에 표시

    의의

        1. 단어/문장의 유사도(관련도)를 계산할 수 있음

        2. 벡터에 의미 정보가 내장되어 있음

        3. 전이학습이 가능해짐(자연어처리는 엄청 많은 데이터 corpus로 학습해야 일반화된 의미를 만족하는 벡터가 생성되는데 그렇지 못한 상황에서도 Word-Embedding 값을 초기값으로 가져와 더 정확한 의미를 가진 벡터를 생성할 수 있음)

    장점 

        1. 단어간 의미의 유사성을 파악할 수 있음

        2. 문맥 정보를 표현한 벡터이므로, 순서 의미도 파악 가능

        3. 차원을 사람이 정하기 때문에 상대적으로 차원의 저주에 덜 민감함

        4. 전이학습이 가능함

    문제점

        1. 적은 데이터에서 충분한 의미를 담기는 힘들어서 대규모 텍스트 데이터가 필요

        2. 벡터 공간의 각 차원이 어떤 의미를 갖는지 해석이 어려움

        3. 학습 데이터에 없는 단어(OOV)의 처리가 어려움

    대표적인 워드임베딩에는 구글의 딥러닝 모델인 Word2Vec이 있습니다. Word2Vec은 두 종류로 구현할 수 있는데 

        1. CBOW : 주변 단어들의 벡터를 이용하여 특정 단어를 예측하는 방식

        2. Skip-gram : 중신 단어를 이용하여 주변 단어를 예측하는 방식

    이 있습니다.

     

     

Designed by Tistory.