본문 바로가기

Natural_Language

[NLP] 03. 자연어 처리 개요 - 텍스트 유사도

반응형

아래 내용은 텐서플로우와 머신러닝으로 시작하는 자연어처리

책을 바탕으로 작성 된 내용입니다.

 

 

텍스트 유사도( Text Similarity )

- 텍스트 유사도란, 말 그대로 텍스트가 얼마나 유사한지를 표현하는 방식 중 하나

- 유사도를 판단하는 척도가 주관적이기 대문에 데이터를 정량화하기 쉽지않고 한계가 있다.

- 이를 최대한 정량화해서 모델을 만드는 것이 중요하다.

- 자주 사용되는 유사도 측정 방법

자카드 유사도 / 유클리디언 유사도 / 맨하탄 유사도 / 코사인 유사도

 

# 단어 벡터화

- 우선 각 유사도를 측정하기 전 두가지 예시 문자을 확인

sentence = ( "휴일 인 오늘 도 서쪽 을 중심 으로 폭염 이 이어졌는데요, 내일 은 반가운 비 소식 이 있습니다.",
	     "폭염 을 피해서 휴일 에 놀러왔다가 갑작스런 비 로 인해 망연자실 하고 있습니다.")

- TF-IDF를 통해 벡터화

from sklearn.feature_extraction.text import TfidfVectorizer

# 객체 생성
tfidf_vectorizer = TfidfVectorizer()

# 문장 벡터화 진행
tfidf_matrix = tfidf_vectorizer.fit_transform(sentence)

# 각 단어
text = tfidf_vectorizer.get_feature_names()

# 각 단어의 벡터 값
idf = tfidf_vectorizer.idf_

- TF-IDF로 벡터화한 값은 자카드 유사도를 제외한 유사도 측정에 모두 사용할 것이다.

 

출력 벡터 값

- 자카드 유사도의 경우 벡터화 없이 바로 유사도 측정이 가능

 

 

자카드 유사도( Jaccard Similarity)

- 두 문장을 각각 단어의 집합으로 만든 뒤 두 집합을 통해 유사도를 측정하는 방식 중 하나

- 유사도를 측정하는 방법은 두 집합의 교집합인 공통된 단어의 개수를 두 집합의 합집합, 전체 단어의 갯수로 나눈다.

- 결괏값은 공통의 원소의 개수에 따라 0과 1사이의 값이 나올 것이고, 1에 가까울수록 유사도가 높다

 

#자카드 유사도 구하는 공식

 

자카드 유사도 공식

- 여기서 A, B는 두 문장이다.

- 유사도를 측정할 때 단어에서 조사는 따로 구분에서 사용한다.

- 자카드 공식에 위의 예제를 대입하면 두 문장의 교집합은 6개, 합집합은 24개이다.

- 따라서 자카드 유사도는 6/24 = 0.25이다.

 

 

코사인 유사도

- 코사인 유사도는 두 개의 벡터값에서 코사인 각도를 구하는 방법이다. 

- 코사인 유사도 값은 -1과 1사이의 값을 가지고 1에 가까울수록 유사하다는 것을 의미한다.

- 유사도를 계산할 때 가장 널리 쓰이는 방법 중 하나다. 일반적으로 성능이 좋기 때문!

- 단순히 좌표 상의 거리를 구하는 다른 유사도 측정과 달리 두 벡터의 각도를 구하므로 방향성의 개념이 더해진다.

- 두 문장이 유사하다면 같은 방향을 가리키고, 그렇지 않다면 직교로 표현 될 것이다.

 

코사인 유사도 공식

 

- 앞서 TF-IDF로 벡터화한 문장을 사용해 코사인 유사도를 구해본다.

 

 

# 사이킷런의 코사인유사도

from sklearn.metrics.pairwise import cosine_similarity

cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])

- 여기서 tfidf_matrix[0:1] 는 첫 번째 문장이고, tfidf_matrix[1:2] 는 두 번째 문장이다.

- 코사인 유사도는 사이킷런에서 유사도 측정을 위한 함수를 제공한다.

 

결과 창

- 코사인 유사도에서 문장 A와 문장 B의 유사도는 0.179로 산출된다.

 

 

유클리디언 유사도 ( L2 Distance )

- 가장 기본적인 거리를 측정하는 유사도 공식이다.

 

유클리디언 유사도 공식

 

- 유클리디언 거리 = L2 거리 : N차원 공간에서 두 점 사이의 최단 거리를 구하는 접근법

 

 

#사이킷런의 유클리디언 유사도

from sklearn.metrics.pairwise import euclidean_distances

euclidean_distances(tfidf_matrix[0:1], tfidf_matrix[1:2])

- 유클리디언 유사도는 사이킷런에서 유사도 측정을 위한 함수를 제공한다.

 

결과 창

- 앞서 확인했던 유사도 방식들은 모두 0과 1사이의 값을 가졌는데, 유클리디언 유사도는 1보다 큰 값이 나왔다.

- 유클리디언 유사도는 단순히 두 점 사이의 거리를 뜻하므로 값에 제한이 없다.

- 다른 유사도와 비교하려면 0과 1사이의 값으로 맞춰주어야한다.

- 앞서 구한 벡터를 일반화한 후 다시 유클리디언 유사도를 측정하면 0과 1사이의 값을 가진다.

 

 

# 벡터를 일반화 + 유클리디언 유사도 

import numpy as np

def l1_normalize(v):
	norm = np.sum(v)
    return v / norm
    
    
tfidf_norm_l1 = l1_normalize(tfidf_matrix)

euclidean_distances(tfidf_norm_l1[0:1], tfidf_norm_l1[1:2])

- 위의 코드에서는 L1 정규화 방법을 사용한다

- L1 정규화 방법 : 각 벡터안의 요소값을 모두 더한 것의 크기가 1이 되도록 벡터의 크기를 조절하는 방법

                      : 즉, 벡터의 모든 값을 더한 뒤, 이 값으로 각 벡터의 값을 나눈다.

- 유클리디언 유사도를 측정 할 때는, 편의를 위해 정규화한 후 측정하는 방법도 있다는 점을 기억!

 

 

맨하탄 유사도 ( L1 Distance )

- 맨하탄 거리를 통해 유사도를 측정하는 방법이다.

- 사각형 격자로 이뤄진 지도에서 출발점에서 도착점까지를 가로지르지 않고 갈 수 있는 최단거리를 구하는 공식

- 맨하탄 거리 = L1 거리

 

맨하탄 유사도 공식

 

- 맨하탄 유사도  또한 유클리디언 유사도와 마찬가지로 값이 계속 커질 수 있다.

- 따라서 0과 1 사이의 값을 갖도록 L1 정규화방법을 사용한 벡터 값으로 유사도를 측정한다.

 

# 벡터를 일반화 + 맨하탄 유사도 

import numpy as np

def l1_normalize(v):
	norm = np.sum(v)
    return v / norm 
  
# L1 정규화  
tfidf_norm_l1 = l1_normalize(tfidf_matrix)

# 맨하탄 유사도
from sklearn.metrics.pairwise import manhattan_distances

manhattan_distances(tfidf_norm_l1[0:1], tfidf_norm_l1[1:2])

- 위와 같이 TF-IDF 값을 정규화 해준 뒤 맨하탄 유사도를 구해야 0과 1사이의 값이 나온다.

 

결과 창

- 맨하탄 유사도로 측정했을 때 유사도가 가장 높게 나왔다. 측정 방법에 따라 크게 유사도가 달라질 수 있으므로, 의도하고자 하는 방향에 맞는 유사도측정 방법을 고르는 것이 중요하다

반응형