logo

딥러닝 기반 임베딩과 Sentence-BERT

딥러닝을 이용한 임베딩

행렬 기반 임베딩의 한계

  • 문서단어 행렬을 특이값 분해(SVD)와 같은 기법으로 저차원 벡터 공간으로 축소
  • 단어와 문서에 내재된 잠재적 의미를 벡터로 표현
  • 단어의 동시 등장 빈도(Co-occurrence) 통계에 의존
  • 한계1: 문맥 파악 능력 부족:
    • 단어의 의미는 문맥에 따라 크게 달라짐 (e.g., "사과" - 과일 vs. 용서)
    • LSA는 단어별로 고정된 벡터를 생성하므로, 문맥에 따른 다의어(Polysemy) 의미 변화를 효과적으로 포착하기 어려움
  • 한계2: 어순 및 문장 구조 정보 손실:
    • 주로 '단어 자루(Bag-of-Words)' 모델에 기반
    • 단어의 순서나 문장 내 문법적 구조가 임베딩에 충분히 반영되지 않음
    • "개가 사람을 물었다" vs. "사람이 개를 물었다"의 의미 차이를 구분하기 어려울 수 있음
  • 한계3: 미묘한 의미 관계 포착의 어려움:
    • 단순 동시 등장 빈도에 의존
    • 동의어지만 함께 잘 등장하지 않는 단어들이나 복잡한 의미 관계를 파악하는 데 한계
    • 새로운 단어(Out-of-Vocabulary) 처리가 어려울 수 있음
  • 전역적(Global) 정보 중심: 개별 단어의 지역적(Local) 문맥보다는 문서 전체의 전역적 통계에 더 집중하는 경향

딥러닝 기반 임베딩

  • 딥러닝 모델은 단어의 주변 문맥을 함께 고려하여 단어/문장의 벡터 표현을 동적으로 생성. → 다의어 문제 해결에 효과적
  • 언어 구조 및 순서 정보 활용: 모델 구조 자체가 순서 정보를 처리하도록 설계 → 어순과 문법적 구조를 임베딩에 반영 가능
  • 대규모 데이터 사전 학습(Pre-training)
    • 방대한 텍스트 데이터로 미리 학습
    • 언어의 복잡하고 미묘한 패턴, 문법, 상식 등을 임베딩에 내포시킴
  • 특정 과제에 대한 미세 조정(Fine-tuning)
    • 문장 유사도 측정, 질의응답 등 특정 NLP 과제에 맞춰 모델을 추가 학습
    • 해당 과제에 대한 성능 극대화 가능

Word2Vec

  • 신경망 언어 모형: 신경망을 통해 다음에 나올 단어를 예측
  • Word2Vec: 두 단어의 임베딩을 신경망에 입력했을 때, 두 단어가 가까이 나올 확률을 계산하는 신경망을 만들어 학습

FastText

  • Word2Vec은 등록된 어휘의 임베딩만 만들 수 있음
  • FastText는 새로운 어휘의 임베딩도 만들 수 있게 한 방법
  • 한 단어를 n-gram으로 분해
    • 예: orangeor, ora, ran, ang, nge, ge
  • 각 n-gram의 임베딩을 더하면 단어의 임베딩이 되도록 학습
  • 새로운 단어도 n-gram으로 분해하여 임베딩을 구할 수 있음

BERT

  • Bi-directional Encoder Representations from Transformers
  • 양방향 Bi-directional으로 정보를 처리하는 트랜스포머 기반의 언어 모형
  • 트랜스포머의 인코더를 이용
  • GPT와 달리 문장 중간의 마스킹된 단어를 예측하도록 학습
  • 다양한 종류의 자연어 처리 과제에 전이 학습을 쉽게 할 수 있도록 설계

Sentence-BERT

  • 문장 임베딩을 위한 BERT 모형
  • siamese neural network: 두 개의 동일한 BERT에 문장을 입력하고, 그 출력을 바탕으로 학습
  • 모든 토큰의 출력에 Mean Pooling
  • 과제의 종류에 따라 다른 목적 함수(손실 함수)를 사용
    • 분류
    • 회귀
    • 삼중항

삼중항 손실 triplet loss

  • 대조 손실의 확장
  • 기준(a), 긍정(p), 부정(n) 3개의 텍스트를 사용
    • p는 a와 같은 내용을 다루는 텍스트
    • n은 a와 다른 내용을 다루는 텍스트
  • a의 임베딩이 n보다 p에 가깝게 출력하도록 학습
  • 적절한 난이도의 삼중항 찾기
    • a와 n이 너무 다르면 학습이 전혀 안됨
    • a와 n이 너무 비슷하면 데이터가 잘못되었거나(예: 같은 내용이 다른 내용으로 잘못 레이블링) 특이 사례일 수 있음
    • 너무 쉽거나 너무 어렵지 않은 정도의 semi-hard data를 찾아 학습

설치 및 임포트

  • colab에서 실습 시 런타임 → 런타임 유형 변경 → GPU
  • 설치
!pip install sentence_transformers
  • 임포트
from sentence_transformers import SentenceTransformer

문장 BERT 모델

  • https://huggingface.co Models
  • Task: Natural Language Processing → Sentence Similarity
  • Languages: Korean
  • 모델마다 학습된 방식이 다르므로, 받아서 사용해보고 자신의 데이터에 맞는 것으로 사용
  • 데이터가 충분히 많다면(예: 1만 개 이상) 직접 학습시킬 수도 있음
  • 모델 로딩
sbert = SentenceTransformer('jhgan/ko-sroberta-multitask')

문장 임베딩

# 파일열기
import pandas as pd
df = pd.read_excel('patents.xlsx')

# 문장 임베딩
doc_emb = sbert.encode(df['abstract'].tolist())

# 저장
import numpy as np
np.save('doc_emb.npy', doc_emb)

# 불러오기
doc_emb = np.load('doc_emb.npy')

문서 유사도

from sklearn.metrics.pairwise import cosine_distances
doc_idx = 0 # 0번 문서와 비슷한 문서 보기

dists = cosine_distances(doc_emb[[doc_idx]], doc_emb).flatten() # 코사인 거리
rank = np.argsort(dists) # 정렬
top10 = rank[:10] # 가장 가까운 10개
df.iloc[top10] # 문서 보기
  • cosine_distances는 1 - cosine_similarity
  • 유사도가 높을 수록, 거리가 작음 → 비슷한 문서가 앞쪽으로 정렬
Previous
LSA 실습