[NLP실습]2.자연어 처리 개요-유사도 및 문제들

jaeyun·2021년 1월 21일
0

자연어 처리 실습

목록 보기
2/2
post-thumbnail

이번 포스팅은 앞의 이론에서 언급했었던 유사도 계산 방법들을 한번 더 설명하고, 구현해보겠습니다. 이론 포스팅은 여기를 클릭해주세요.

텍스트 유사도는 두 개 이상의 텍스트가 얼마나 유사한지 표현하는 방식 중 하나입니다. 텍스트 유사도 측정 방법은 여러가지가 있지만, 여기서는 4가지를 다루겠습니다.

1. 자카드 유사도(Jaccard Similarity)

▶구현 포인트

(1) 입력 받은 문장을 단어 단위로 쪼개주고, 중복을 제거해줍니다.

(2) 두 단어 집합의 합집합을 구해줍니다.

(3) 두 단어 집합의 교집합을 구해줍니다.

(4) 교집합/합집합을 통해 유사도를 구해줍니다.

아래 코드는 자카드 유사도를 구현한 코드입니다.

def jaccard(sent1,sent2):
  #(1) 입력 받은 문장을 단어 단위로 쪼개주고, 중복을 제거해줍니다.
  sent1_tokens = set(sent1.split(' '))
  sent2_tokens = set(sent2.split(' '))
  #(2) 두 단어 집합의 합집합을 구해줍니다.
  union = len(sent1_tokens | sent2_tokens)
  #(3) 두 단어 집합의 교집합을 구해줍니다.
  intersection = len(sent1_tokens & sent2_tokens)
  #(4) 교집합/합집합을 통해 유사도를 구해줍니다.
  return intersection / union

sent1 = "i am so sorry but i love you"
sent2 = "i love you but i hate you"

result = jaccard(sent1,sent2)
print("Jaccard Similarity : ",result)

'''
Jaccard Similarity :  0.5
'''

2. 유클리디언 유사도(Euclidean Similarity)

▶구현 포인트

(1) 임베딩된 두 문장을 구해줍니다.(여기서는 SBERT를 이용하여 임베딩 하였습니다.)

(2) 거리 구하는 공식을 적용시켜 줍니다.

d(x,y)=(x1y1)2+(x2y2)2+...+(xnyn)2\textcolor{#141414}{{d\left(x,y\right)=\sqrt{{\left({x}_1-{y}_1\right)}^2+{\left({x}_2-{y}_2\right)}^2+...+{\left({x}_n-{y}_n\right)}^2}}}

아래 코드는 유클리디언 유사도를 구현한 코드입니다.

여기서는 L1정규화를 적용하지 않았기 때문에 1 이상의 값이 출력될 수 있습니다.

from sentence_transformers import SentenceTransformer
import numpy as np

sent1 = "i am so sorry but i love you"
sent2 = "i love you but i hate you"
model = SentenceTransformer('paraphrase-distilroberta-base-v1')

def euclidean(sent1, sent2):
  sentences = [sent1,sent2]
  #(1) 임베딩된 두 문장을 구해줍니다.(여기서는 SBERT를 이용하여 임베딩 하였습니다.)
  sentence_embeddings = model.encode(sentences)
  #(2) 거리 구하는 공식을 적용시켜 줍니다.
  return np.sqrt(np.sum((sentence_embeddings[0]-sentence_embeddings[1])**2))

result = euclidean(sent1,sent2)
print("Euclidean Similarity : ",result)

'''
Euclidean Similarity :  4.518221
'''

3. 맨하탄 유사도(Manhattan Similarity)

▶구현 포인트

(1) 임베딩된 두 문장을 구해줍니다.(여기서는 SBERT를 이용하여 임베딩 하였습니다.)

(2) 공식을 적용시켜줍니다.

MaDistance=i=1nai​−biMaDis\tan ce=\sum _{i=1}^n|ai​−bi​|

from sentence_transformers import SentenceTransformer
import numpy as np

sent1 = "i am so sorry but i love you"
sent2 = "i love you but i hate you"
model = SentenceTransformer('paraphrase-distilroberta-base-v1')

def manhattan(sent1, sent2):
  sentences = [sent1,sent2]
  #(1) 임베딩된 두 문장을 구해줍니다.(여기서는 SBERT를 이용하여 임베딩 하였습니다.)
  sentence_embeddings = model.encode(sentences)
  #(2) 공식을 적용시켜줍니다.
  return np.sqrt(np.sum(np.abs(sentence_embeddings[0]-sentence_embeddings[1])))

result = manhattan(sent1,sent2)
print("Manhattan Similarity : ",result)

'''
Manhattan Similarity :  9.857575
'''

4. 코사인 유사도(Cosine Similarity)

▶구현 포인트

(1) 임베딩된 두 문장을 구해줍니다.(여기서는 SBERT를 이용하여 임베딩 하였습니다.)

(2) 공식을 적용시켜줍니다.

cos(θ)=abab\textcolor{#141414}{\cos \left(\theta \right)=\frac{\overrightarrow{a}\cdot \overrightarrow{b}}{||\overrightarrow{a}||\cdot ||\overrightarrow{b}||}}

from sentence_transformers import SentenceTransformer
import numpy as np

sent1 = "i am so sorry but i love you"
sent2 = "i love you but i hate you"
model = SentenceTransformer('paraphrase-distilroberta-base-v1')

def cosine(sent1, sent2):
  sentences = [sent1,sent2]
  #(1) 임베딩된 두 문장을 구해줍니다.(여기서는 SBERT를 이용하여 임베딩 하였습니다.)
  sentence_embeddings = model.encode(sentences)
  #(2) 공식을 적용시켜줍니다.
  return np.dot(sentence_embeddings[0],sentence_embeddings[1])/(np.linalg.norm(sentence_embeddings[0])*np.linalg.norm(sentence_embeddings[1]))

result = cosine(sent1,sent2)
print("Cosine Similarity : ",result)

'''
Cosine Similarity :  0.77774066
'''

profile
벨로그에서는 인공지능 관련 포스팅만 합니다! 더 많은 정보는 소개를 참고해주세요!

0개의 댓글