Veni AI
Arama Teknolojileri

Semantic Search ve Embedding Modelleri Karşılaştırması

Semantic search sistemleri, popüler embedding modellerinin karşılaştırması, benchmark sonuçları ve kurumsal arama çözümleri için rehber.

Veni AI Teknik Ekibi2 Ocak 20255 dk okuma

Reference Overview

FieldValueSource
Canonical Path/blog/semantic-search-embedding-modelleri-karsilastirmaVeni AI Blog
Primary CategoryArama TeknolojileriPost Metadata
AuthorVeni AI Teknik EkibiPost Metadata
Semantic Search ve Embedding Modelleri Karşılaştırması

Semantic Search ve Embedding Modelleri Karşılaştırması

Semantic search, kelime eşleşmesi yerine anlam benzerliği ile arama yapan sistemlerdir. Bu rehberde embedding modellerini ve semantic search implementasyonlarını inceliyoruz.

Keyword vs Semantic Search

1Keyword Search: 2Query: "ucuz telefon" 3Sonuç: Sadece "ucuz" ve "telefon" kelimelerini içeren belgeler 4 5Semantic Search: 6Query: "ucuz telefon" 7Sonuç: "bütçe dostu akıllı cihaz", "ekonomik smartphone", 8 "fiyatı uygun mobil" gibi anlamsal benzer belgeler

Embedding Modelleri Karşılaştırması

Popüler Modeller

ModelBoyutMax TokensTürkçeMTEB Score
text-embedding-3-large30728191İyi64.6
text-embedding-3-small15368191İyi62.3
Cohere embed-v31024512Orta64.5
BGE-M310248192Çok İyi63.2
E5-mistral-7b409632768İyi66.6
mxbai-embed-large1024512İyi64.7

OpenAI Embedding

