본문 바로가기

~2023

[네이버 부캠] 프로젝트1: 문장 간 유사도 측정(STS) 대회 정리

728x90
반응형

네이버 부스트캠프 ai tech 교육 과정에서 총 5번의 프로젝트를 수행한다. 4번의 프로젝트는 캠프에서 주제와 데이터를 제공해줘 AI Stages 플랫폼을 통해 대회 형식으로 진행되고 마지막 프로젝트는 최종 프로젝트로 팀 내에서 기획부터 구현까지 수행하는 걸로 알고 있다. (아직은 최종 프로젝트에 대한 정보가 부족함 ㅎ)
암튼 오늘은 첫 번째 프로젝트를 회고하겠다. CV, NLP, ReySys별로 주제는 다르며, 나는 NLP 과정을 수료중이기 때문에 문장 간 유사도 측정(Semantic Text Similarity; STS)을 주제로 대회를 진행했다. 우리는 public 5위, private 10위로 마무리 했으며(private 6위인데 최종 파일 잘못 제출함ㅜ) 깃허브 레파지토리 주소는 여기다.

1. 대회 방식

대회는 2023년 4월 10일부터 2023년 4월 20일까지 약 2주 동안 진행했고 AI Stages에서 코드를 입력하면 해당 코드에 대한 대회가 활성화 되는데 그 대회 내에서 서버를 할당 받아 GPU V100을 사용했다.
그리고 submit.csv 파일을 제출하면 test 점수에 따른 리더보드 업데이트가 이루어진다. 참고로 팀으로 활동할텐데 팀당 제출 가능한 회수는 일일 10회이다.

1.1 프로젝트 구조

├── level1_semantictextsimilarity-nlp-06
│   ├── data/ (private)
│   ├── results/ (private)
│   ├── data_viz/
│   │   ├── _EDA.ipynb
│   │   └── _data_preprocessing.ipynb
│   ├── models/
│   │   └── model.py
│   ├── utils/
│   │   ├── train.py
│   │   ├── process_manipulator.py
│   │   ├── utils.py
│   │   └── data_preprocessing.py
│   ├── baselines/
│   │   └── baseline_config.yml
│   ├── requirements.txt
│   ├── READMD.md
│   └── main_process.py

2. 데이터 분석

데이터는 다음과 같이 구성되어 있다.

  • train data 9324개
  • val data 550개
  • test data 1,100개

데이콘 같은 대회에서는 하나의 데이터셋에서 사용자가 학습/검증 용도를 따로 분리해야 하는데 이번 대회에서는 train 데이터와 val 데이터는 왜 나눠 주는지 잘 모르겠다.

2.1 데이터 시각화

(좌) train data의 label 분포 (우) val data의 label 분포

label은 0~5 사이의 실수인데 분포를 보기 위해 시각화 해본 결과 train data에 대해서는 0에 편향되어 있고 val data는 골고루 분포되어 있다.

2.2 토큰 갯수 시각화

토큰으로 변환 후에 데이터 길이에 대한 분포를 시각화

$sentence_1 + <SEP> + sentence_2$으로 새로운 데이터를 만들어 토큰화 후에 모델 입력으로 넣는데 모델 입력 넣기 전 토큰화된 데이터의 길이 분포를 확인해보니 위와 같았다. 대부분의 토큰 개수가 100개 이하였고, 가장 토큰이 많은 데이터의 길이는 169였다. 특수문자가 반복되는 경우가 많았는데 특수문자 중복을 제거했을 경우 최대 100개로 길이 변화 폭이 크다. 이로 인해 학습 속도가 훨씬 빨라지는 효과를 얻을 수 있었다. 그래서 우리는 실험 환경으로 tokenizer의 model_max_len를 100으로 선정했다.

3. 데이터 전처리

데이터 전처리는 12개의 기법을 사용했는데 두 가지 카테고리인 데이터 클리닝과 데이터 증강으로 분류했다. 분류 기준은 다음과 같다. 원본 데이터를 변환시키는 전처리 기법은 데이터 클리닝이라고 하며, 원본 데이터를 유지한 채 새로운 데이터를 만들어내면 데이터 증강으로 카테고리를 지정했다.

3.1 데이터 클리닝(Data Cleaning)

3.1.1 맞춤법 검사(Spell Check)
PyKoSpacing 을 이용해 띄어쓰기를 진행 한 후 SymSpell 로 맞춤법 체크를 진행하였다. 그러나 육안으로 확인했을 때 띄어쓰기 및 맞춤법 오류가 많이 개선되지 않았다. 그 대안으로 EDA 를 진행하면서 너무 많은 특수문자, 이모티콘 등을 제거하였고, 초성 등을 단어로 바꿔주었다. 그 이후에 네이버 맞춤법 체크 api를 활용한 HanSpell 로 맞춤법 체크를 하였다. 맞춤법 오류가 많이 개선되었으며, 토큰화 기준 가장 긴 문장의 길이가 180에서 120으로 줄었다.

3.1.2 Hangulize
hangulize는 'OPIC'을 '오픽'으로 변환해주는 등 영어를 한글 발음으로 바꿔주는 라이브러리이다.

모델이 예측한 validation data의 label과 실제 정답 값을 비교했을 때 영어 단어가 한글로 되어서 실제 정답 점수는 높은데 모델이 label을 낮게 주는 경우가 다소 있었다. 이에 우리는 모델이 두 단어를 서로 다른 단어로 인식하여 낮은 점수를 주었다고 가정하여, 외래어 단어를 한글 발음으로 바꿔주는 hangulize 라이브러리를 통해 데이터를 클리닝했다.

