본문 바로가기
Data

[text classification, categorizing] fasttext, bert로 자연어 분류하고 비교하기 (작성중)

by hyemjjang 2021. 7. 21.

목적: 7가지의 대분류로 라벨링되어 있는 상품 키워드 데이터를(총 24417개) 학습하고, 이를 기반으로 새로운 키워드 입력시, 자동으로 해당 키워드를 대분류(category)로 분류하는 모델 성능 측정

 

방식: 

1. 한국어 키워드 전처리 (null값 제거, 특수문자 제거, 불용어 제거)

2. 키워드 토큰화 

* 이때 나의 미숙함으로 토큰화된 데이터가 데이터프레임화 형식으로 만들어지지 않음 -> 이 부분은 다시 생각해보기

3. train/test 분리

4. 모델 학습

5. 키워드 입력시 카테고리 분류하는 message 출력

 

모델 선정 기준: 자연어를 벡터화하여 유사도에 따라 학습하는 semantic 모델

이 중 자연어 처리(그 중에서도 konlp) 및 text classfication에 주로 쓰이는 fasttext, bert를 비교

 

문제상황: 키워드의 길이가 너무 짧아(10글자 미만) 성능 개선이 어려움

 

성능 평가: 가장 쉽고 직관적인 방법은 특정 키워드를 입력하고 이에 대한 결과값이 정확히 나오는지 비교하는 것이다. 하지만 이러한 귀납적 방법으로는 예외상황을 일반화하기 어렵고, 수치화하기 어렵다는 단점이 있다

 

추가적으로 성능을 측정할 수 있는 방법을 고안해야겠다

 


1. fasttext

 

어플 당근마켓에서는 사용자가 상품 이름을 입력할 때 카테고리를 자동으로 분류하여 사용자의 선택을 돕고, 상품 검색 정확도를 높인다

이 때 입력되는 키워드의 길이가 우리에게 제시된 키워드와 유사하다는 점에서 당근마켓이 사용하는 모델을 참고했다

 

당근마켓에서 사용하는 모델에 대한 정보는 medium 블로그에 공개되어 있다

아래는 내가 참고한 글이다

fasttext는 페이스북에서 개발한 모델로 다양한 다국어 pre-trained 모델을 제공한다는 큰 장점이 있다

https://fasttext.cc/

 

fastText

Library for efficient text classification and representation learning

fasttext.cc

여기에서는 단순히 fasttext로 categorizing 하는 법, 그리고 pre-trained된 한국어 모델을 적용하면 성능이 더 좋아지는지 실험해보고자 한다. 

 

  1. fasttext로 categorizing 코드
    - 깃허브 코드
    https://github.com/thursdaydreaming/whitescan/blob/main/FASTTEXT%EB%A1%9C_%EC%B9%B4%ED%85%8C%EA%B3%A0%EB%A6%AC_%EC%98%88%EC%B8%A1.ipynb
  2. pre-trained된 한국어 모델 적용
    - 위의 깃허브 코드에 한국어 모델을 적용했다
    한국어 모델의 경우
    pip install gensim
    
    import fastext.util
    fasttext.util.download_model('ko', if_exists='ignore') 
    
    #bin과 vec 차이는 vec은 라인마다 단어의 벡터 포함, bin은 벡터+딕셔너리, hyper parameter등 포함
    #bin은 모델 추가 학습 가능(성능 개선)
    pt1=fasttext.load_model('cc.ko.300.bin')
    pt2=fasttext.load_model('cc.ko.300.vec')​
    이 모델은 우리가 아는 그대로  model 학습 부분에 적용해주면 됨

    근데 여기서 문제가 생김
    categorizing은 predict()함수를 사용함
    여기서 predict 함수는 지도학습(supervised model)을 거친 모델만 가능하다고 함..! 
    문제는 pre-trained 모델이 비지도학습이라는 점 ....
    그래서 1번과 동일하게 적용하는 것이 불가능하다 ㄱ-

    결론:pre-trained 모델로는 유사도 분석까지만 가능.
    1번의 hyper-parameter를 조정하고, 토큰화 문제를 해결하여 성능을 향상시키는 방법밖에 없는 듯

장점

  1. 쉬운 학습, 높은 성능
    - 토큰화 전 성능 : 약 3n%
    - 토큰화 후 성능 : 약 6n%
    (팀원이 구한 성능으로, 아직 코드를 확인하지 못해 정확하지 않음)
  2. categorizing용 함수가 구현되어 있음
    - predict() 활용
    - 이를 활용하여 관련 서비스 쉽게 구현 가능

단점

  1. pre-trained된 한국어 모델이 있음이 장점이나, 이를 predict()와 병행하지 못함
  2. 모델 개선을 통한 성능 개선이 어려움 

2. bert

 

bert는 요즘 가장 핫한 기계번역 모델이다. bert라는 모델 자체에 이미 33억개의 unlabeled 데이터가 학습된 상태이기 때문에 성능이 좋고, 전체 학습 시간이 상당히 단축된다. fintuning을 통해 내가 원하는 데이터만 추가적으로 학습시켜주면 되는 것이다. 

 

하지만 이 bert의 경우 우리의 상황인 'labeled data->supervised model->predict'과 맞지 않는다. 일단 unlabeled data이기 때문에 기본적으로 비지도학습이고 대체로 이중분류로 쓰이는 것 같다. (긍/부정 감정분석 등) 

그렇기 때문에 bert를 어떻게 사용할지 고민하다가 bert로 다중분류하는 케이스를 찾아냈다

 

특히 한국어 단어를 처리할 예정이기 때문에, koBERT를 사용하였다

해당 모델의 경우 한국어 위키에서 5백만개의 문장, 54백만개의 단어를 학습시킨 것으로 한국어 문장에 대한 높은 성능을 보여준다고 한다


kobert의 다중분류에는 아래 블로그의 자료를 참고하였다