rag.py ์ฝ๋ ๋น๊ต ๋ฆฌ๋ทฐ ๐
์ด๋ฒ ํํ์ ์งํํ๋ฉด์ RAG๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด rag.py ๋ชจ๋์ ๋ง๋ค์ด์ ์ฝ๋๋ฅผ ์ง๋ณด์๋๋ฐ,
์ฒซ๋ฒ์งธ ์ฝ๋๋ก ์ฅ๊ณ ์๋ฒ ๋๋ ธ์ ๋ ์ถ๋ ฅ๋ ๊ฒฐ๊ณผ์ ๋๋ฒ์งธ ์ฝ๋๋ก ์ถ๋ ฅ๋ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์
<๋ ์ฝ๋์๋ ์ด๋ค ์ฐจ์ด๊ฐ ์๋๊ฐ> ์ ๋ํ ๋ฆฌ๋ทฐ๋ฅผ ํด๋ณด์ํจ~
# ์ฒซ๋ฒ์งธ ์ฝ๋
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from .models import CrawledData
def search_similar_documents(query_embedding):
embeddings = [data.embedding for data in CrawledData.objects.all()]
embeddings = np.array(embeddings)
# ์ฝ์ฌ์ธ ์ ์ฌ๋๋ฅผ ๊ณ์ฐํ์ฌ ์ ์ฌํ ๋ฌธ์ ์ฐพ๊ธฐ
similarities = cosine_similarity(query_embedding, embeddings)
most_similar_idx = np.argmax(similarities)
return CrawledData.objects.all()[most_similar_idx] # ๊ฐ์ฅ ์ ์ฌํ ๋ฌธ์ ๋ฐํ
# ๋๋ฒ์งธ ์ฝ๋
from sklearn.metrics.pairwise import cosine_similarity
from .models import CrawledData
import numpy as np
def search_similar_documents(query_embedding):
# CrawledData์์ embedding์ด ์๋ ๋ฌธ์๋ง ๊ฐ์ ธ์ค๊ธฐ
all_docs = CrawledData.objects.filter(embedding__isnull=False)
if not all_docs.exists():
return None # ๋ฌธ์๊ฐ ์์ผ๋ฉด None ๋ฐํ
embeddings = []
for doc in all_docs:
embedding = np.array(doc.embedding, dtype=np.float32)
# NaN ๋๋ Inf ๊ฐ์ด ์์ ๊ฒฝ์ฐ, ํด๋น ๋ฒกํฐ๋ฅผ zero vector๋ก ๋ณ๊ฒฝ
if np.isnan(embedding).any() or np.isinf(embedding).any():
print(f"Warning: Invalid embedding for document ID {doc.id}, replacing with zero vector.")
embedding = np.zeros(768, dtype=np.float32)
if embedding.ndim == 1:
embedding = embedding.reshape(1, -1) # 1์ฐจ์ ๋ฐฐ์ด์ 2์ฐจ์ ๋ฐฐ์ด๋ก ๋ณํ
embeddings.append(embedding)
if not embeddings:
return None # ์๋ฒ ๋ฉ์ด ์์ผ๋ฉด None ๋ฐํ
# ์๋ฒ ๋ฉ ๋ฐฐ์ด์ ํฉ์ณ์ ํ๋์ matrix๋ก ๋ง๋ฌ
embeddings_matrix = np.vstack([emb[0] for emb in embeddings if emb.shape[0] > 0])
# query_embedding์ด 2์ฐจ์ ๋ฐฐ์ด์ธ์ง ํ์ธํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด reshape
if query_embedding.ndim == 1:
query_embedding = query_embedding.reshape(1, -1)
if query_embedding.shape[1] != embeddings_matrix.shape[1]:
print("Error: query_embedding and embeddings_matrix dimensions do not match.")
return None
# cosine similarity ๊ณ์ฐ
similarities = cosine_similarity(query_embedding, embeddings_matrix)
# ๊ฐ์ฅ ์ ์ฌํ ๋ฌธ์์ ์ธ๋ฑ์ค ์ฐพ๊ธฐ
most_similar_idx = np.argmax(similarities.flatten())
most_similar_idx = int(most_similar_idx)
# ์ ์ฌ๋๊ฐ ๋ฎ์ผ๋ฉด None์ ๋ฐํํ๋๋ก ์ค์
if similarities.flatten()[most_similar_idx] < 0.7: # 0.7์ ์๊ณ๊ฐ์ผ๋ก ์ค์
print("No sufficiently similar documents found.")
return None
# ๊ฐ์ฅ ์ ์ฌํ ๋ฌธ์๋ฅผ ๋ฐํ
return all_docs[most_similar_idx]
1. ์ฃผ์ ์ฐจ์ด์
1) `CrawledData` ๊ฐ์ ธ์ค๋ ๋ฐฉ์
- ์ฒซ ๋ฒ์งธ ์ฝ๋: `CrawledData.objects.all()`์ ์ฌ์ฉํ์ฌ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
- ๋ ๋ฒ์งธ ์ฝ๋: `CrawledData.objects.filter(embedding__isnull=False)`๋ฅผ ์ฌ์ฉํ์ฌ `embedding` ๊ฐ์ด ์๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ธํจ
๐น ์ฅ์ : ๋ ๋ฒ์งธ ์ฝ๋๊ฐ ๋ ์์ ํจ, `embedding` ๊ฐ์ด `None`์ธ ๊ฒฝ์ฐ๋ฅผ ํํฐ๋งํ์ฌ ๋ถํ์ํ ์๋ฌ๋ฅผ ๋ฐฉ์ง
2) ์๋ฒ ๋ฉ ๋ฐ์ดํฐ ์ ๋ฆฌ ๊ณผ์
- ์ฒซ ๋ฒ์งธ ์ฝ๋: ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ `np.array`๋ก ๋ณํํ์ฌ ๋ฐ๋ก ์ฝ์ฌ์ธ ์ ์ฌ๋๋ฅผ ๊ณ์ฐํจ
- ๋ ๋ฒ์งธ ์ฝ๋:
- `embedding`์ด `None`, `NaN`, `Inf` ๊ฐ์ธ์ง ๊ฒ์ฌํ์ฌ ์์ ์ฑ ํ๋ณด
- `embedding`์ด 1์ฐจ์์ธ์ง ํ์ธ ํ, 2์ฐจ์์ผ๋ก ๋ณํ
- `np.vstack()`์ ์ฌ์ฉํ์ฌ ์๋ฒ ๋ฉ ํ๋ ฌ์ ์์ฑํจ
๐น ์ฅ์ : ๋ ๋ฒ์งธ ์ฝ๋๊ฐ ๋ ์์ ํจ, `NaN`์ด๋ `Inf` ๊ฐ์ด ํฌํจ๋ ๋ฒกํฐ๋ฅผ 0 ๋ฒกํฐ๋ก ๋์ฒดํ์ฌ ์๋ฌ๋ฅผ ๋ฐฉ์ง
3) Query Embedding ์ฒ๋ฆฌ
- ์ฒซ ๋ฒ์งธ ์ฝ๋: `query_embedding`์ด 1์ฐจ์์ธ์ง ๊ฒ์ฌ ์์ด ๊ทธ๋๋ก ์ฌ์ฉํจ
- ๋ ๋ฒ์งธ ์ฝ๋:
- `query_embedding`์ด 1์ฐจ์์ธ์ง ํ์ธํ๊ณ , 2์ฐจ์์ผ๋ก ๋ณํ
- `query_embedding.shape[1]`๊ณผ `embeddings_matrix.shape[1]` ๋น๊ตํ์ฌ ์ฐจ์์ด ๋ค๋ฅด๋ฉด ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ `None` ๋ฐํ
๐น ์ฅ์ : ๋ ๋ฒ์งธ ์ฝ๋๊ฐ ๋ ์์ ํจ, Query ๋ฒกํฐ์ ์๋ฒ ๋ฉ ํ๋ ฌ์ ์ฐจ์์ด ๋ค๋ฅด๋ฉด ์ค๋ฅ ๋ฐ์์ ๋ฐฉ์ง
4) ์ ์ฌ๋ ์๊ณ๊ฐ ์ค์
- ์ฒซ ๋ฒ์งธ ์ฝ๋: ๊ฐ์ฅ ์ ์ฌํ ๋ฌธ์๋ฅผ ์ฐพ๊ณ ๋ฐ๋ก ๋ฐํํจ
- ๋ ๋ฒ์งธ ์ฝ๋:
- `similarities.flatten()[most_similar_idx]` ๊ฐ์ด 0.7 ๋ฏธ๋ง์ด๋ฉด `None` ๋ฐํ
- ์ถฉ๋ถํ ์ ์ฌํ์ง ์์ผ๋ฉด ๋ฌธ์๋ฅผ ๋ฐํํ์ง ์์
๐น ์ฅ์ : ๋ ๋ฒ์งธ ์ฝ๋๊ฐ ๋ ์ ํํจ, ๋๋ฌด ๋ฎ์ ์ ์ฌ๋๋ฅผ ๊ฐ์ง ๋ฌธ์๋ฅผ ๋ฌด์กฐ๊ฑด ๋ฐํํ์ง ์๋๋ก ์กฐ์ ํจ
2. ์๋ชป๋ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ ๊ฐ๋ฅ์ฑ์ด ๋์ ์ฝ๋
๐จ ์ฒซ ๋ฒ์งธ ์ฝ๋ (์๋ชป๋ ๊ฒฐ๊ณผ ๊ฐ๋ฅ์ฑ)
- `embedding` ๊ฐ์ด `None`, `NaN`, `Inf`์ธ ๊ฒฝ์ฐ ์๋ฌ ๋ฐ์ ๊ฐ๋ฅ
- `query_embedding`๊ณผ ๋ฐ์ดํฐ์ `embedding` ์ฐจ์์ด ๋ค๋ฅด๋ฉด ์๋ฌ ๋ฐ์ ๊ฐ๋ฅ
- ์๋ฒ ๋ฉ์ ์์งํ ๋ `reshape`์ ๊ณ ๋ คํ์ง ์์ ์ฐจ์ ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ
- ์ ์ฌ๋๊ฐ ๋ฎ์๋ ๊ฐ์ฅ ์ ์ฌํ ๋ฌธ์๋ฅผ ๋ฌด์กฐ๊ฑด ๋ฐํํ์ฌ ๋ถ์ ํํ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํจ
โ ๋ ๋ฒ์งธ ์ฝ๋ (๋ ์์ ํ ์ฝ๋)
- `None`, `NaN`, `Inf`๋ฅผ ๊ฐ์งํ์ฌ ์ฒ๋ฆฌํจ
- `query_embedding`์ ์ฐจ์์ ์๋์ผ๋ก ์กฐ์
- ์ ์ฌ๋๊ฐ ๋๋ฌด ๋ฎ์ผ๋ฉด `None`์ ๋ฐํํ์ฌ ๋ถ์ ํํ ์ถ์ฒ์ ๋ฐฉ์ง
์ฝ๋ ๋ฆฌ๋ทฐ ์ ๋ฆฌ:
1. ๋ ๋ฒ์งธ ์ฝ๋๊ฐ ๋ ์์ ํ๊ณ ์ ํํ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ ๊ฐ๋ฅ์ฑ์ด ๋๋ค~
2. ์ฒซ ๋ฒ์งธ ์ฝ๋๋ ์๋ฒ ๋ฉ ๊ฐ์ด ์๋ชป๋ ๊ฒฝ์ฐ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฑฐ๋, ๋ถ์ ํํ ๋ฌธ์๋ฅผ ๋ฐํํ ๊ฐ๋ฅ์ฑ์ด ํฌ๋ค~
'Today I Learned ๐' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[250228] SA ๋ฌธ์ ์์ฑ์ ์ค์์ฑ (0) | 2025.02.28 |
---|---|
[250111] Today I Learned (0) | 2025.01.12 |