패스트텍스트(FastText) #1, 개념 이해하기

    현재 가장 많이 사용되는 딥러닝(Deep Learning) 기반의 분산 표현(distributed representation) 워드임베딩(Word Embedding, 자연어를 기계가 이해할 수 있는 숫자 벡터 값으로 변경하는 기술)은 Word2vec이라 할 수 있다. Word2Vec 임베딩 기술은 단순하지만 성능이 우수해서 많이 사용되는데 치명적인 문제점도 존재한다. 바로 주어지는 단어(Corpus, 말뭉치)를 기반으로 학습을 진행하며 존재하지 않던 단어를 던졌을 때 에러가 발생하는 등 만능적인 모습을 보여주지 않는다. 

     

    당연히 학습 안된 단어는 나오지 말아야 되는거 아니냐? 할 수 있겠지만 이 문제를 해결하기 위한 방식이 연구되고 있었고, 페이스북(Facebook)에서 이를 보완하는 언어 모델이 등장한다. 아시다시피 Word2Vec은 구글(Google)에서 만들었는데 페이스북이 Fasttext를 내놓고, 구글이 Tensorflow를 내놓으니 페이스북이 Pytorch를 내놓는 모습을 보면 정말 페이스북이 구글을 대하는 모습이 마치 LG전자 = 페이스북와 삼성전자 = 구글 같은 모습이다.

     

    패스트텍스트, 개념 이해하기


    단어를 대하는 태도

    패스트텍스트(FastText)와 Word2vec의 가장 큰 차이점은 바로 단어를 어떻게 인식하느냐의 차이이다. Fasttext는 단어를 다시 n-gram으로 구성하여 내부적으로 쪼개는데 단어를 다시 쪼개는 것을 내부 단어(subword)라고 하며 이렇게 내부 단어를 사용하는 것을 "단어 이하 수준의 정보(subword-level information)를 사용한다"라고 한다.

     

    예시

    korean

    korean이라는 단어를 n-gram으로 쪼개본다고 가정해보자. 이때 쪼개는 기준을 bi-gram(2개)로 할 경우 다음과 같이 쪼갠다.

     

    bi-gram (n=2)

    <k, ko, or, re, ea, an, n>, <korean>

    일단 단어를 쪼갠 때, 처음 시작할 때 < 값을 넣고, 마지막에 >를 넣게 된다. 즉 단어를 우선 홑화살괄호로 감싼 후 n-gram의 값으로 단어를 쪼갠다. 이때 subword말고 하나를 더 추가하는데 홀화살괄호가 감싸진 단어를 추가하게 된다. 이해가 안된 사람을 위해서 다시 위 내용을 tri-gram으로 쪼개본다.

     

    tri-gram (n=3)

    <ko, kor, ore, rea, ean, an>, <korean>

     

    그러나 FastText의 n-gram은 이렇게 n을 한개의 값만 쓰는 것이 아니라 최소값과 최대값을 설정할 수 있는데 default로 최소값은 3, 최대값은 6으로 되어 있다.

     

    n-gram (3~6)

    # fasttext의 n-gram
    3-gram : <ko, kor, ore, rea, ean, an>
    4-gram : <kor, kore, orea, rean, ean>
    5-gram : <kore, korea, orean, rean>
    6-gram : <korea, korean, orean>
    special : <korean>
    
    # 결과
    <ko ..., an>, <kor ..., ean>, <kore ..., rean>, <korea ..., orean>, <korean>

     

    이렇게 단어를 쪼개게 되면, 예상하지 못했던 단어도 학습을 할 수 있다. 예를 들어, tensorflow라는 단어는 말뭉치(Corpus)에 있지만 tensor는 없다고 가정을 해보자. Word2Vec으로 해당 corpus를 학습을 했다면 tensor라는 단어를 모델에 던졌을 시 해당 단어를 학습한적이 없다는 에러(Out-of-Vocabulary, OOV)를 뿌릴 것이다.

     

    하지만, Fasttext의 경우 tensor가 포함된 tensorflow를 학습한 적이 있기 때문에 tensor에서 에러가 발생하지 않고 결과를 출력할 수 있다.

     

     

    한국어의 특이점

    Fasttext를 한국어로 처리할 경우 2가지 방식을 사용할 수 있다. 바로 단어를 영문과 유사한 방식으로 쪼개거나 자모단위로 변환하여 넣는 방식이다.

     

    예를 들어 아래와 같은 단어가 있다고 해보자

    텍스트

     

    위와 같은 단어를 아래와 같이 일반적인 방식으로 할 수도 있지만

    # n-gram (n=2)
    <텍, 텍스, 스트, 트>

     

    자모 단위로 나눠서 넣을 수 있다. 다만 자모 단위로 처리할 때 종성 부분이 없을 경우, 임의의 문자값을 넣어서 처리하게 된다. 

    # 종성 대체 음절 q
    <, ㅌ, ㅔ, ㄱ, ㅅ, ㅡ, q, ㅌ, ㅡ, q,>

     

    한국어는 형태소 분석기가 변수

    사실 한국어의 성능을 좌지우지 할 수 있는 것은 바로 형태소 분석기이다. 영미권에서는 공백 기준으로 토큰(Token) 하나가 한가지의 품사에 대응이 되기 때문에 처리하는 것이 매우 간단하나 한국어는 공백 기준으로 여러가지 품사가 섞일 수가 있다.

     

    즉, 위와 같은 패스트텍스트의 예시는 어디까지나 영문을 기준으로 성능이 좋을 수 있는 것이고 형태소 분석기를 활용한다면 오히려 한국어의 경우 Word2vec 모델의 효과가 더 좋은 사례와 논문들도 많이 나오고 있다. 그러니 한가지 방식으로만 임베딩을 수행하지 말고 최대한 할 수 있는 모든것을 사용해서 성능이 좋은 최적의 모델을 찾는 것이 가장 좋을 것이다.

     

    연관포스팅

    희소 표현과 분산 표현, 차원의 저주

    Word2Vec #1, (개념, CBOW와 Skip-gram)

    Word2Vec #2, 기본적인 모델 구현(생성)하기

    Word2Vec #3, 모델 활용(사용)하기

     

     

    댓글

    Designed by JB FACTORY