[자연언어처리] 2-5. 코사인 유사도 cosine similarity
임베딩 벡터의 유사도를 측정하는 기본적인 유사도
코사인 유사도 cosine similarity
정의
- 두 벡터 사이의 유사도를 판단하기 위해 사용하는 계산 방법, 혹은 유사도 값
- 두 벡터의 방향이 동일하면 1의 값을 가지고, 직교하면 0을 가지게 된다.
- 1에 가까울 수록 유사성이 높고, 0에 가까울 수록 유사성이 낮은 것이다.
- 자연어처리에서는 단어 또는 문서 벡터 사이의 유사도를 비교하기 위해 사용될 수 있다.
계산법
\[\text{similarity} = \cos(\theta) = \frac{A \cdot B}{\|A\| \|B\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}}\]- 코사인 유사도는 두 벡터의 내적을 두 벡터의 크기(길이) 곱으로 나눈 것이다.
- 쉽게 말해 두 벡터가 크기(길이)에 상관 없이 방향이 얼마나 유사한가를 측정하는 것이다.
- 분자 : 두 벡터의 내적
- 분모 : 두 벡터 크기의 곱
보통 코사인 유사도를 계산할 때에는
unit length로 만든 뒤 계산한다.
unit length 란, 벡터의 길이가 1이란 뜻이다. (||a|| = ||b|| = 1)
그 이유는, unit length 로 만들 경우 분모 계산 필요 없이 두 벡터의 점곱만으로 간단하게 연산할 수 있기 때문이다.
코드
직접 계산해보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import numpy as np
vector_a = (1, 10)
vector_b = (3, 2)
# cosine similarity (직접 구축)
def cosine_similarity(vector_a, vector_b):
# type check
arr_a = vector_a if isinstance(vector_a, np.ndarray) else np.array(vector_a)
arr_b = vector_b if isinstance(vector_b, np.ndarray) else np.array(vector_b)
# dimension check
if arr_a.shape != arr_b.shape:
raise ValueError("dimension dismatched")
# cosine similarity
length_sum_a = 0
length_sum_b = 0
point_mul_sum = 0
for point_a, point_b in zip(arr_a, arr_b):
length_sum_a += point_a**2
length_sum_b += point_b**2
point_mul_sum += point_a * point_b
cosine_similarity = point_mul_sum / ((length_sum_a**0.5) * (length_sum_b**0.5))
return cosine_similarity
print(cosine_similarity(vector_a, vector_b))
>> np.float64(0.6347394233600139)
numpy 라이브러리를 이용
1
2
3
4
5
6
7
8
9
10
11
12
13
# cosine similarity (numpy)
import numpy as np
from numpy import dot
from numpy.linalg import norm
vector_a = (1, 10)
vector_b = (3, 2)
arr_a = np.array(vector_a)
arr_b = np.array(vector_b)
print(dot(arr_a, arr_b) / (norm(arr_a)*norm(arr_b)))
>> np.float64(0.6347394233600139)
gensim 라이브러리를 이용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# cosine similarity (gensim)
from gensim.matutils import cossim
vector_a = (1, 10)
vector_b = (3, 2)
arr_a = np.array(vector_a)
arr_b = np.array(vector_b)
# 희소행렬로 변환
# gensim 의 경우 계산 대상인 vector를 generator 방식으로 작동하도록 해야함
sparse_vector_a = enumerate(arr_a)
sparse_vector_b = enumerate(arr_b)
# 코사인 유사도
sim = cossim(sparse_vector_a, sparse_vector_b)
print(sim)
>> 0.6347394233600139
코사인 유사도의 사용
- 임베딩 모델을 통해 만들어진 단어 벡터 또는 문서 벡터 사이의 유사성 비교
- 이를 통해 문서 검색, 챗봇, 표절 검사 등에 사용된다.
- 벡터간 유사성 비교이므로 텍스트 뿐만 아니라 추천 시스템, 분류 문제 등에서도 사용할 수 있다.
실습
- 추후 시간 나면 실습 코드 리뷰
Reference
방송통신대학교 - 자연언어처리 수업 (유찬우 교수)
// reading compass
이 글과 이어지는 경로
시리즈, 카테고리, 태그 겹침, 최신도를 점수화해 가까운 글일수록 중심에 배치합니다.
댓글 남기기