머신러닝

faiss

content0474 2024. 11. 12. 10:11

이전의 embedding 게시물과 이어지는 내용

 

이번에는 faiss를 가져와서 문장을 입력하면 유사한 문장을 찾고 유사도 점수를 보여주게 해보자.

 

전체 코드

더보기

import faiss

# 문장 임베딩을 사용해 인덱스 생성
dimension = sentence_embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)  # L2 거리 기반 인덱스

# 인덱스에 벡터 추가
index.add(np.array(sentence_embeddings))

 

query = "문장을 입력하세요"
query_vec = model.encode(query)

# 유사한 문장 3개 찾기
D, I = index.search(np.array([query_vec]), k=3)

# 결과 출력
for idx, score in zip(I[0], D[0]):
    print(f"유사 문장: {sentences[idx]}, 유사도 점수: {score}")

 

dimension = sentence_embeddings.shape[1]

더보기

임베딩한 문장에 .shpae를 하면 (행,렬) 형태의 튜플이 된다.

만약 10개의 문장이고 200차원의 임베딩 벡터라면 (10,200) 형태이다. 이 때

.shape[0] =10  ->문장의 개수

.shape[1]=200 ->임베딩 벡터의 차원

index = faiss.IndexFlatL2(dimension)

더보기

faiss.IndexFlatL2 는 벡터 데이터를 인덱스에 저장하여 유클리드 거리 기반으로 검색할 수 있게 하는 기본 인덱스를 설정하는 부분이다. 인덱스가 있어야 나중에 유사도를 검색할 때 빠르게 찾을 수 있다.

faiss.IndexFlatL2(dimension)는 차원이 dimension인 벡터를 저장하고 인덱스를 설정한다.

 

index.add(np.array(sentence_embeddings))

더보기

위에서 설정한 인덱스를 벡터 데이터에 추가해준다.

이 코드가 없으면 단순히 인덱스가 어떻다고 정해지기만 했을 뿐 사용할수는 없다. 

np.array는 넘파이 형태 배열로 반환해주는 함수

 

D, I = index.search(np.array([query_vec]), k=3)

더보기

index.search는 유사도(D)와 인덱스(I)를 반환한다.

이 코드는 query_vec과 가장 유사한 3개의 벡터를 찾는 코드이다.

예를 들어

D=[[0.5, 0.7, 0.8]]

I=[[0,3,2]]

이렇게 반환되었다면, 0번인덱스 문장의 유사도는 0.5, 3번 인덱스 문장의 유사도는 0.7, 2번인덱스 문장의 유사도는 0.8이다.

for idx, score in zip(I[0], D[0]):

    print(f"유사 문장: {sentences[idx]}, 유사도 점수: {score}")

더보기

zip은 리스트를 병렬형태 튜플로 묶어주는 함수

그러니까 위의 예시에서 zip을 쓰면

(index, score) = (0, 0.5), (3, 0.7), (2, 0.8)  이렇게 된다. 

이걸로 유사한 문장과 유사도 점수를 보여줄 수 있다.

 

결과

더보기

1.

 

참고로, 이전 cosine similarity를 이용했던 결과와 비교해보면 faiss가 더 우수함을 알 수 있다.

 

2.

 

비교 (cosine_similarity)

이렇게 잘 안나오는 이유는 아마 텍스트 전처리가 안되었기 때문이 아닐까? 불용어라든지 어간추출이라든지

 

3.

결과는 비슷하지만 점 하나 차이로 유사도 점수가 크게 달라진 것을 볼 수 있다. 이런 문장부호도 텍스트 전처리로 잘 처리해주면 더 좋겠다.

 

 

what's next

더보기

모듈화된 텍스트 전처리 함수 + sentence transformer보다 더 좋은 모델로 다시 해보기

or

object detection model

 

더보기

사담

명량 한산 노량 다 봤는데 나는 한산이 제일 재밌었다.

이순신 장군은 무관이기는 하지만 선비의 면모도 있을것이라 생각했는데 내 머릿속에 있던 이미지와 딱 맞는 배우의 연기여서 그랬던 것 같다.