아래 내용은 텐서플로우와 머신러닝으로 시작하는 자연어처리
책을 바탕으로 작성 된 내용입니다.
텍스트 유사도( 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사이의 값이 나온다.
- 맨하탄 유사도로 측정했을 때 유사도가 가장 높게 나왔다. 측정 방법에 따라 크게 유사도가 달라질 수 있으므로, 의도하고자 하는 방향에 맞는 유사도측정 방법을 고르는 것이 중요하다
'Natural_Language' 카테고리의 다른 글
[NLP] 03.자연어 처리 개요 - 데이터 이해하기 (0) | 2019.05.04 |
---|---|
[NLP] 03. 자연어 처리 개요 - 텍스트 분류 (0) | 2019.04.28 |
[NLP] 03. 자연어 처리 개요 - 단어표현/단어임베딩/단어벡터 (0) | 2019.04.28 |
[NLP] 02. 자연어 처리 개발 준비 - 자연어 토크나이징 도구/전처리 (2) | 2019.04.27 |
[NLP] 02. 자연어 처리 개발 준비 - 사이킷런 (0) | 2019.04.27 |