3.1.3 Label Smoothing
우리가 직접 만든 데이터 전처리 기법으로 데이터의 레이블 별 분포를 보았을 때, 레이블이 0인 데이터가 많고, 5인 데이터는 거의 없었다. 따라서 label을 균등 분포로 만들어주기 위해, label 0의 데이터를 잘라내서 label 5의 데이터로 만들어주는 작업을 진행했다. copied translation을 이용하여 레이블 0의 데이터 중 sentence1 데이터를 sentence2로 copy하여 label 5로 만들어주었다. 잘라내는 label 0 데이터의 비율을 조정하며 최적의 값을 찾아보았다.

3.1.4 Over/Under Sampling
validation data는 label별 데이터 분포가 uniform distribution에 가까운 것에 비해 train data는 다소 편향된 분포를 보였다. train data에서 label별 데이터 개수를 x라는 값을 기준으로 데이터가 개수가 x보다 크면 Undersampling, x보다 작으면 Oversampling했다. 특정 데이터에 과적합 되는 것을 막기 위해 Oversampling시 한 데이터가 3회 이상 복제되지 않도록 제한했고, 결과적으로 완전한 uniform distribution이 만들어지진 않았다. train data를 uniform으로 변형하기 전과 비교했을 때, validation pearson coefficient를 0.9208에서 0.9362로 0.0157 개선할 수 있었다.

3.1.5 불용어 제거
Okt 라이브러리를 사용하여 형태소 단위로 끊어 불용어에 해당하는 형태소들을 제거하는 기법이다. 불용어를 제거하는 과정에서 의미가 있는 단어들을 제거하는 경우가 있어서 그런지 성능이 오히려 떨어지는 결과가 생겨 중반부터 사용하는 기법에서 제외하였다.

3.1.6 특수문자 제거
정규식을 활용해 특수 문자를 제거했다.

3.2 데이터 증강(Data Augmentation)

3.2.1 Swap Sentence
두 문장 사이의 유사도는 두 문장의 순서가 바뀌어도 동일하기 때문에 문장의 품질을 떨어뜨리지 않으면서 데이터를 늘릴 수 있었다. 이후 대부분의 실험에서 swap sentence를 사용했다.

3.2.2 Easy Data Augmentation (EDA)

  • synonym replacement : 무작위 단어를 유의어로 대체
  • random insert : 유의어를 무작위 위치에 삽입
  • random swap : 단어들의 위치를 무작위로 변경
  • random deletion : 단어 무작위 삭제

품사 태깅은 OKt 사용, 확률 p값은 초기에는 0.3으로 진행 후 논문 상 sweet spot이 0.1이라 변경해서 적용했다. 초반에는 단순히 sentence_1 컬럼과 sentence_2 컬럼에 둘 다 적용하여 데이터 증강을 진행했는데, 이는 오히려 label의 의미를 해치는 것이 아닌가 하여 한 컬럼에 변형을 가하면 그 쌍이 되는 문장은 기존 문장으로 삽입하여 데이터 증강을 시도해 보았다. Random Swap 외에는 유의미한 성능 향상을 보이지 않았다.

3.2.3 Back Translation
googletrans를 통해 역번역을 하여 데이터 증강을 시도했으나, 번역된 문장의 질이 많이 떨어져 data로 활용하지 못했다.

3.2.4 Text Style Tranfer
huggingface의 한국어 말투 변환 모델 heegyu/kobart-text-style-transfer. 구어체, 문어체 등 최대 12가지 말투 변환 가능. 문장의 말투를 바꾸면 data의 label이 바뀌지 않으면서 data를 증강할 수 있을 것이라 생각했으나, 말투 변환 모델이 완벽하지 않아 문장의 의미가 바뀌는 경우가 생겨 유의미한 데이터 증강이 되지 못했다.

3.2.5 Reverse Text
문장의 어절 단위로 끊어 순서를 바꾼 상태로 학습하는 방법이다. 단일 혹은 다른 기법들과 조합 시 성능이 좋지는 않아 중반부터 사용하는 기법에서 제외하였다.

3.2.6 SMOTE
SMOTE는 정형 데이터에서 사용하는 데이터 증강 기법으로 imbalanced 문제를 해결하는데 매우 적절하다. 벡터 공간에서 label이 군집화 됐을 때 새로운 빈 공간을 찾아 낸다면 그 데이터가 동일한 label을 가지는 새로운 데이터이기 때문에 우리 문제에서도 사용해봤다. 하지만 직접 실험해본 결과 문장 의미, 단어 의미가 많이 변환되어 실험에는 채택되지 못 했다.

4. 사용한 모델

  • snunlp/KR-ELECTRA-discriminator
  • monologg/koelectra-base-v3-discriminator

5. 아쉬웠던 점

앙상블이 확실히 성능을 높이기에 좋기 때문에 좀 더 다양한 모델으로 실험을 진행했어야 했는데 두 개의 모델만으로 실험을 진행한 게 아쉽다. 그래도 우리 인사이트를 NLP 캠퍼와 정상근 마스터님 앞에서 발표했는데 우리처럼 다양한 데이터 전처리 기법을 사용하는 것을 보고 마스터님도 한 수 배워 가신다고 해서 뿌듯했다.

728x90
반응형