- 수업 내용 리마인드 및 아카이빙 목적의 업로드
자연어 처리에서 텍스트의 유사도를 측정하는 것은 매우 중요한 작업이에요. 단어 임베딩을 통해 벡터로 변환된 단어들 사이의 거리를 측정하면, 단어들이 얼마나 비슷한지 계산할 수 있습니다. 이번 글에서는 유클리디안 거리, 자카드 유사도, 코사인 유사도를 계산하는 방법을 단계별로 알아봐요.
1. 유클리디안 거리 (Euclidean Distance)
유클리디안 거리는 두 벡터 사이의 직선 거리를 의미합니다. 즉, 두 점 사이의 최단 거리를 구하는 방법이죠. 벡터 간의 차이를 계산한 후, 그 차이의 제곱을 더하고 루트를 취하면 유클리디안 거리가 나옵니다.
* 유클리디안 거리 계산 코드 예시
import numpy as np
# 단어 임베딩 사전
word_embedding_dic = {
'사과': [1.0, 0.5],
'바나나': [0.9, 1.2],
'원숭이': [0.5, 1.5]
}
# 유클리디안 거리 계산 함수
def euclidean_dist(x, y):
x = np.array(x)
y = np.array(y)
return np.sqrt(np.sum((x - y) ** 2))
# 사과와 바나나의 유클리디안 거리 계산
print(f"사과와 바나나의 유클리디안 거리: {euclidean_dist(word_embedding_dic['사과'], word_embedding_dic['바나나']):.4f}")
위 코드에서는 사과와 바나나의 유클리디안 거리를 계산하고 그 결과는 0.7071입니다. 두 단어의 벡터 간의 거리가 가까울수록 두 단어가 유사하다는 것을 의미해요.
2. 자카드 유사도 (Jaccard Similarity)
자카드 유사도는 두 집합 사이의 유사도를 측정하는 방법입니다. 두 집합의 교집합을 합집합으로 나누어 계산해요. 텍스트에서 자카드 유사도를 계산할 때는, 각 문장을 단어로 나누어 두 집합 간의 유사도를 계산합니다.
* 자카드 유사도 계산 코드 예시
# 두 문장
s1 = '대부분 원숭이는 바나나를 좋아합니다.'
s2 = '코주부 원숭이는 바나나를 싫어합니다.'
# 토큰화
token_s1 = s1.split()
token_s2 = s2.split()
# 교집합과 합집합
union = set(token_s1).union(set(token_s2))
intersection = set(token_s1).intersection(set(token_s2))
# 자카드 유사도 계산
jaccard_similarity = len(intersection) / len(union)
print(f"자카드 유사도: {jaccard_similarity:.4f}")
이 코드에서는 두 문장의 자카드 유사도를 계산합니다. 교집합에는 ['바나나를', '원숭이는']이 포함되고, 합집합에는 총 6개의 단어가 있어, 자카드 유사도는 0.3333입니다.
3. 코사인 유사도 (Cosine Similarity)
코사인 유사도는 두 벡터가 이루는 각도를 바탕으로 유사도를 측정하는 방법입니다. 벡터가 이루는 각도가 작을수록 유사도가 높아지고, 두 벡터가 같은 방향에 있을 때 유사도는 1에 가까워집니다. 반면, 90도일 때는 0, 반대 방향일 때는 -1에 가까워집니다.
* 코사인 유사도 계산 코드 예시
# 단어 임베딩 사전
word_embedding_dic = {
'사과': [1.0, 0.5],
'바나나': [0.9, 1.2],
'원숭이': [0.5, 1.5]
}
# 코사인 유사도 계산 함수
def cosine_similarity(x, y):
nominator = np.dot(x, y) # 두 벡터의 내적
denominator = np.linalg.norm(x) * np.linalg.norm(y) # 벡터 크기의 곱
return nominator / denominator
# 코사인 유사도 계산 예시
print(f"사과와 바나나의 코사인 유사도: {cosine_similarity(word_embedding_dic['사과'], word_embedding_dic['바나나']):.4f}")
print(f"사과와 원숭이의 코사인 유사도: {cosine_similarity(word_embedding_dic['사과'], word_embedding_dic['원숭이']):.4f}")
print(f"바나나와 원숭이의 코사인 유사도: {cosine_similarity(word_embedding_dic['바나나'], word_embedding_dic['원숭이']):.4f}")
위 코드에서는 사과와 바나나의 코사인 유사도는 0.8944, 사과와 원숭이는 0.7071, 바나나와 원숭이는 0.9487로 계산됩니다. 값이 1에 가까울수록 두 벡터(단어)의 유사도가 높다는 것을 의미합니다.
* Scikit-learn을 사용한 코사인 유사도 계산
코사인 유사도를 계산할 때는 Scikit-learn의 cosine_similarity 함수를 사용할 수도 있어요. Scikit-learn을 활용하면 계산이 더 간편해집니다.
from sklearn.metrics.pairwise import cosine_similarity
# 사과와 바나나의 코사인 유사도
cos_sim_ab = cosine_similarity([word_embedding_dic['사과']], [word_embedding_dic['바나나']])[0][0]
print(f"사과와 바나나의 코사인 유사도: {cos_sim_ab:.4f}")
# 사과와 원숭이의 코사인 유사도
cos_sim_am = cosine_similarity([word_embedding_dic['사과']], [word_embedding_dic['원숭이']])[0][0]
print(f"사과와 원숭이의 코사인 유사도: {cos_sim_am:.4f}")
이 코드에서는 Scikit-learn의 cosine_similarity 함수를 사용하여 코사인 유사도를 계산하고, 그 결과는 앞선 결과와 동일하게 나타납니다.
이 글에서는 유클리디안 거리, 자카드 유사도, 코사인 유사도 세 가지 방법으로 단어 사이의 유사도를 계산하는 방법을 알아보았어요. 각각의 방법은 데이터의 특성과 분석 목적에 따라 적절히 선택하면 됩니다.
- 유클리디안 거리는 직선 거리로 두 벡터 간의 차이를 계산하는 방법이에요.
- 자카드 유사도는 두 집합의 유사도를 계산할 때 유용하며, 교집합과 합집합을 이용해 계산합니다.
- 코사인 유사도는 벡터 간의 각도를 바탕으로 유사도를 측정해, 방향성을 고려한 유사도 분석에 적합합니다.
'+ 개발' 카테고리의 다른 글
리스트 컴프리헨션(List Comprehension) (0) | 2024.09.11 |
---|---|
파이썬의 강력한 도구들(ft. Lambda, defaultdict, map) (0) | 2024.09.10 |
문서 표현 기법(ft. Scikit-learn & Gensim) (1) | 2024.09.08 |
N-gram: 텍스트에서 문맥 파악하기 (5) | 2024.09.07 |
단어 표현(Word Representation) (1) | 2024.09.06 |