1from openai import OpenAI 2 3client = OpenAI() 4 5def get_embedding(text: str, model: str = "text-embedding-3-large"): 6 response = client.embeddings.create( 7 input=text, 8 model=model, 9 dimensions=1024 # Boyut azaltma (opsiyonel) 10 ) 11 return response.data[0].embedding 12 13# Batch embedding 14def get_embeddings_batch(texts: list[str]): 15 response = client.embeddings.create( 16 input=texts, 17 model="text-embedding-3-large" 18 ) 19 return [item.embedding for item in response.data]

Cohere Embedding

1import cohere 2 3co = cohere.Client("api-key") 4 5def get_cohere_embedding(texts: list[str], input_type: str = "search_document"): 6 response = co.embed( 7 texts=texts, 8 model="embed-multilingual-v3.0", 9 input_type=input_type # search_document veya search_query 10 ) 11 return response.embeddings

Sentence Transformers (Local)

1from sentence_transformers import SentenceTransformer 2 3model = SentenceTransformer("BAAI/bge-m3") 4 5# Tek metin 6embedding = model.encode("Merhaba dünya") 7 8# Batch 9embeddings = model.encode([ 10 "Birinci metin", 11 "İkinci metin", 12 "Üçüncü metin" 13], batch_size=32, show_progress_bar=True)

Semantic Search Implementasyonu

Basit Cosine Similarity

1import numpy as np 2 3def cosine_similarity(a, b): 4 return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) 5 6def search(query: str, documents: list[dict], top_k: int = 5): 7 query_embedding = get_embedding(query) 8 9 results = [] 10 for doc in documents: 11 similarity = cosine_similarity(query_embedding, doc["embedding"]) 12 results.append({ 13 "document": doc, 14 "score": similarity 15 }) 16 17 results.sort(key=lambda x: x["score"], reverse=True) 18 return results[:top_k]

Vector Database ile Search

1from pinecone import Pinecone 2 3pc = Pinecone(api_key="xxx") 4index = pc.Index("semantic-search") 5 6def semantic_search(query: str, top_k: int = 10, filter: dict = None): 7 query_embedding = get_embedding(query) 8 9 results = index.query( 10 vector=query_embedding, 11 top_k=top_k, 12 filter=filter, 13 include_metadata=True 14 ) 15 16 return [ 17 { 18 "id": match.id, 19 "score": match.score, 20 "metadata": match.metadata 21 } 22 for match in results.matches 23 ]

Hybrid Search

Keyword + Semantic search kombinasyonu:

1from rank_bm25 import BM25Okapi 2 3class HybridSearch: 4 def __init__(self, documents): 5 self.documents = documents 6 7 # BM25 index 8 tokenized = [doc["text"].split() for doc in documents] 9 self.bm25 = BM25Okapi(tokenized) 10 11 # Embeddings 12 texts = [doc["text"] for doc in documents] 13 self.embeddings = get_embeddings_batch(texts) 14 15 def search(self, query: str, top_k: int = 10, alpha: float = 0.5): 16 # BM25 scores 17 bm25_scores = self.bm25.get_scores(query.split()) 18 bm25_scores = (bm25_scores - bm25_scores.min()) / (bm25_scores.max() - bm25_scores.min() + 1e-6) 19 20 # Semantic scores 21 query_emb = get_embedding(query) 22 semantic_scores = [ 23 cosine_similarity(query_emb, emb) 24 for emb in self.embeddings 25 ] 26 semantic_scores = np.array(semantic_scores) 27 28 # Hybrid score 29 hybrid_scores = alpha * semantic_scores + (1 - alpha) * bm25_scores 30 31 # Sort and return 32 top_indices = np.argsort(hybrid_scores)[::-1][:top_k] 33 34 return [ 35 { 36 "document": self.documents[i], 37 "score": hybrid_scores[i], 38 "bm25_score": bm25_scores[i], 39 "semantic_score": semantic_scores[i] 40 } 41 for i in top_indices 42 ]

Reranking

İlk sonuçları daha doğru sıralama:

1import cohere 2 3co = cohere.Client("api-key") 4 5def rerank_results(query: str, documents: list[str], top_k: int = 10): 6 response = co.rerank( 7 query=query, 8 documents=documents, 9 model="rerank-multilingual-v3.0", 10 top_n=top_k 11 ) 12 13 return [ 14 { 15 "index": result.index, 16 "text": documents[result.index], 17 "score": result.relevance_score 18 } 19 for result in response.results 20 ] 21 22# Pipeline: Retrieve → Rerank 23def search_with_rerank(query: str, top_k: int = 5): 24 # Step 1: Get more candidates 25 candidates = semantic_search(query, top_k=top_k * 3) 26 27 # Step 2: Rerank 28 docs = [c["metadata"]["text"] for c in candidates] 29 reranked = rerank_results(query, docs, top_k=top_k) 30 31 return reranked

Query Understanding

Query Expansion

1def expand_query(query: str) -> list[str]: 2 """LLM ile sorgu genişletme""" 3 response = client.chat.completions.create( 4 model="gpt-4-turbo", 5 messages=[ 6 { 7 "role": "system", 8 "content": "Verilen arama sorgusunun 3 farklı varyasyonunu oluştur." 9 }, 10 {"role": "user", "content": query} 11 ] 12 ) 13 14 variations = response.choices[0].message.content.split("\n") 15 return [query] + variations

HyDE (Hypothetical Document Embeddings)

1def hyde_search(query: str, top_k: int = 5): 2 """Hipotetik belge oluşturup embedding al""" 3 4 # Generate hypothetical document 5 response = client.chat.completions.create( 6 model="gpt-4-turbo", 7 messages=[ 8 { 9 "role": "system", 10 "content": "Bu soruya cevap veren bir paragraf yaz." 11 }, 12 {"role": "user", "content": query} 13 ] 14 ) 15 16 hypothetical_doc = response.choices[0].message.content 17 18 # Embed the hypothetical document 19 hyde_embedding = get_embedding(hypothetical_doc) 20 21 # Search with this embedding 22 return vector_search(hyde_embedding, top_k)

Evaluation Metrics

Retrieval Metrics

1def calculate_metrics(retrieved: list, relevant: list, k: int): 2 """Precision@K, Recall@K, MRR hesapla""" 3 4 # Precision@K 5 retrieved_k = retrieved[:k] 6 relevant_in_k = len(set(retrieved_k) & set(relevant)) 7 precision_k = relevant_in_k / k 8 9 # Recall@K 10 recall_k = relevant_in_k / len(relevant) 11 12 # MRR 13 mrr = 0 14 for i, doc in enumerate(retrieved): 15 if doc in relevant: 16 mrr = 1 / (i + 1) 17 break 18 19 return { 20 "precision@k": precision_k, 21 "recall@k": recall_k, 22 "mrr": mrr 23 }

NDCG (Normalized Discounted Cumulative Gain)

1import numpy as np 2 3def dcg(relevances, k): 4 relevances = np.array(relevances)[:k] 5 return np.sum(relevances / np.log2(np.arange(2, len(relevances) + 2))) 6 7def ndcg(retrieved_relevances, ideal_relevances, k): 8 actual_dcg = dcg(retrieved_relevances, k) 9 ideal_dcg = dcg(sorted(ideal_relevances, reverse=True), k) 10 return actual_dcg / ideal_dcg if ideal_dcg > 0 else 0

Production Optimizasyonları

Embedding Cache

1import hashlib 2import redis 3 4redis_client = redis.Redis() 5 6def get_embedding_cached(text: str, model: str = "text-embedding-3-large"): 7 cache_key = f"emb:{model}:{hashlib.md5(text.encode()).hexdigest()}" 8 9 cached = redis_client.get(cache_key) 10 if cached: 11 return json.loads(cached) 12 13 embedding = get_embedding(text, model) 14 redis_client.setex(cache_key, 86400, json.dumps(embedding)) # 24h TTL 15 16 return embedding

Batch Processing

1async def process_documents_async(documents: list[dict], batch_size: int = 100): 2 """Async batch embedding""" 3 4 async def process_batch(batch): 5 texts = [doc["text"] for doc in batch] 6 embeddings = await async_get_embeddings(texts) 7 8 for doc, emb in zip(batch, embeddings): 9 doc["embedding"] = emb 10 11 return batch 12 13 tasks = [] 14 for i in range(0, len(documents), batch_size): 15 batch = documents[i:i + batch_size] 16 tasks.append(process_batch(batch)) 17 18 results = await asyncio.gather(*tasks) 19 return [doc for batch in results for doc in batch]

Sonuç

Semantic search, kullanıcı deneyimini önemli ölçüde iyileştiren güçlü bir teknolojidir. Doğru embedding modeli seçimi, hybrid search ve reranking ile yüksek kaliteli arama sistemleri oluşturabilirsiniz.

Veni AI olarak, kurumsal semantic search çözümleri geliştiriyoruz.

İlgili Makaleler