Spaces:
Sleeping
Sleeping
File size: 5,869 Bytes
3d99898 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
"""
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ı!") |