nyzmemre/turkce-tibbi-rag-vektor-db
Türkçe Tıbbi Makaleler — Vektör Arama Veri Tabanı Türkçe hastane sağlık rehberi makalelerinden oluşturulmuş, benzerlik eşiğiyle filtrelenen bir vektör arama sistemi. Cevabı dokümanlarda bulunmayan sorularda sistem içerik döndürmez. Kaynak veri: umutertugrul/turkish-hospital-medical-articles (erişim onayı gerektirir), atlas bölümü — 130 makale. Veri tablosu chunks.parquet dosyası şu kolonları içerir: Kolon Tip Açıklama url string Parçanın alındığı… See the full description on the dataset page: https://huggingface.co/datasets/nyzmemre/turkce-tibbi-rag-vektor-db.
Türkçe Tıbbi Makaleler — Vektör Arama Veri Tabanı
Türkçe hastane sağlık rehberi makalelerinden oluşturulmuş, benzerlik eşiğiyle filtrelenen bir vektör arama sistemi. Cevabı dokümanlarda bulunmayan sorularda sistem içerik döndürmez.
Kaynak veri: umutertugrul/turkish-hospital-medical-articles (erişim onayı gerektirir), atlas bölümü — 130 makale.
Veri tablosu
chunks.parquet dosyası şu kolonları içerir:
Toplam 1.010 parça, 130 makaleden üretildi (makale başına ortalama 7,8 parça).
Chunking stratejisi
Veriyi incelemeden bir yöntem seçmek yerine önce metinlerin yapısına bakıldı ve iki gözlem belirleyici oldu:
Birincisi, makalelerde \n\n ayracı hiç bulunmuyor. Satırlar tek \n ile ayrılmış ve bu satırlar hem gerçek paragrafları hem de - Ameliyat Kararı Ne Zaman Verilir? gibi kısa ara başlıkları içeriyor. Bu nedenle klasik paragraf bölme bu veride doğrudan uygulanamıyor.
İkincisi, 130 makalenin 98'i İçindekiler satırı ve ardından gelen bağlantı listesiyle başlıyor. Bu blok yalnızca başlıklardan oluştuğu için parçalandığında içerik taşımayan bir vektör üretiyor ve aramada gürültü yaratıyordu; temizlik adımında kaldırıldı.
Seçilen yöntem karma (mixed) parçalama:
- Metin önce doğal sınırlarından birimlere ayrılır — önce satır, hedef uzunluğu aşan satırlar ayrıca cümle sonlarından.
- Birimler, hedef uzunluğa ulaşana kadar birleştirilir.
- Komşu parçalar arasında örtüşme bırakılır: önceki parçanın son cümleleri yeni parçanın başına taşınır.
- Tek başına anlam taşımayacak kadar kısa artıklar bir öncekine eklenir.
Parametreler: hedef 800 karakter, örtüşme 150 karakter, en kısa parça 120 karakter. Sonuçta parça uzunlukları 127–1197 karakter aralığında, medyan 668 karakter.
Neden bu yöntem: sabit token bölme cümleyi ortasından keser ve tanımlar yarım kalır. Saf satır bölme ise 30–40 karakterlik başlık parçaları üretir; bunlar tek başına vektörleştirildiğinde aramada anlamsız eşleşmelere yol açar. Karma yöntem, parçaların hem anlamlı bir bütünlük taşımasını hem de birbirine yakın boyutta olmasını sağlıyor. Örtüşme ise bir tanımın parça sınırında ikiye bölünüp her iki parçada da eksik kalması riskini azaltıyor.
Embedding modeli
Kullanılan model: `magibu/embeddingmagibu-200m`, vektör boyutu 768.
Değerlendirilen alternatifler ve seçim gerekçesi:
Seçimde üç ölçüt etkili oldu. Model Türkçe odaklı; bu çalışmadaki sorular günlük hasta diliyle yazıldığı için dilin kendi kalıplarını tanıması gerekiyordu. Bağlam penceresi 8192 token, yani 800 karakterlik parçalar hiçbir koşulda kırpılmıyor — daha dar pencereli bir modelde uzun parçaların sonu sessizce atılabilirdi. Son olarak 430 MB ile listedeki en hafif seçenek; embedding üretimi Apple M2 üzerinde MPS ile 1.010 parça için 121 saniye sürdü, ayrı bir GPU gerekmedi.
Vektörler birim uzunluğa normalize ediliyor. Böylece nokta çarpımı doğrudan kosinüs benzerliğine eşit oluyor ve veritabanının mesafe hesabıyla raporlanan skorlar birbiriyle tutarlı kalıyor.
Aynı model hem parçaları hem soruları vektörleştiriyor. Farklı modeller farklı vektör uzaylarına yazdığı için karışık kullanım skorları anlamsız hale getirirdi.
Vektör veritabanı
ChromaDB, kosinüs uzaklığı ile yapılandırıldı. Tek bir dizinde çalışan gömülü bir veritabanı olduğu için ek altyapı gerektirmiyor. PGVector alternatifi ayrıca bir PostgreSQL sunucusu kurmayı ve yönetmeyi gerektirirdi; bu ölçekte (1.010 parça) böyle bir yükün karşılığı yok.
Test kümesi
30 soru: 20 pozitif, 10 negatif (`test_sorulari.json`).
Sorular bilinçli olarak günlük hasta diliyle yazıldı. "Topuk dikeni nedir?" biçiminde bir soru, "Topuk Dikeni Nedir? Belirtileri ve Tedavisi" başlıklı makaleyle birebir kelime örtüşmesi kurar; bu, aramanın değil kelime tekrarının başarısıdır. Bunun yerine "Sabah yataktan kalkıp ilk adımı attığımda topuğumun altında keskin bir ağrı hissediyorum" gibi, makalenin anahtar kelimesini hiç içermeyen sorular tercih edildi.
Negatif soruların seçimi tahminle yapılmadı. İlk aday listesindeki bazı sorular ölçüldüğünde elendi:
Buradaki ders, kelime taramasının yeterli olmadığı: bir terim veride hiç geçmiyor olabilir, ama anlamsal komşusu bulunuyorsa vektör araması onu yine de yakalar. Negatif sorular ancak ölçülerek doğrulanabildi.
Eşik analizi
Eşik değeri tahminle değil, test kümesinin skor dağılımı taranarak seçildi.
Skor dağılımı
pozitif (20 soru) : min 0,398 medyan 0,635 maks 0,842
negatif (10 soru) : min 0,359 medyan 0,428 maks 0,471Eşik taraması
Seçilen eşik: 0,48
F1 skoru en yüksek değer 0,47 (0,950). Buna rağmen 0,48 tercih edildi, çünkü 0,47'de bir negatif soru sızıyor: "Hapşurduğumda gıdıklanıyorum. neden olur" (0,471). Tıbbi içerikte cevabı olmayan bir soruya alakasız bir makale döndürmek, cevabı olan bir soruyu kaçırmaktan daha ağır bir hata. Bu nedenle kesinliğin 1,000 olduğu ilk değer seçildi.
0,48 eşiğinde kaçırılan iki pozitif sorunun hangileri olduğu ayrıca incelendi:
0,398 "Diyet yapıyorum. Diyette nelere dikkat etmem lazım"
0,476 "Vücudumdaki şişlikler zararsız. ama estetik açıdan kötü görünüyor..."Her ikisi de test kümesinde beklenen_makale alanı boş bırakılan sorular. Birincisi tek bir makaleye oturmayacak kadar genel, ikincisinin konusu (iyi huylu deri altı şişlikleri) bu 130 makalede işlenmiyor. Yani sistem bu sorularda hata yapmıyor; karşılığı olmayan içeriği zorlamak yerine doğru biçimde eliyor.
Eşiğin üzerinde kalan 0,50–0,60 bandı da denendi. Kesinlik değişmiyor, ancak duyarlılık 0,850'den 0,550'ye düşüyor: cevabı veride bulunan sorular da elenmeye başlıyor. 0,48 bu iki hata türü arasındaki en dengeli nokta.
Getirme doğruluğu
Filtrelemeden ayrı olarak, eşiği geçen soruların doğru makaleyi getirip getirmediği de ölçüldü. beklenen_makale tanımlı 15 sorunun 15'inde beklenen makale ilk üç sonuç içinde yer aldı.
Bu iki ölçümü ayırmak gerekiyor: yüksek benzerlik skoru tek başına doğru cevap anlamına gelmez. Test hazırlığı sırasında 0,585 skorla eşiği geçen bir soru, konusuyla ilgisi olmayan bir makaleyi getirmişti. Yalnızca skora bakılsaydı sistem olduğundan iyi görünecekti.
Kullanım
pip install -r requirements.txt
python hazirla.py # makale -> parça -> vektör -> ChromaDB + parquet
python degerlendir.py # 30 soruluk test, eşik taraması
python ara.py "Sabah ilk adımda topuğum ağrıyor, sebebi ne olabilir?"Eşiğin altında kalan sorularda çıktı:
Bu sorunun cevabı dokümanlarımda yer almamaktadır.