벡터 DB 유사도 측정 방식 총 정리(L2 Distance,Inner Product, Cosine,Jaccard)
필만이2024. 11. 10. 00:39
벡터 DB 유사도 측정 방식 총 정리
1. L2 Distance (유클리드 거리)
요약 : 유클리드 거리는 벡터 간의 직선 거리를 측정하므로, 크기와 방향 모두가 유사도 계산에 영향을 줍니다.
수학적 원리: 두 벡터 간의 직선 거리를 계산하며, 각 요소의 차이를 제곱해 합한 후 제곱근을 구하는 방식입니다. 이로 인해 두 벡터 간의 물리적 거리를 나타내며 크기와 방향이 모두 고려됩니다.
사용 상황
벡터의 크기와 방향이 모두 중요한 경우, 예: 이미지 임베딩 간 거리 계산, 물리적 거리, 픽셀 간 거리 비교 등.
이런 상황에 왜 좋은가?
이미지 임베딩은 고차원 공간의 특징 벡터로, L2 거리 계산을 통해 시각적 차이를 반영할 수 있습니다.
코드
import numpy as np
import faiss
# 128차원 벡터 10,000개를 가진 임베딩 예시
embeddings = np.random.random((10000, 128)).astype('float32')
# L2 거리 기반 인덱스 생성
index = faiss.IndexFlatL2(128)
index.add(embeddings)
# 쿼리 벡터와 가장 가까운 이웃 찾기 (유클리드 거리 기준)
query = np.random.random((1, 128)).astype('float32')
D, I = index.search(query, k=5) # 가장 가까운 5개 검색
print("L2 Distance Neighbors:", I)
2. (MAX) Inner Product (내적)
요약 : 내적은 벡터의 크기와 방향을 모두 반영하며, 내적 값이 클수록 두 벡터가 더 유사하다는 의미입니다. MAX가 앞에 붙은 이유는 가장 유사도 높은 문서를 여러개 찾는것. Inner Product 와 똑같은거라고 보면됨
수학적 원리: 두 벡터의 대응되는 요소를 곱한 후 모두 더하는 방식으로 계산됩니다. 이는 방향이 비슷하고 크기가 클수록 더 큰 내적 값을 생성합니다.
사용 상황
추천 시스템에서 사용자와 아이템의 선호도를 매칭할 때, 내적을 통해 선호도 강도와 방향성을 반영할 수 있어 추천 시스템에 유리합니다.
이런 상황에 왜 좋은가?
추천 시스템에서 유저와 아이템 임베딩 간의 내적을 계산하면 유저의 선호도 강도가 반영됩니다. 예를 들어, 유저가 특정 아이템을 강하게 선호할수록 해당 아이템 임베딩과 유저 임베딩 간의 내적이 커져, 추천의 우선순위가 높아짐.
또한, 내적을 통해 높은 선호도와 방향성이 맞는 아이템이 자동으로 선택되므로, 유저와 아이템의 관계를 직접적으로 반영하는 데 유리.
코드
import numpy as np
import faiss
# 임베딩 벡터 데이터 예시 (정규화되지 않은 벡터)
data = np.array([
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, 9.0]
], dtype=np.float32)
# 쿼리 벡터 (정규화되지 않음)
query = np.array([[2.0, 3.0, 4.0]], dtype=np.float32)
# MAX_INNER_PRODUCT 방식 - 정규화 없이 내적 계산
index_ip = faiss.IndexFlatIP(data.shape[1]) # Inner Product (IP) 인덱스 생성
index_ip.add(data) # 데이터 추가
# 쿼리 벡터와 유사한 벡터 검색
scores_ip, indices_ip = index_ip.search(query, k=2)
print("MAX_INNER_PRODUCT 방식 (정규화되지 않은 벡터)")
print("유사도 점수:", scores_ip)
print("인덱스:", indices_ip)
3. Cosine Similarity (코사인 유사도)
요약 : 코사인 유사도는 두 벡터의 각도만 고려하고 크기는 무시합니다. 두 벡터의 방향이 유사할수록 코사인 유사도가 높아집니다.
수학적 원리: 벡터의 각도를 계산하여 벡터가 얼마나 같은 방향을 가리키는지 평가하며, 벡터가 같은 방향일 때 1, 반대 방향일 때 -1에 가까운 값을 갖습니다.
사용 상황
벡터 크기를 무시하고 방향만으로 유사성을 파악할 때, 예: 텍스트 임베딩 간 의미 비교, 문서 유사도 분석.
이런 상황에 왜 좋은가?
텍스트 임베딩에서 코사인 유사도는 문장 간의 의미적 유사성을 비교하는 데 효과적입니다. 두 문장의 의미가 비슷할 때 임베딩 벡터의 방향이 유사하게 나타나기 때문에, 크기 차이를 무시하고 방향만 비교하는 코사인 유사도를 사용하는 것이 적합합니다.
예를 들어, "고양이가 창문을 보고 있다"와 "고양이가 창문 너머를 바라보고 있다"는 같은 의미이지만, 단어 수 차이로 인해 벡터의 크기는 다를 수 있습니다. 이때 코사인 유사도를 사용하면 크기와 상관없이 방향만 비교하여 높은 유사도를 얻을 수 있습니다.
코드
import numpy as np
import faiss
# 128차원 벡터 10,000개를 가진 임베딩 예시 생성
embeddings = np.random.random((10000, 128)).astype('float32')
# L2 정규화를 적용하여 각 벡터의 크기를 1로 고정
faiss.normalize_L2(embeddings) # embeddings는 이제 정규화된 상태입니다.
# 내적 기반 인덱스 생성
index = faiss.IndexFlatIP(128) # 128차원 내적 인덱스 생성
index.add(embeddings) # 정규화된 벡터 추가
# 쿼리 벡터 예시 (정규화 필요)
query = np.random.random((1, 128)).astype('float32')
faiss.normalize_L2(query) # 쿼리도 정규화
# 코사인 유사도와 유사한 방식으로 유사한 벡터 검색
D, I = index.search(query, k=5) # 가장 유사한 5개의 벡터 검색
print("유사도 점수:", D)
print("인덱스:", I)
4. Jaccard 유사도
요약 : Jaccard Similarity는 집합 기반 유사도로, 두 집합이 공통 요소를 얼마나 많이 공유하는지 평가합니다.
수학적 원리: 두 집합의 교집합의 크기를 합집합의 크기로 나눈 값으로, 0과 1 사이의 값을 가집니다. 0이면 두 집합에 공통 요소가 없고, 1이면 두 집합이 동일.
사용 상황
두 뉴스 기사가 #정치, #경제, #사회와 같은 해시태그를 가지고 있을 때, Jaccard Similarity를 통해 주제의 유사성을 평가. 두 사용자가 관심 있는 상품 목록을 0과 1로 나타냈다면, Jaccard 유사도를 통해 유사한 관심사를 가진 사용자를 찾을 수 있음.
추천 시스템에서 사용자 행동을 기록한 희소 벡터를 비교하여 유사한 행동 패턴을 가진 사용자나 아이템을 찾는 데 사용할 수 있음. 두 이미지가 #자연, #산, #하늘과 같은 태그를 공유하는 정도에 따라 Jaccard 유사도를 사용해 유사한 이미지를 찾을 수 있음.
이런 상황에 왜 좋은가?
Jaccard 유사도는 집합 기반 데이터에서 공통 항목 비율을 빠르게 계산하여 유사도를 판단할 수 있기 때문에, 태그, 이진 벡터, 범주형 데이터에서 유용
코드
import numpy as np
import faiss
# 두 집합을 이진 벡터로 표현
# 예: 128차원 이진 벡터 10,000개 생성 (각 원소는 0 또는 1)
binary\_embeddings = np.random.randint(2, size=(10000, 128)).astype('uint8')
# FAISS의 IndexBinaryFlat를 사용하여 Hamming 거리 기반으로 유사도 계산
# IndexBinaryFlat는 이진 벡터(0과 1로만 구성된 벡터) 간의 유사성을 Hamming 거리를 통해 비교하는 인덱스
index = faiss.IndexBinaryFlat(128) # 128차원 이진 인덱스 생성
index.add(binary\_embeddings) # 이진 벡터 추가
# 쿼리 벡터 예시 (이진 벡터로 표현)
query = np.random.randint(2, size=(1, 128)).astype('uint8')
# FAISS의 IndexBinaryFlat는 이진 벡터를 처리할 때, 벡터 간 유사도를 Hamming 거리로 측정하고, 이 거리를 **D**에 저장해 반환
# 유사도 검색: Hamming 거리를 사용하여 가장 유사한 5개 항목 검색
# Hamming 거리 : 두 벡터에서 서로 다른 위치에 있는 값의 개수
D, I = index.search(query, k=5)
# Jaccard 유사도 변환: Jaccard = 1 - (Hamming distance / 벡터 길이)
jaccard\_similarity = 1 - D / 128 # 128은 벡터 길이
print("Hamming 거리:", D)
print("Jaccard 유사도:", jaccard\_similarity)
print("인덱스:", I)
표정리
유사도/거리 측정 방식
정의
적합한 사용 예
설명
Inner Product
벡터 내적 계산
- 추천 시스템에서 유저와 아이템의 매칭 - 같은 방향성을 가지는 대형 벡터 간 비교
내적 값이 클수록 벡터의 방향과 크기가 비슷함을 의미하며, 추천 시스템 등에서 유사한 아이템을 찾는 데 활용됨.
L2 Distance
두 벡터 간의 유클리드 거리
- 물리적 거리 계산 - 얼굴 인식 및 이미지 매칭
벡터 간의 절대적 거리를 측정하므로, 실제 좌표상의 물리적 거리를 평가하는 데 유리함.
Cosine Similarity
벡터 간의 각도 기반 유사도
- 텍스트 데이터 유사도 - 문서 및 키워드 매칭 - 추천 시스템에서 선호도 예측
벡터 크기와 상관없이 방향성만 비교하므로, 문서 간 주제 유사성을 파악하거나, 크기 차이를 무시한 유사도 측정에 유리함.
Jaccard Similarity
두 집합의 겹치는 비율
- 태그, 키워드 기반 검색 - 고객의 공통 관심사 분석 - 바이너리 속성 데이터 비교
두 집합의 겹치는 정도를 측정하여 유사도를 계산하므로, 이진 속성이나 범주형 데이터 간 유사도 측정에 적합함.
요약
Inner Product는 크기와 방향을 모두 고려하므로, 추천 시스템처럼 특정 벡터와 내적 값이 최대가 되도록 최적화된 매칭에서 유용합니다.
L2 Distance는 절대적인 거리 계산에 유리하여, 이미지 매칭이나 물리적 거리 평가에 적합합니다.
Cosine Similarity는 크기를 무시하고 방향만 비교하므로, 문서나 텍스트의 주제 유사성을 파악하는 데 효과적입니다.
Jaccard Similarity는 집합 기반 데이터에서 유용하며, 태그나 이진 속성 데이터를 비교하는 데 주로 사용됩니다.