데이터 한 그릇

자연어 처리 개요_텍스트 유사도 본문

NLP/텐서플로2와 머신러닝으로 시작하는 자연어처리

자연어 처리 개요_텍스트 유사도

장사이언스 2022. 1. 9. 14:21

자연어 처리 개요_텍스트 유사도

"이 노래 누가 만들었어?"

 

"지금 나오는 노래 작곡가가 누구야?"

 

 

우리는 이 두 개의 문장이 같은 의미를 지니고 있는지 금방 파악할 수 있지만, 기계는 그러지 못한다. 따라서 두 문장에 대해 답변을 하려면 각각의 답변을 준비해야만 한다.

 

 

하지만 이 텍스들간에 유사성이 있음을 판단하면 한 개의 답변만 준비하면 된다.

 

이 두 텍스트가 유사한지 유사하지 않은지 측정하면 되는데, 이때 사용하는 방법이 텍스트 유사도(TextSimilarity) 다.

 

 

텍스트 유사도 방식에는 여러 가지 방식이 있는데, 그 중에서

 

 

 

***딥러닝을 기반으로 텍스트의 유사도를 측정하는 방식을 주로 다룰 예정.***

 

 

 

***텍스트를 벡터화 한 이후에, 벡터화 된 각 문장간의 유사도를 측정하는 방법.***

 

(text -> 벡터화

text 내의 각 문장들도 벡터화됨.

각 벡터화된 문장들의 유사도 측정)

 

 

4개의 유사도 측정 방법 존재.

 

  1. 자카드 유사도
  2. 유클리디언 유사도
  3. 맨허튼 유사도
  4. 코사인 유사도

 

먼저 밑의 두 문장에 대해서 Document Term Matrix 를 tf_idf 방식으로 만들어보자.

 

 

 

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

 

 

from sklearn.feature_extraction.text import TfidfVectorizer

#해당 문서에 자주 나오면서 다른 문서에는 잘 나오지 않았으면 높은 값을 기록

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

tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(sent)
print()

idf = tfidf_vectorizer.idf_
print(dict(zip(tfidf_vectorizer.get_feature_names(), idf)))

 

 

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

 

자카드 경우 벡터화 없이 바로 유사도 측정이 가능하기 때문에.



자카드 유사도

 

 

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

 

(A -> 단어의 집합 A(X)

B -> 단어의 집합 B(Y)

X <-> Y 의 유사도 측정)

 

 

두 집합의 교집합인 공통된 단어의 개수 CO_NUM 을 두 집합의 합집합인 전체 단어의 개수 EN_NUM 로 나눈 수치.

 

값은 0과 1사이의 값을 기록

1에 가까울소록 유사도가 높다는 의미, 0에 가까울수록 유사도가 낮다는 의미.

 

코사인 유사도

 

 

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

 

-1 ~ 1 사이의 값을 가진다.

1에 가까울수록 유사하다.

 

 

가장 널리 쓰이는 방식.

 

 

 

다른 유사도 방식은 단순 좌표상의 거리를 구하는 게 다인데, 벡터 간의 각도를 구하기 때문에 방향성의 개념이 더해져서 더 정확하다.

 

 

두 문장이 유사하다면 같은 방향을 가리킬 것이고, 유사하지 않을수록 `직교` 로 표현이 된다.

 

 

from sklearn.metrics.pairwise import cosine_similarity

cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2]) #두 개의 단어를 비교

 

유클리디언 유사도

L2 거리라고도 부름

 

n 차원 공간에서 두 점 사이의 최단 거리를 구하는 공식.

 

 

from sklearn.metrics.pairwise import euclidean_distances

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

 

 

앞선 유사도 방식들은 0 ~ 1 사이의 값을 가졌는데, 유클리디언 유사도는 단순 두 점 사이의 거리기 때문에 값에 리미트가 없다.

 

 

 

앞서 각 문장을 벡터화 시켰는데, 이 벡터를 일반화하면 도출되는 유클리디언 유사도도 0~1사이의 값을 가진다.

 

이 일반화, 정규화 방식을 L1 정규화 방법이라고 정할 것.

 

L1 정규화 방법은 각 벡터 안의 요소 값들을 모두 더한 다음, 이 값으로 각 벡터 안의 요소 값을 나눈다.

 

 

import numpy as np

def l1_normalization(v):
    norm = np.sum(v)
    return v / norm

tfidf_norm_l1 = l1_normalization(tfidf_matrix)
euclidean_distances(tfidf_norm_l1[0:1],tfidf_norm_l1[1:2])

 

맨하튼 거리

 

 

사각형 격자로 이뤄진 지도에서 출발점부터 도착지까지 가로지르지 않고 가장 빨리 도착하는 경로를 찾는 것.

 

유클리디언 거리를 L1 거리라고 불렀다면 맨하튼 거리는 L2 거리라고 불린다.

 

맨허튼 거리도 마찬가지로 결과값이 0 ~ 1 사이로만 나오지 않고 값에 리미트가 없다.

따라서 정규화 해줄 수 있다.

 

from sklearn.metrics.pairwise import manhattan_distances

tfidf_norm_l1 = l1_normalization(tfidf_matrix)
manhattan_distances(tfidf_norm_l1[0:1],tfidf_norm_l1[1:2])
Comments