오늘은 FACEBOOK AI연구소에서 만든 텍스트 임베딩 기법 중 하나인 fastText에 대해 알아보자.
전반적으로 word2vec과 유사하나, 가장 큰 차이점은 각 단어를 character 단위 n-gram으로 쪼갠다는 것이다.
예를 들어, "eating"이라는 단어는 n=3일 때 아래와 같이 쪼개져서 표현된다.
한국어 같은 경우에는, 토마토주스를 표현한다고 하면, [토마, 토마토, 마토주, 토주스, 주스]로 표현된다.
fastText또한 word2vec에서와 같이 네거티브 샘플링을 쓴다.
네거티브 샘플링에 대한 내용은
https://simonezz.tistory.com/36
을 참고.
즉, positive sample이 주어지면 해당 쌍의 벡터의 유사도(내적값)를 높이는 방향으로 훈련되고, negative sample이 주어지면 내적값을 낮추는 방향으로 훈련된다.
fastText는 한국어와 같이 조사/어미가 발달한 언어에 좋은 성능이 나올 뿐만 아니라 한 단어를 쪼개서 훈련시키기 때문에 미등록단어(OTT)에도 잘 작동한다.
ratsgo님 블로그에서 볼 수 있듯이 영어에서 각 알파벳으로 분리하듯이 한국어를 자음, 모음으로 분리하여 이용을 하게 되는데 문장 전체를 그대로 하기보다는 형태소 분리를 이용하여 토큰화 한 후 자소분리하여 training data에 쓰이게 된다.
보통 한국어 임베딩에 쓰이는 데이터는 한국 위키피디아, 네이버 영화 리뷰 데이터, korquad이 세 가지인데
회사에서 현재 벡터화해야하는 데이터들은 수학 문제 관련 데이터이기 때문에 위 세가지 데이터로 훈련시켜진 모델은 잘 작동하지 않는다.
내가 원하는 것은 예를 들어 "경우의 수"를 입력했을 때, "방법의 수", "가짓수" 등이 유사 단어로 나오길 바라지만,
위 세 데이터로 훈련시킨 모델은 "경우의 수"를 입력했을 때 전혀 의미가 유사하지 않은 수학 키워드만 나오기 때문이다. 그래서 직접 데이터를 이용하여 훈련시켜야하는 상황이였다.
가지고 있는 데이터의 한 유형을 한 라인으로 해서 만든 txt파일을 이용하여 gensim의 fastText를 훈련시켰다.
model = FastText(corpus, size=100, workers=4, sg=1, iter=2, word_ngrams=5 라인 한 줄로 훈련이 가능할 정도로 간단하다!
ex)
다음으로는 훈련시킨 fastText의 한계를 알아보고 그에 대한 대처방안에 대해 포스팅을 해봐야겠다.
댓글