1 분 소요


텍스트 유사도

코사인 유사도(Cos)

가장 많이 사용되는 기법

  • 백터 내적
\[\overrightarrow{a}\cdot{}\overrightarrow{b}=\vert\overrightarrow{a}\vert*\vert\overrightarrow{b}\vert*cos{θ}\]
In [1]:
import numpy as np
from numpy import dot
from numpy.linalg import norm
In [2]:
# 코사인 세타를 구하는 함수
def cos_sim(A, B):
    return dot(A, B)/(norm(A)*norm(B)) # norm(A): 벡터 A의 길이
문서 1: 나는 치킨 좋아요
문서 2: 나는 피자 좋아요
문서 3: 나는 피자 좋아요 나는 피자 좋아요

          나는  치킨  피자  좋아요
문서 1:     1     1     0     1
문서 2:     1     0     1     1
문서 3:     2     0     2     2
In [3]:
doc1 = np.array([1,1,0,1])
doc2 = np.array([1,0,1,1])
doc3 = np.array([2,0,2,2])
In [4]:
print(cos_sim(doc1, doc2))
print(cos_sim(doc1, doc3))
print(cos_sim(doc2, doc3)) # 각도, 방향이 같으므로 두 문서의 유사도는 100%이다.
Out [4]:
0.6666666666666667
0.6666666666666667
1.0000000000000002

sklearn - cosine_similarity

In [5]:
from sklearn.metrics.pairwise import cosine_similarity
In [6]:
print(cosine_similarity([doc1], [doc2]))
print(cosine_similarity([doc1], [doc3]))
print(cosine_similarity([doc2], [doc3]))
Out [6]:
[[0.66666667]]
[[0.66666667]]
[[1.]]

유클리드 거리

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

말의 어조, 억양에 대해서는 의미가 있으나 일반적으로 잘 사용하지 않는다.

  • 두 점 사이의 거리 공식
\[d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}\]
In [7]:
def eu_dist(A, B):
    return np.sqrt(np.sum((A-B)**2))
In [8]:
print(eu_dist(doc1, doc2))
print(eu_dist(doc1, doc3))
print(eu_dist(doc2, doc3)) # 각도가 아니라 거리이므로 강도의 차이가 있다.
Out [8]:
1.4142135623730951
2.6457513110645907
1.7320508075688772

sklearn - euclidean_distances

In [9]:
from sklearn.metrics.pairwise import euclidean_distances
In [10]:
print(euclidean_distances([doc1], [doc2]))
print(euclidean_distances([doc1], [doc3]))
print(euclidean_distances([doc2], [doc3]))
Out [10]:
[[1.41421356]]
[[2.64575131]]
[[1.73205081]]

맨해튼 유사도

Manhattan Similarity

정수 처리가 필요한 경우 사용한다.

In [11]:
from sklearn.metrics.pairwise import manhattan_distances
In [12]:
print(manhattan_distances([doc1], [doc2]))
print(manhattan_distances([doc1], [doc3]))
print(manhattan_distances([doc2], [doc3]))
Out [12]:
[[2.]]
[[5.]]
[[3.]]

자카드 유사도

Jaccard Similarity

공통된 단어가 얼마나 있는지 나타낸다.

  • \[J(A, B) = \frac{\vert{A∩B}\vert}{\vert{A∪B}\vert}\]
In [13]:
doc1 = '나는 치킨 좋아요'
doc2 = '나는 피자 좋아요'
doc3 = '나는 피자 좋아요 나는 피자 좋아요'

token_doc1 = doc1.split()
token_doc2 = doc2.split()
token_doc3 = doc3.split()

# 합집합
union = set(token_doc1).union(set(token_doc2))
# 교집합
intsec = set(token_doc1).intersection(set(token_doc2))
In [14]:
union, intsec
Out [14]:
({'나는', '좋아요', '치킨', '피자'}, {'나는', '좋아요'})
In [15]:
len(intsec)/len(union)
Out [15]:
0.5
In [16]:
print(len(set(token_doc1).intersection(set(token_doc2)))/len(set(token_doc1).union(set(token_doc2))))
print(len(set(token_doc1).intersection(set(token_doc3)))/len(set(token_doc1).union(set(token_doc3))))
print(len(set(token_doc2).intersection(set(token_doc3)))/len(set(token_doc2).union(set(token_doc3))))
Out [16]:
0.5
0.5
1.0

태그: ,

카테고리:

업데이트:

댓글남기기