tdk-chatbot / src /embeddings.py
esrakoc's picture
Upload 15 files
3d99898
"""
Embedding modeli yönetimi.
Bu modül metinleri sayısal vektörlere dönüştürmek için
sentence-transformers kütüphanesini kullanır.
"""
from sentence_transformers import SentenceTransformer
import numpy as np
from tqdm import tqdm
import pickle
import os
class EmbeddingModel:
"""Türkçe metinler için embedding modeli."""
def __init__(self, model_name="emrecan/bert-base-turkish-cased-mean-nli-stsb-tr"):
"""
Args:
model_name: Kullanılacak embedding modeli.
Türkçe için özel eğitilmiş model kullanıyoruz.
"""
print(f"🤖 Embedding modeli yükleniyor: {model_name}")
try:
self.model = SentenceTransformer(model_name)
self.model_name = model_name
print("Model başarıyla yüklendi!")
# Model bilgilerini göster
embedding_dim = self.model.get_sentence_embedding_dimension()
print(f"Embedding boyutu: {embedding_dim}")
except Exception as e:
print(f"Model yüklenirken hata: {e}")
raise
def encode_single(self, text):
"""
Tek bir metni embedding'e çevirir.
Args:
text: Çevrilecek metin
Returns:
numpy array: Embedding vektörü
"""
if not text or not isinstance(text, str):
return None
try:
embedding = self.model.encode(text, convert_to_numpy=True)
return embedding
except Exception as e:
print(f"Encoding hatası: {e}")
return None
def encode_batch(self, texts, batch_size=32, show_progress=True):
"""
Birden fazla metni toplu olarak embedding'e çevirir.
Args:
texts: Metin listesi
batch_size: Aynı anda işlenecek metin sayısı
show_progress: İlerleme çubuğu göster
Returns:
numpy array: Embedding matrisi (n_texts, embedding_dim)
"""
if not texts:
return np.array([])
print(f"{len(texts)} metin embedding'e çevriliyor...")
try:
embeddings = self.model.encode(
texts,
batch_size=batch_size,
show_progress_bar=show_progress,
convert_to_numpy=True
)
print(f"Embedding tamamlandı! Shape: {embeddings.shape}")
return embeddings
except Exception as e:
print(f"Batch encoding hatası: {e}")
return None
def encode_documents(self, documents, text_key='text'):
"""
Doküman listesini embedding'e çevirir.
Args:
documents: Doküman listesi (dict formatında)
text_key: Metin alanının key'i
Returns:
tuple: (embeddings, valid_documents)
"""
if not documents:
return None, []
# Metinleri çıkar
texts = []
valid_docs = []
for doc in documents:
text = doc.get(text_key, '')
if text and isinstance(text, str):
texts.append(text)
valid_docs.append(doc)
print(f"{len(valid_docs)} geçerli doküman bulundu")
# Embedding'leri oluştur
embeddings = self.encode_batch(texts)
return embeddings, valid_docs
def save_embeddings(self, embeddings, documents, filepath):
"""
Embedding'leri ve dokümanları kaydeder.
Args:
embeddings: Embedding matrisi
documents: Doküman listesi
filepath: Kayıt yolu
"""
data = {
'embeddings': embeddings,
'documents': documents,
'model_name': self.model_name
}
# Klasör yoksa oluştur
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'wb') as f:
pickle.dump(data, f)
print(f"Embedding'ler kaydedildi: {filepath}")
@staticmethod
def load_embeddings(filepath):
"""
Kaydedilmiş embedding'leri yükler.
Args:
filepath: Dosya yolu
Returns:
dict: {'embeddings', 'documents', 'model_name'}
"""
if not os.path.exists(filepath):
print(f"Dosya bulunamadı: {filepath}")
return None
with open(filepath, 'rb') as f:
data = pickle.load(f)
print(f"Embedding'ler yüklendi: {filepath}")
print(f"Embedding shape: {data['embeddings'].shape}")
print(f"Model: {data['model_name']}")
return data
def test_similarity(self, text1, text2):
"""
İki metin arasındaki benzerliği test eder.
Args:
text1, text2: Karşılaştırılacak metinler
Returns:
float: Benzerlik skoru (0-1 arası)
"""
emb1 = self.encode_single(text1)
emb2 = self.encode_single(text2)
if emb1 is None or emb2 is None:
return None
# Cosine benzerliği hesapla
similarity = np.dot(emb1, emb2) / (np.linalg.norm(emb1) * np.linalg.norm(emb2))
print(f"\nBenzerlik Testi:")
print(f"Metin 1: {text1}")
print(f"Metin 2: {text2}")
print(f"Benzerlik: {similarity:.4f}")
return float(similarity)
# Test için main fonksiyonu
if __name__ == "__main__":
# Embedding modelini oluştur
embedder = EmbeddingModel()
# Basit test
print("\n" + "=" * 60)
print("BENZERLİK TESTİ")
print("=" * 60)
# Test metinleri
embedder.test_similarity(
"Kitap okumayı seviyorum",
"Okumak benim hobimdir"
)
embedder.test_similarity(
"Kitap okumayı seviyorum",
"Futbol oynamak eğlencelidir"
)
print("\n✨ Test tamamlandı!")