Semantic Text Similarity (STS)란 두 텍스트가 얼마나 유사한지 판단하는 NLP Task입니다. 일반적으로 두 개의 문장을 입력하고, 이러한 문장쌍이 얼마나 의미적으로 서로 유사한지를 판단합니다.
우리는 STS 데이터셋을 활용해 두 문장의 유사도를 측정하는 AI모델을 구축할 것입니다. 유사도 점수와 함께 두 문장의 유사함을 참과 거짓으로 판단하는 binary 정보도 같이 제공하지만, 최종적으로 0과 5사이의 유사도 점수를 예측하는 것을 목적으로 합니다.
학습 데이터셋 9,324개, 검증 데이터셋 550개, 평가 데이터는 1,100개가 제공됩니다. 평가 데이터의 50%는 Public 점수 계산에 활용되어 실시간 리더보드에 표기가 되고, 남은 50%는 Private 결과 계산에 활용되어 대회 종료 후 평가됩니다.
피어슨 상관 계수(Pearson Correlation Coefficient ,PCC)는 두 변수 X 와 Y 간의 선형 상관 관계를 계량화한 수치로, 보통 상관관계라 함은 피어슨 상관관계를 칭합니다.
피어슨 상관계수는 -1~1 사이의 값을 가지며, +1은 완벽한 양의 선형 상관 관계, 0은 선형 상관 관계 없음, -1은 완벽한 음의 선형 상관 관계를 의미합니다.
피어슨 상관 계수는 정답과 예측이 일치하지 않더라도 증감율이 일치하면 1에 가까운 값을 보입니다. 반대로 정답값과 예측이 근사하더라도 증감율이 다르면 -1에 가까운 값을 보일 수 있습니다.
이는 정답을 정확히 예측하는 것 보다, 높은 값은 확실히 높게, 낮은 값은 확실히 낮게, 즉 전체적인 경향을 잘 예측하는 것이 중요함을 의미합니다.
Task | Task Description |
---|---|
EDA | 데이터의 특성을 살펴보기 위해 label별 분포 등 시각화 및 분석 |
Augmentation | 데이터셋의 불균형성을 해소하기 위해 다양한 방법으로 데이터 증강 수행 |
Model Exploration | 데이터셋과 STS task를 수행하기 적합한 pre-trained model 선정 |
Second-stream with GNN | 단어들 사이의 유의어 관계를 모델링하기 위해 Graph Neural Networks (GNN)을 second-stream으로 NLP 모델에 통합하고 성능 평가 |
Contrastive Learning | STS Task에서 SOTA의 성능을 달성했던 Contrastive Learning을 본 프로젝트에 적용하여 성능 평가 |
Clustering | 문장 사이의 코사인 유사도를 바탕으로 라벨관의 상관관계를 탐구하여 모델에의 활용 방안 및 전처리 방법 고안 |
Soft Voting Ensemble | 증강된 데이터셋으로 학습한 다양한 model의 예측확률을 평균하여 여러 모델의 강점을 결합해 성능 향상 |
데이터 불균형은 모델이 자주 나타나는 라벨에 치우쳐 예측하게 되어, 드문 라벨을 제대로 예측하지 못하는 경향이 생기는 등 부정적인 결과를 가져올 수 있습니다. 이를 해결하기 위해서 다음과 같은 데이터 전처리 및 증강기법을 사용할 수 있습니다.
label 별 빈도수 | range 별 빈도수 |
label 별 빈도수 | range 별 빈도수 |
label 별 빈도수 | range 별 빈도수 |
label 별 빈도수 | range 별 빈도수 |
본 프로젝트의 목적은 한국어 문장 쌍에 대한 유사도를 정확하게 예측하는 모델을 개발해 실수 범위로 정밀한 유사도 점수를 예측하는 것으로, 한국어 데이터셋에 적합한 pre-trained model을 선정하고, 이를 base 모델로 하여 STS 성능을 극대화하는 방향으로 진행했습니다. Hugging Face의 모델 허브에서 semantic text similarity
tag로 필터링한 후, BERT기반 한국어 모델들(e.g. simcse-ko-bert, klue-roberta, kf-deberta)에 대해 성능 평가를 진행했습니다. 또한, 서버의 HW 환경을 고려한 효율적인 학습 및 추론을 위해 LLM보다 가벼운 Encoder 기반 모델을 선정했습니다.
L1Loss
, AdamW
, Linear
, get_linear_schedule_with_warmup
deliciouscat/kf-deberta-base-cross-sts
을 선택했습니다. (KLUE와 KorSTS 데이터셋으로 학습된 DeBERTa 기반 모델)sorryhyun/sentence-embedding-klue-large
을 선택했습니다. (KlueNLI와 KlueSTS 데이터로 멀티태스크 학습된 RoBERTa-large 기반 모델)snumin44/simcse-ko-bert-supervised
도 함께 선택했습니다. (KorNLI 및 KorSTS 데이터셋으로 학습된 SimCSE 기반 한국어 BERT 모델)STS(Semantic Textual Similarity) 문제에서 단어 사이의 유사도가 중요한 factor일 것이라는 가설을 세워 실험을 진행했습니다. 유사한 의미를 가진 단어들은 문장에서 비슷한 역할을 하며, 이들 간의 관계를 고려하는 것은 문장의 의미를 더 정확하게 파악하는데 도움이 될 것으라고 추정했습니다.
실험 세팅 : 전처리 되지 않은 학습 데이터 문장 쌍에 대해 형태소 분석을 진행하고, 그 중에서 명사에 해당하는 토큰을 추출하여 각 토큰 당 등장 빈도수가 25개 이상인 토큰을 단어로 선정했습니다. 단어들을 직접 검수하면서 오류 및 불필요한 단어를 제거하고 남은 1,000개의 단어를 노드로 지정했습니다. 각 노드 별 유사도를 backbone 모델로 계산했습니다.
평가 모델 및 결과
Model | Valid Pearson | Public Pearson |
---|---|---|
deliciouscat/kf-deberta-base-cross-sts | 0.926 | 0.9110 |
deliciouscat/kf-deberta-base-cross-sts + GNN | 0.929 | 0.9164 |
제안하는 모델이 기존 backbone의 성능보다 더 좋은 것을 확인했지만, 모델 학습의 cost가 커지는 것 대비 성능의 차이가 미미한 것으로 판단했습니다. 사전 그래프 구축 작업의 정교함에 따라 성능의 폭이 커질 것으로 예상되어, 마지막 제출 전 시간이 남으면 진행할 것으로 결론지었습니다.
SimCSE(Gao et al., 2021)는 Contrastive Learning을 문장 임베딩에 처음 적용한 논문입니다. 이 논문은 문장의 의미를 잘 표현하는 벡터(숫자 집합)를 만드는 방법으로 그 해 STS Task에서 SOTA를 달성했습니다. 문장 임베딩이란 문장을 컴퓨터가 이해하고 처리할 수 있도록 문장을 숫자로 바꾸는 방법으로, 문장을 벡터로 변환하면 벡터 사이의 거리를 계산할 수 있습니다. Contrastive Learning은 비슷한 문장은 벡터 간 거리가 가까워야 하고, 다른 문장은 거리가 멀어야한다는 목표를 가지고 벡터를 학습시키는 방법을 의미합니다. 문장 간 유사도를 측정해야 하는 본 프로젝트의 특성과 부합하다고 생각하여, SimCSE의 Constrastive Learning 방식을 본 프로젝트의 적용 시키고자 하였습니다.
1. Unsupervised SimCSE (비지도 학습): 비슷한 문장이나 데이터를 구체적으로 알려주지 않고 모델이 스스로 학습하게 하는 방법입니다. 여기서는 문장을 입력한 뒤 dropout이라는 노이즈(잡음)를 섞어서 두 가지 다른 버전의 벡터를 만든 후, positive pairs(긍정 쌍)로 묶어 모델이 "이 둘은 비슷한 문장"이라고 학습하게 합니다.
2. Supervised SimCSE (지도 학습): 문장 쌍이 비슷하거나 다른 것을 미리 알려준 상태에서 모델을 훈련시키는 방법입니다.
이번 프로젝트에서는 시간 관계 상 Unsupervised 방식을 적용했습니다.
모델을 학습시키는 방법으로는 교차 엔트로피 손실 함수를 사용합니다. In-batch negatives란 mini-batch 내의 데이터를 활용하여 negative 예시를 샘플링하는 방법입니다. 예를 들어, 배치 안에 쿼리 A와 그에 맞는 문서 A+, 쿼리 B와 그에 맞는 문서 B+가 있다면, 쿼리 A에 대한 negative는 문서 B+가 될 수 있고, 쿼리 B에 대한 negative는 문서 A+가 될 수 있습니다. 본 논문에서는 첫번째 문장과 다른 문장을 mini-batch 안에 넣고, 그 문장들을 negative로 하였습니다. 즉, A라는 문장과 A+라는 비슷한 문장을 학습할 때, B라는 문장을 negative pair로 삼아서 모델이 "A와 B는 다르다"라고 학습하게 합니다. 모델이 한 번에 여러 문장을 학습할 때, 그 중 일부를 "다른 문장"이라고 알아채게 만드는 방식입니다.
Model | Validation Pearson | Public Pearson |
---|---|---|
deliciouscat/kf-deberta-base-cross-sts | 0.926 | 0.9110 |
deliciouscat/kf-deberta-base-cross-sts + GNN | 0.929 | 0.9164 |
deliciouscat/kf-deberta-base-cross-sts + CL | 0.929 | 0.9190 |
STS(Semantic Textual Similarity) 문제에서 모델은 다음 두 가지 상황에서 어려움을 겪을 수 있다고 가정했습니다.
이를 해결하기 위해, 두 문장의 임베딩 벡터를 계산하여 코사인 유사도와 label 간의 상관관계를 분석하고, 그에 따른 클러스터를 형성하여 모델을 학습하고자 했습니다.
train.csv의 sentence_1
, sentence_2
를 사전 학습된 encoder 모델을 사용해 각각 임베딩 벡터로 변환한 후, 각 임베딩 벡터 간의 코사인 유사도를 계산하여 유사도와 실제 label 값 간의 상관관계를 확인했습니다. 대부분의 벡터들이 높은 코사인 유사도를 보이는 경향이 있었으며, 이는 Anisotropy problem 때문이라고 분석했습니다.
"모델이 깊어진다"는 표현은 모델이 많은 레이어(층)를 가지고 있다는 뜻으로, 모델이 깊어질수록 각 층이 입력 데이터를 점진적으로 변환하고, 더 복잡한 패턴을 학습할 수 있게 됩니다.
BERT 같은 트랜스포머 기반 모델들은 일반적으로 12개 이상의 레이어를 가집니다. 문장의 복잡한 문맥 정보를 학습하기 위해 깊은 구조를 가지게 되는데, 깊은 모델은 더 많은 정보와 상호작용을 학습하지만 그 과정에서 임베딩 벡터들이 특정 방향으로 집중되는 Anisotropy(비균일성) 문제가 발생할 수 있습니다.
Anisotropy(비균일성)이란 임베딩 벡터들이 특정 방향으로 지나치게 몰리는 현상을 의미합니다. 여기서 임베딩 공간이란 단어, 문장 등을 벡터로 표현한 후, 그 벡터들이 위치하게 되는 수학적인 공간을 말합니다. 벡터가 고르게 퍼져 있으면 임베딩 공간에서 의미 있는 거리를 측정할 수 있는데, 비균일한 경우 의미가 다른 문장들도 가까이 위치하게 되어 코사인 유사도가 제대로 작동하지 않게 됩니다. 모델이 깊어질수록, 모든 단어 또는 문장의 임베딩 벡터들이 특정한 방향으로 점점 집중되는 현상이 발생합니다. 이는 마치 모든 벡터들이 같은 쪽으로 쏠리는 것처럼 보이는데, 이러면 원래는 거리가 멀어야 할 벡터들(의미가 다른 문장들)도 상대적으로 가까워지는 문제가 생기게 됩니다.
모델이 깊어짐에 따라 Anisotropy problem이 발생하는 이유는 다음과 같습니다.
이에 코사인 유사도의 값을 적절한 threshold로 구분하여 데이터의 분포를 확인한 결과, 코사인 유사도가 0.982 이상인 데이터에서 label 값이 높은 경우가 많았음을 확인했습니다.
이에 따라 아래와 같이 두 개의 클러스터를 생성해 데이터를 구분하여 모델을 학습시켰습니다.
모델 학습 : 각 클러스터의 데이터를 deliciouscat/kf-deberta-base-cross-sts
모델로 학습했습니다. Public Pearson 측정 결과 0.9177의 성능을 확인할 수 있었습니다.
결과 분석 : 모델 예측에서 발생한 몇 가지 문제와 그에 대한 분석을 진행했습니다.
전처리 개선 : 위의 문제를 해결하기 위해 다음 전처리 방법들을 추가 적용했습니다.
hanspell
라이브러리로 맞춤법 검사를 시행해 오류를 줄였습니다.spacing
라이브러리로 띄어쓰기 오류를 검사하여 맞춤법 검사기에서 누락된 부분을 보완했습니다.googletrans
라이브러리로 영어 단어를 한국어로 번역하여 모델이 언어 차이를 극복할 수 있도록 했습니다.Soft Voting은 앙상블 학습에서 여러 모델의 예측 결과를 결합하여 최종 예측을 도출하는 기법입니다. 각 모델이 예측한 logit 값을 평균하거나 가중 평균하여 최종 예측을 만드는 방식으로, 분류 성능을 향상시키는 데 목적이 있습니다. 본 프로젝트에서는 데이터 증강(Data Augmentation)을 통해 생성된 여러 버전의 train data와 모델 탐색을 거쳐 선정된 다양한 모델 조합을 앙상블하여 최적의 성능을 도출하고자 하였습니다.
단순히 validation score 기반 가중 평균을 사용할 때, 대부분의 앙상블 대상 모델이 0.92에서 0.93 사이의 유사한 validation score를 보여 가중치에 큰 차이를 주기 어려움
더 좋은 성능을 보이는 모델과 그렇지 않은 모델 간의 차이를 명확히 하기 위해 적합한 가중치 정규화가 필요하다고 판단
Min-Max 정규화는 피처의 값을 0~1 범위로 조정하는 기법이지만, 본 프로젝트에서는 validation score를 0.8~1.2 범위로 조정하여 가중평균에 사용
이를 위해 Min-Max 정규화 수식을 변형하여, 과 값을 각각 0.8과 1.2로 설정
모델 | 활용 기법 | Validation Pearson | Min-Max 정규화 가중 평균 |
---|---|---|---|
deliciouscat/kf-deberta-base-cross-sts | raw + Contrastive Learning | 0.930 | 1.111 |
deliciouscat/kf-deberta-base-cross-sts | raw + Cleaning | 0.930 | 1.111 |
sorryhyun/sentence-embedding-klue-large | Data v2 | 0.923 | 0.800 |
snunlp/KR-ELECTRA-discriminator | Data v2 | 0.932 | 1.200 |
snunlp/KR-ELECTRA-discriminator | Data v3 | 0.930 | 1.111 |
위의 세 가지 방법을 비교한 결과, Min-Max 정규화 가중 평균을 적용한 경우 가장 높은 성능을 보였습니다. 92.98의 Public Pearson 점수를 기록하였고, 다른 기법들보다 우수한 결과를 확인할 수 있었습니다. 이 과정을 통해 다양한 모델의 조합과 그 성능을 극대화할 수 있었습니다.
Leader Board에서 Pearson 점수를 비교하였을 때 Public Score보다 0.105가 올라, 대회에 참여한 16팀 중 최종 4위를 기록하는 성과를 내었습니다.
Public Leader Board 순위 (중간 순위)
Private Leader Board 순위 (최종 순위)
불균형한 데이터을 다루며 데이터 증강을 진행하면서 원래 문장과 증강된 문장들 간 유사도 측정에 코사인 유사도를 활용했습니다. 하지만 후에 모델팀의 Clustering 실험 결과, 전반적으로 코사인 유사도가 높은 값을 보이는 Anisotropy 문제가 존재한다는 것을 알게 되었습니다. 데이터 증강 작업에 집중하다 보니 상대적으로 적은 양의 데이터셋에 초점을 맞추는 경향이 있었고, 데이터셋 전체를 보는 시각이 부족했음을 느꼈습니다.
또한, 모델팀과 의견 교환이 원활하지 않아 이런 문제를 함께 논의할 수 없었던 점이 아쉬움으로 남습니다. 하지만 이를 개선하기 위해 다음 프로젝트를 진행하면서는 피어세션 시간마다 모델팀과 데이터팀이 진행 상황을 정기적으로 공유하는 체계를 마련하기로 했습니다. 이를 통해 상호 피드백을 통해 문제를 조기에 인지하고 해결할 수 있을 것이라 기대합니다.
향후 프로젝트에서는 데이터 증강 작업 시 개별 데이터의 처리뿐만 아니라, 전체 데이터셋의 특성과 균형을 고려하는 포괄적인 접근이 필요하다는 생각을 하게 되었습니다. 주어진 데이터셋이 너무 주관적이지 않은지, 모델이 학습하는 과정에서 혼동을 일으킬 수 있는 데이터가 포함되어 있지 않은지 충분히 고민하지 않았던 점이 아쉬움으로 남습니다. 룰 기반의 전처리 방식을 적용했다면 모델이 이해하기 좋은 데이터셋을 만들 수 있었겠다는 생각도 해보았습니다. 이번 프로젝트를 진행하면서 데이터를 다루었던 경험은 앞으로의 데이터 처리와 증강 작업에 있어 더 균형 잡힌 시각과 접근 방식을 갖추는 데 밑바탕이 되어줄 것 같습니다.
나는 내 학습 목표를 달성하기 위해 무엇을 어떻게 했는가?
어떠한 고민 속에서 모델의 성능을 향상하려 했는가?
협업 과정에서 잘된 점/아쉬운 점은 어떤 점이 있는가?
프로젝트에서 협업 도구를 활용하며 어떤 경험과 교훈을 얻었는가?
배운 점과 앞으로의 목표