코사인 유사도 Cosine Similarity 개념 정리
코사인 유사도란?
코사인 유사도는 두 문서 벡터의 방향이 얼마나 유사한지를 측정하는 방법입니다. 두 벡터가 이루는 각도가 $ 0^{\circ} $에 가까울수록 유사도가 높고, $ 90^{\circ} $에 가까울수록 유사도가 낮습니다.
- 코사인 유사도 수식
- 코사인 유사도 특징
- 파이썬을 활용한 코사인 유사도 계산
코사인 유사도 수식
두 벡터 A와 B가 있을 대, 코사인 유사도는 다음과 같이 정의됩니다.
$$ \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} $$
여기서, $ \mathbf{A} \cdot \mathbf{B} $는 두 벡터의 내적, $ \|\mathbf{A}\| $는 벡터 A의 크기, $ \|\mathbf{B}\| $는 벡터 B의 크기를 의미합니다.
즉, 두 벡터의 내적을 각 벡터의 크기의 곱으로 나눈 값입니다. 이 값은 [-1,1] 범위를 가지며, 일반적인 문서 벡터에서는 0~1 사이의 값을 갖습니다.
위의 수식을 적용하여, 두 문장의 코사인 유사도를 계산하면 다음과 같습니다.
예제 문장
문장 A: "나는 파이썬을 좋아합니다."
문장 B: "나는 파이썬과 자바를 공부합니다."
벡터화 - 단어 출현 수 CountVectorizer 사용
단어 | 나는 | 파이썬 | 좋아합니다 | 자바 | 공부합니다 |
문장 A | 1 | 1 | 1 | 0 | 0 |
문장 B | 1 | 1 | 0 | 1 | 1 |
코사인 유사도 계산
벡터 A = (1, 1, 1, 0, 0) / 벡터 B = (1, 1, 0, 1, 1)
1. 내적 $ (\mathbf{A} \cdot \mathbf{B}) $
$$ (1\times 1)+(1\times 1)+(1\times 0)+(0\times 1)+(0\times 1)= 1+1+0+0+0=2 $$
2. 벡터의 크기(norm)
$$ \|\mathbf{A}\| = \sqrt{(1^2 + 1^2 + 1^2 + 0^2 + 0^2)} = \sqrt{3} \approx 1.732 $$
$$ \|\mathbf{B}\| = \sqrt{(1^2 + 1^2 + 0^2 + 1^2 + 1^2)} = \sqrt{4} = 2 $$
3. 코사인 유사도 계산
$$ \cos(\theta) = \frac{1.732 \times 2}{2 \times 2} = \frac{3.464}{4} \approx 0.577 $$
코사인 유사도 특징
코사인 유사도의 특징은 다음과 같습니다.
1. 크기가 아닌 방향으로 유사도를 측정합니다.
문장의 길이가 다르더라도 내용이 비슷할 경우, 높은 유사도를 가질 수 있습니다.
2. 코사인 유사도는 0에서 1사이의 값을 가집니다.
1에 가까울수록 두 문장은 비슷하고, 0에 가까울수록 다름을 의미합니다.
아래의 그래프는 두 벡터가 이루는 각도에 따른 코사인 유사도입니다.
X축은 두 벡터가 이루는 각도($ 0^{\circ} $ ~ $ 180^{\circ} $)이며, Y축은 코사인 유사도 값입니다.각도가 $ 0^{\circ} $일 경우, 두 벡터가 완전히 같은 방향으로 완전히 유사한 문서를 의미합니다. 각도가 $ 90^{\circ} $일 경우, 두 벡터는 직교를 이루므로 관련성이 전혀 없음을 의미합니다. 유의할 점은 이론적으로 코사인 유사도는 [-1,1] 범위를 가지지만, 텍스트 분석에서는 -1이 나오는 경우가 거의 없기 때문에 0~1 범위에서 해석해야 한다는 점입니다(단어 등장 빈도 기반의 벡터화에서는 음수 값이 나오지 않기 때문입니다).
파이썬을 활용한 코사인 유사도 계산
코사인 유사도를 계산하기 위해서는 먼저 문장 수치화가 필요합니다. 다음은 TfidfVectorizer를 사용하여 문장을 벡터화하고, 코사인 유사도를 계산하는 방법입니다. 코사인 유사도는 약 0.34입니다.
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
sentence1 = "I love programming."
sentence2 = "I love swimming."
# TF-IDF 벡터화
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform([sentence1, sentence2])
# 코사인 유사도 계산
cos_sim = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])
print(f"Cosine Similarity: {cos_sim[0][0]}")
다음은 CountVectorizer를 사용하여 문장을 벡터화하고, 코사인 유사도를 계산하는 방법입니다. 코사인 유사도는 약 0.5입니다.
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
sentence1 = "I love programming."
sentence2 = "I love swimming."
# CountVectorizer 벡터화
vectorizer = CountVectorizer()
count_matrix = vectorizer.fit_transform([sentence1, sentence2])
# 코사인 유사도 계산
cos_sim = cosine_similarity(count_matrix[0:1], count_matrix[1:2])
print(f"Cosine Similarity: {cos_sim[0][0]}")
'이론' 카테고리의 다른 글
[NLP] 텍스트 임베딩 Text Embedding 개념 정리 - 응용 분야, 종류 (2) | 2025.03.24 |
---|---|
[이론] 클러스터링 평가 지표 - ARI, Confusion Matrix (0) | 2025.03.12 |
[NLP] 자연어 처리 입문을 위한 개념 정리- NLP, LLM (3) | 2025.02.17 |
[NLP] 자카드 유사도 Jaccard Similarity 개념 정리 (4) | 2025.02.13 |
[DL] 딥러닝의 작동 원리 - 가중치, 손실함수, 옵티마이저를 중심으로 (1) | 2024.12.23 |