---
title: 'Gömme Vektörleri ve Erişim Artırılmış Üretim'
source: 'https://academia.sh/tr/kurslar/rag'
language: tr
updated: '2026-08-17T04:38:27+00:00'
license: 'CC BY-SA 4.0'
lessons: 16
outcomes:
    - 'Gömme temelli benzerlik aramasını kurar ve getirilen parçanın doğruluğunu tam tarama tabanına karşı ölçer'
    - 'Belge hazırlama, parçalama, dizinleme ve yeniden sıralama kararlarının her birinin anma ile belirteç bedelini yazar'
    - 'Erişim kalitesini üretim kalitesinden ayrı ölçer ve tek bir sayının hangi durumları gizlediğini gösterir'
---

# Gömme Vektörleri ve Erişim Artırılmış Üretim

Modele verilen bilginin elle değil ölçülerek seçilmesi ve erişim ile üretimin ayrı ayrı sayılması: anahtar sözcük eşleşmesi ile gömme benzerliğinin aynı sorgu kümesinde getirdiği parça, alan dışı gömmenin aynı boyutta kaybettirdiği, açı benzerliği ile iç çarpımın ilk üç sonucu ayırdığı sorgu sayısı ve uzunluk yanlılığı, tam tarama tabanına karşı dizinli aramanın anması ile karşılaştırma sayısı, süzgeç seçiciliği arttıkça bozulan komşuluk, anahtar sözcük ile gömmenin birleştirilmesinin ikisinden de kötü kaldığı sorgu sınıfı, erişimsiz taban ile yanlış parçalı koşumun tabanın altına düşmesi, belge hazırlığının erişim anmasına kattığı ve attığı bilgi, parça boyutu ile örtüşmenin anma ve belirteci ters yönde oynatması, yenileme aralığı uzadıkça büyüyen bayatlık payı, sorgu dönüştürmenin kısa sorguda kazandırıp uzun sorguda kaybettirdiği, yeniden sıralamanın ilk k kesinliğine kattığı ve eklediği adım, bağlam sınırına sığan parça sayısı ile sıranın değiştirdiği yanıt payı, doğru parça ile doğru yanıtın dört durumlu tablosu, üç görevde erişim ile ince ayarın kattığı ve erişimin kazanmadığı görev, tablo taşıyan kaynağın satır bazlı ve blok bazlı parçalanmasının anmaya yaptığı.

## Gömmeler ve Vektör Arama

Bir sorgunun dağarcıktaki hangi parçayı getirdiğinin ve arama düzeneğinin her katmanının neyi kazandırıp neyi kaybettirdiğinin ölçülmesi: anahtar sözcük eşleşmesi ile gömme benzerliğinin aynı sorgu kümesindeki erişim kesinliği ve anması, aynı boyutta alan içi ile alan dışı gömmenin getirdiği parça farkı, açı benzerliği ile iç çarpımın ilk üç sonucu kaç sorguda ayırdığı ve uzunluk yanlılığının hangisinde çıktığı, tam tarama tabanına karşı dizinli aramanın anması ile karşılaştırma sayısının yan yana okunması, süzgeç seçiciliği arttıkça daralan uzayda komşuluğun bozulması ve aday sayısının düşmesi, yalnız anahtar sözcük, yalnız gömme ve birleşik kurulumun karşılaştırılması ile birleşiğin ikisinden de kötü kaldığı sorgu sınıfı.

### Gömme Nedir

Source: https://academia.sh/tr/kurslar/rag/gomme-nedir

Bir sorgunun dağarcıktaki hangi belgeye benzediğine sözcüklerle değil anlamla karar verilmesi ve bu kararın iki ayrı ölçütle sayılması. İki yüz belgelik, 693 paragraflık, yirmi kavramlı kurgu bir dağarcıkta kırk sorgu koşturulur: anahtar sözcük eşleşmesinin erişim kesinliği 0,1200 ve erişim anması 0,0616 kalırken gömme benzerliği 0,4600 ve 0,2223 veriyor; ilk sonucun kavram isabeti 0,0500'den 0,5000'e, sınıf isabeti 0,2500'den 1,0000'e çıkıyor. Anmanın tavanı beş parça için 0,4904'tür ve sınıf isabetinin tek başına okunması kavram isabetindeki yarım payı gizler. Bedel 8000 karşılaştırma, 240 gömme çağrısı ve 6400 saklanan sayıdır.

Model API'leri ile Uygulama Geliştirme kursu yirmi altı derste çağrıyı bir ağ işlemi olarak ele
aldı: belirteç bütçesi, akış, biçim doğrulama, önbellek, yedek model ve her düzeneğin bedeli
yazıldı. Kapanışta duran soru şuydu — modele verilen **bilgi** hep istemin içine **elle** konuldu.
Bin belgelik bir dağarcıktan **hangi üçünün** o isteme gireceği, o seçimin **hangi tabana karşı**
ölçüleceği ve yanlış seçimin bedeli hiç sorulmadı.

Bu ders o seçimin ilk aracını kurar. Soru şudur: bir sorgunun dağarcıktaki hangi belgeye
benzediğine karar verirken neye bakılır. En doğrudan yanıt sözcüklerdir. **Gömme** ikinci
yanıttır: metin, komşuluğu anlamı yansıtan bir vektöre çevrilir ve benzerlik vektörler arasında
hesaplanır. Gömmenin tanımı, açı benzerliği ve sözcük komşuluğu Doğal Dil İşleme ve Bilgisayarla
Görme kursunda kuruldu; burada tekrarlanmaz. Bu derste gömme bir **arama anahtarıdır** ve ölçüsü
tektir: getirilen belgenin doğruluğu.

- **GM1.** Bütün kod bir **benzeticidir**. Dağarcık, kavram ekseni, gömme yordamı ve sorgu kümesi
  **kurgudur**; hiçbir gerçek kurum, ürün ya da belge değildir. Tohum **20260218**.
- **GM2.** Benzeticinin modellediği şey şudur: her kavramın **iki yüzeyi** vardır. Belgelerde geçen
  biçim (`kademe esigi`) ile sorguda geçen biçim (`hangi dilimdeyim`) **hiçbir belirteç
  paylaşmaz**. Anahtar sözcük araması yalnız yüzeyi görür; gömme önce yüzeyi **kavrama** çevirir.
- **GM3.** Gömme yordamı iki adımlıdır: yirmi kavramlık bir vektör kurulur, sonra bu vektör
  `BOYUT` boyuta **izdüşürülür**. İzdüşüm bir sıkıştırmadır; bu derste boyut sabit tutulur ve
  otuz ikidir.
- **GM4.** Gömme **belirlenmiştir**: aynı metin her çağrıda aynı vektörü verir. Bu dersin
  koşumdan bağımsız ölçüsü budur ve blokta gösterilir.
- **GM5.** Bu dersin **tabanı anahtar sözcük aramasıdır**: sorgunun ayrık belirteçlerinden kaçının
  belgede geçtiği sayılır, eşitlik durumunda belge sırası karar verir.
- **GM6.** Bir sorgu için **ilgili belge**, ana kavramı sorgunun hedef kavramıyla aynı olan
  belgedir. Getirilen parça sayısı **beştir**.
- **GM7. Erişim kesinliği** getirilen beş belgeden ilgili olanların payı, **erişim anması** ilgili
  belgelerin bu beşe giren payıdır. Kesinlik ile anma çifti Arama Motorları kursunda ölçüldü;
  yordamı tekrarlanmaz.
- **GM8.** **Sınıf isabeti kolay ölçüttür, kavram isabeti zor olandır.** İkisi **iki ayrı sütun**
  olarak basılır.
- **GM9.** Dağarcık bu konuda **belge düzeyinde** kullanılır; parçalama erişim hattına bırakılır.
- **GM10.** Erişimin bedeli **getirilen parça, karşılaştırma sayısı, gömme çağrısı ve saklanan
  sayı adedi** olarak yazılır; ham süre yazılmaz.

#### Kurgu Dağarcık ve Kavram Ekseni

Aşağıdaki blok dağarcığı, kavram eksenini, gömme benzeticisini ve sorgu kümesini kurar. Dağarcık
iki yüz belgedir; her belge bir başlık ve iki ile beş arası paragraf taşır, beş sınıfa ve yirmi
kavrama dağılır. Kavramlar bir ölçüm ağının saha ekibi için tutulan kurgu yordamlardır: tarife
kademesi, arıza kodu, sayaç endeksi, kesinti süresi, vana kontrolü.

Eksen tek bir tasarım kararı üzerine kuruludur. Saha ekibinin yazdığı yordam `kademe esigi` der;
aboneden gelen soru `hangi dilimdeyim` der. İkisi aynı kavramı gösterir ve tek bir belirteç bile
paylaşmaz. Gerçek bir dağarcıkta bu ayrım kısmidir; benzetici onu **uç noktaya taşır** ki iki
aramanın farkı bir gürültü payının içinde kaybolmasın.

```python
# BENZETICI -- KURGUDUR. Gercek bir gomme uc noktasi cagrilmaz. Dagarcik,
# kavram ekseni, gomme yordami ve sorgu kumesi KURGUDUR; hicbir gercek
# kurum, urun ya da belge degildir.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

print(f"dagarcik: {len(BELGE)} belge , {sum(len(d['par']) for d in BELGE)} paragraf ,"
      f" {len(ANAHTAR)} kavram , {len(SINIF)} sinif")
print("sinif dagilimi:", " , ".join(
    f"{s} {sum(1 for d in BELGE if d['sinif'] == s)}" for s in SINIF))
ortak = sum(len(set(belirtecle(KAVRAM[k][1])) & set(belirtecle(KAVRAM[k][2])))
            for k in ANAHTAR)
print(f"belge dili ile sorgu dili arasinda ortak belirtec , 20 kavram : {ortak}")
d = BELGE[0]
print(f"\n{d['kod']} ({d['sinif']}) baslik : {d['baslik']}")
print(f"  paragraf 1  : {d['par'][1]}")
q = SORGU[0]
print(f"sorgu       : {q['metin']}  -> kavram {q['kavram']} , sinif {q['sinif']}")
print(f"  {q['kavram']} belge dilinde '{KAVRAM[q['kavram']][1]}' ,"
      f" sorgu dilinde '{KAVRAM[q['kavram']][2]}'")
u, v = gom(q["metin"]), gom(q["metin"])
print(f"\ngomme {len(u)} boyut , ikinci cagri ayni vektor : {u == v}")
print("ilk alti koordinat :", " ".join(f"{x:+.3f}" for x in u[:6]))
```

```
dagarcik: 200 belge , 693 paragraf , 20 kavram , 5 sinif
sinif dagilimi: tarife 52 , ariza 46 , sayac 39 , kesinti 32 , bakim 31
belge dili ile sorgu dili arasinda ortak belirtec , 20 kavram : 0

BK001 (bakim) baslik : filtre degisimi yordami
  paragraf 1  : kalibrasyon kaydi icin kayit tutulur ve filtre degisimi ile birlikte yazilir
sorgu       : nasil kaydediliyor form  -> kavram okuma , sinif sayac
  okuma belge dilinde 'okuma yordami' , sorgu dilinde 'nasil kaydediliyor'

gomme 32 boyut , ikinci cagri ayni vektor : True
ilk alti koordinat : -0.018 -0.155 -0.145 -0.101 +0.243 +0.028
```

Çıktının ilk üç satırı dağarcığın ölçüsünü veriyor: iki yüz belge, altı yüz doksan üç paragraf,
yirmi kavram, beş sınıf. Sınıflar elli iki ile otuz bir arasında dağılmış, yani hiçbir sınıf tek
başına çoğunluk değil. Üçüncü satır dersin mekanizmasıdır: yirmi kavramın tamamında belge dili
ile sorgu dili arasındaki ortak belirteç sayısı **sıfır**.

Örnek satırlar bunu somutlaştırıyor. `BK001` bakım sınıfından bir belge, paragrafları belge
dilinde yazılmış; ilk sorgu `nasil kaydediliyor form` ve hedef kavramı `okuma`. Okuma kavramı
belgelerde `okuma yordami` diye geçiyor, sorguda `nasil kaydediliyor` diye. Sorgu ile belge
arasında **sözcük köprüsü yok**; köprü ancak kavram üzerinden kurulabilir. Kalan iki satır koşum
sorusunu kapatıyor: aynı metnin iki çağrısı aynı vektörü veriyor. Metin üreten bir çağrıda aynı
istem iki koşumda iki ayrı yanıt verebiliyordu; gömme yüzeyinde veremez.

#### İki Aramanın Aynı Sorgu Kümesindeki Sayısı

Kırk sorgunun her biri iki kurulumda koşturulur. Birincisi **anahtar sözcük aramasıdır**: sorgunun
ayrık belirteçlerinden kaçının belgede geçtiği sayılır, en yüksek puanlı beş belge getirilir,
eşitlikte belge sırası karar verir. İkincisi **gömme aramasıdır**: sorgu ve belgeler aynı
benzeticiyle gömülür, açı benzerliği en yüksek beş belge getirilir. Her kurulum dört sayı üretir;
kesinlik ile anma getirilen kümenin bütünü üzerinde, kavram ile sınıf isabeti yalnız ilk sonuç
üzerinde okunur.

```python
K = 5
BELIRTEC = [set(belirtecle(metin(d))) for d in BELGE]
VEKTOR = [gom(metin(d)) for d in BELGE]
ILGILI = {k: sum(1 for d in BELGE if d["ana"] == k) for k in ANAHTAR}


def ilk_k(puan):
    return sorted(range(len(BELGE)), key=lambda i: (-puan[i], i))[:K]


def anahtar_ara(q):
    qb = set(belirtecle(q["metin"]))
    return ilk_k([len(qb & BELIRTEC[i]) for i in range(len(BELGE))])


def gomme_ara(q):
    qv = gom(q["metin"])
    return ilk_k([aci(qv, VEKTOR[i]) for i in range(len(BELGE))])


def olc(getir):
    kesinlik = anma = kavram = sinif = 0.0
    for q in SORGU:
        ust = getir(q)
        d = sum(BELGE[i]["ana"] == q["kavram"] for i in ust)
        kesinlik += d / K
        anma += d / ILGILI[q["kavram"]]
        kavram += BELGE[ust[0]]["ana"] == q["kavram"]
        sinif += BELGE[ust[0]]["sinif"] == q["sinif"]
    n = len(SORGU)
    return kesinlik / n, anma / n, kavram / n, sinif / n


ort = sum(ILGILI[q["kavram"]] for q in SORGU) / len(SORGU)
tavan = sum(min(K, ILGILI[q["kavram"]]) / ILGILI[q["kavram"]] for q in SORGU) / len(SORGU)
print(f"{len(SORGU)} sorgu , k={K} , sorgu basina ilgili belge {ort:.3f} ,"
      f" anma tavani {tavan:.4f}")
print(f"bedel: {len(SORGU) * K} getirilen parca , {len(SORGU) * len(BELGE)} karsilastirma ,"
      f" {len(BELGE) + len(SORGU)} gomme cagrisi , {len(BELGE) * BOYUT} saklanan sayi")
print("\nkurulum          kesinlik    anma  kavram   sinif")
for ad, getir in (("anahtar sozcuk", anahtar_ara), ("gomme", gomme_ara)):
    p, a, kv, sn = olc(getir)
    print(f"{ad:<16} {p:8.4f} {a:7.4f} {kv:7.4f} {sn:7.4f}")

esit = 0
for q in SORGU:
    qb = set(belirtecle(q["metin"]))
    puan = [len(qb & BELIRTEC[i]) for i in range(len(BELGE))]
    esit += puan.count(max(puan))
print(f"\nanahtar sozcukte en yuksek puani paylasan belge sayisi ortalamasi :"
      f" {esit / len(SORGU):.1f}")
q = SORGU[0]
print(f"sorgu : {q['metin']}  (kavram {q['kavram']})")
for ad, getir in (("anahtar sozcuk", anahtar_ara), ("gomme", gomme_ara)):
    print(f"  {ad:<14}", " ".join(
        f"{BELGE[i]['kod']}/{BELGE[i]['ana']}" for i in getir(q)[:3]))
```

```
40 sorgu , k=5 , sorgu basina ilgili belge 10.825 , anma tavani 0.4904
bedel: 200 getirilen parca , 8000 karsilastirma , 240 gomme cagrisi , 6400 saklanan sayi

kurulum          kesinlik    anma  kavram   sinif
anahtar sozcuk     0.1200  0.0616  0.0500  0.2500
gomme              0.4600  0.2223  0.5000  1.0000

anahtar sozcukte en yuksek puani paylasan belge sayisi ortalamasi : 59.5
sorgu : nasil kaydediliyor form  (kavram okuma)
  anahtar sozcuk BK001/filtre AR002/basinc SY003/okuma
  gomme          SY025/degisim SY031/okuma SY035/degisim
```

#### Tablonun Okunması

Anahtar sözcük satırı bir arama sonucu gibi görünüyor ama değil. Kesinlik 0,1200; sorgu başına
ortalama 10,825 ilgili belge iki yüz belge içinde durduğuna göre rastgele beş belge seçmenin
kesinliği 0,0541 olurdu. Aradaki farkın kaynağını son satırlar söylüyor: en yüksek anahtar sözcük
puanını ortalama **59,5 belge paylaşıyor**. İlk beşi belirleyen şey ilgililik değil, eşitliği
bozan belge sırasıdır. Anma 0,0616'da kalıyor.

Gömme satırı aynı sorgularda 0,4600 kesinlik ve 0,2223 anma veriyor; kesinlik dört katına
çıkıyor. Anmanın kendi tavanı var: her sorguda ortalama 10,825 ilgili belge varken beş belge
getirilirse anma en çok **0,4904** olabilir. Gömme bu tavanın yarısına yakınını alıyor ve kalan
boşluk düzeneğin değil, **getirilen parça sayısının** boşluğudur.

Örnek sorgunun ilk üç sonucu farkı somutlaştırıyor. Anahtar sözcük araması `BK001`, `AR002` ve
`SY003` getiriyor: üç ayrı sınıftan üç belge, hedef kavramı taşıyan tek belge de eşitlik
bozulduğu için üçüncü sıraya gelmiş. Gömme araması üçünü de sayaç sınıfından getiriyor ve
ikincisi hedef kavramı taşıyor.

#### İki Sütunun Niçin Ayrı Durduğu

Tablonun son iki sütunu bu kursun kuralının ilk uygulamasıdır. Gömme aramasının **sınıf isabeti
1,0000**: kırk sorgunun kırkında ilk sonuç doğru sınıftan. Aynı satırın **kavram isabeti 0,5000**:
yirmi sorguda ilk sonuç yanlış kavramın belgesi, doğru sınıfın içinden.

Tek bir ölçüte indirilseydi ne olurdu. Sınıf isabeti raporlansaydı sistem kusursuz görünür,
iyileştirilecek bir şey kalmazdı. Kavram isabeti raporlansaydı yazı tura kadar iyi görünür, sınıf
düzeyindeki tam isabet görünmezdi. İkisi yan yana durunca sorun adını alıyor: **düzenek sınıfı
buluyor, kavramı bulamıyor.** Yanlış getirilen belge aynı sınıftan olduğu için ilgisiz değil,
yalnız yanlış; bir yanıtın içine konduğunda konu dışı görünmez.

Anahtar sözcük satırında aynı ayrım tersinden okunuyor: sınıf isabeti 0,2500, kavram isabeti
0,0500. Sınıf sütunu buradaki başarısızlığı **yumuşatıyor**, çünkü beş sınıf varken dörtte bir
isabet tek bir sınıfı her seferinde söylemenin payından uzak değil.

Bedel satırı düzeneğin fiyatını yazıyor: 8000 karşılaştırma, 240 gömme çağrısı, 6400 saklanan
sayı, 200 getirilen parça. Anahtar sözcük araması gömme çağrısı harcamıyor; farkın tamamı bu 240
çağrının ve 6400 sayının karşılığıdır. Dağarcık büyüdükçe karşılaştırma sayısı doğru orantılı
büyür, çünkü her sorgu bütün dağarcıkla karşılaştırılıyor.

#### Özet

- Bir kavramın belge dilindeki yüzeyi ile sorgu dilindeki yüzeyi ayrı olabilir; bu dağarcıkta
  yirmi kavramın tamamında ortak belirteç sayısı sıfırdır.
- Aynı kırk sorguda anahtar sözcük araması 0,1200 erişim kesinliği ve 0,0616 erişim anması, gömme
  araması 0,4600 ve 0,2223 veriyor.
- Anahtar sözcükte en yüksek puanı ortalama 59,5 belge paylaşıyor; ilk beşi ilgililik değil
  eşitliği bozan sıra belirliyor.
- Anmanın tavanı beş parça ve ortalama 10,825 ilgili belge için 0,4904'tür; ölçülen anma bu tavana
  göre okunur.
- Sınıf isabeti 1,0000 iken kavram isabeti 0,5000'dir; iki sütun sorunu adlandırır, tek sayı
  gizler.
- Erişimin bedeli 8000 karşılaştırma, 240 gömme çağrısı, 6400 saklanan sayı ve 200 getirilen
  parçadır.

#### Sonraki Adım

Bu derste tek bir gömme kullanıldı ve o gömme dağarcığın diliyle sorgunun dilini birlikte tanıyor.
Bu bir varsayımdır: hazır bir gömme modeli başka bir alanın metinleriyle kurulmuşsa sorgu dilini
tanımayabilir. Sonraki ders aynı boyutta iki gömme kurar — biri bu alanın diline uyumlu, öbürü
değil — ve aynı kırk sorguda ikisinin getirdiği parçayı yan yana sayar. Boyut kararının bedeli
Model API'leri ile Uygulama Geliştirme kursunda ölçülmüştü; üstüne eklenecek olan alan uyumunun
payıdır.

### Gömme Modelleri

Source: https://academia.sh/tr/kurslar/rag/gomme-modelleri

Bir gömme modelinin üç ayarından ikisinin aynı iş yükünde yan yana ölçülmesi: boyut ve alan uyumu. Aynı otuz iki boyutta, aynı 6400 saklanan sayıda, aynı kırk sorguda alan içi gömme 0,4600 erişim kesinliği ve 0,5000 kavram isabeti verirken alan dışı gömme 0,0650 ve 0,0500'e düşüyor; kavram ve sınıf isabetinde anahtar sözcük tabanının sayısını birebir tekrarlıyor, getirilen kümede ise tabanın altına iniyor. Aynı aileden ikinci bir gömme modeliyle fark 0,0250 kavram isabetinde kalırken alan dışına düşmenin kaybı 0,4500; ilki ölçülmemiş, ikincisi ölçülmüştür. Boyut süpürmesinde iki model 64 ile 8 arasında hangi boyutun iyi olduğunda anlaşmıyor ve uçurum yalnız 8 ile 4 arasında ortaya çıkıyor.

Önceki ders tek bir gömme kullandı ve o gömme hem dağarcığın dilini hem sorgunun dilini tanıyordu.
Anahtar sözcük tabanına karşı erişim kesinliği 0,1200'den 0,4600'e, kavram isabeti 0,0500'den
0,5000'e çıktı. Bu, bir gömme modelinin sayısı değildi; **sorgu dilini tanıyan** bir gömme modelinin sayısıydı.
Hazır bir modelle bu varsayım kendiliğinden doğru olmaz.

Bir gömme modeli seçilirken üç ayar konuşulur: **boyut**, **alan uyumu** ve **dil desteği**. Boyut
kararının bedeli Model API'leri ile Uygulama Geliştirme kursunda ölçüldü: üç en yakın komşunun
aynı konudan olma payı yüz kırk dört boyutta 0,9259 iken yetmiş iki boyutta 0,9028 oldu, saklanan
sayı 10368'den yarısına indi. O yordam tekrarlanmaz; bu dersin eklediği **aynı boyutta** alan
uyumunun payıdır. Dil desteği üçüncü bir ayar gibi görünür ama bu ölçüde aynı yüzeydir: soru her
iki durumda da modelin **sorgu dilini tanıyıp tanımadığıdır**.

- **GM11.** Bütün kod **benzeticidir**; dağarcık, kavram ekseni ve gömme yordamı **kurgudur**.
  Tohum **20260218**. Gerçek bir gömme uç noktası çağrılmaz.
- **GM12.** **Alan uyumu benzeticide açıkça modellenir.** Alan içi gömme kavramın iki yüzeyini de
  tanır: belge dilindeki `basinc dususu` ile sorgu dilindeki `zayif akis` aynı kavrama gider. Alan
  dışı gömme yalnız belge yüzeyini tanır; sorgu yüzeyini görmez ve elinde kalan tek sinyal
  belgelerle paylaşılan **ortak sözcüklerdir**. Bu, başka bir alanın metinleriyle kurulmuş bir
  gömmenin yapısal karşılığıdır.
- **GM13.** Boyut **sabit tutulur**: otuz iki. İki kurulum aynı sayıda koordinat saklar ve aynı
  sayıda çarpma yapar; aradaki fark **yalnız** alan uyumundandır.
- **GM14.** **Aynı aileden ikinci bir gömme modeli** kurulur; yalnız izdüşüm tohumu farklıdır
  (20260219). Bir kaybın ölçülmüş sayılması için **iki model arasındaki farkı aşması** gerekir.
  Bu, dersin koşumdan bağımsız tabanıdır.
- **GM15.** Taban çizgisi yine **anahtar sözcük aramasıdır**; ölçü tanımları önceki dersle aynıdır:
  getirilen parça beş, ilgili belge ana kavramı sorgunun hedef kavramıyla aynı olan belge.
- **GM16.** Boyut süpürmesi **iki modelle birlikte** okunur; iki model aynı sıralamayı vermiyorsa
  o aralıkta **ölçülmüş bir sıra yoktur**.
- **GM17.** Saklama maliyeti **belge sayısı çarpı boyut**, yani saklanan sayı adedidir.

#### Alan Uyumu Neyin Modellenmesidir

İlk blok dağarcığı, kavram eksenini ve gömme benzeticisini kurar; sonunda tek bir sorgu üzerinde
alan uyumunu gösterir. Alan içi gömme sorgu yüzeyini gördüğünde kavramın ağırlığını tam yazar;
alan dışı gömme o kavramı **göremez** ve geriye ortak sözcüklerin dağıttığı ince bir ağırlık
kalır.

```python
# BENZETICI -- KURGUDUR. Gercek bir gomme uc noktasi cagrilmaz. Dagarcik,
# kavram ekseni, gomme yordami ve sorgu kumesi KURGUDUR; hicbir gercek
# kurum, urun ya da belge degildir.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

print(f"dagarcik: {len(BELGE)} belge , {len(ANAHTAR)} kavram , {len(SINIF)} sinif ,"
      f" {len(SORGU)} sorgu , gomme boyutu {BOYUT}")
q = SORGU[3]
k = q["kavram"]
print(f"sorgu : {q['metin']}  -> kavram {k} , sinif {q['sinif']}")
print(f"  {k} belge dilinde '{KAVRAM[k][1]}' , sorgu dilinde '{KAVRAM[k][2]}'")
print(f"  alan ici gomme kavram vektorunde {k} agirligi :"
      f" {_kavramla(q['metin'])[ANAHTAR.index(k)]:.2f}")
print(f"  alan disi gomme kavram vektorunde {k} agirligi :"
      f" {_kavramla(q['metin'], alan=False)[ANAHTAR.index(k)]:.2f}")
```

```
dagarcik: 200 belge , 20 kavram , 5 sinif , 40 sorgu , gomme boyutu 32
sorgu : zayif akis bolge  -> kavram basinc , sinif ariza
  basinc belge dilinde 'basinc dususu' , sorgu dilinde 'zayif akis'
  alan ici gomme kavram vektorunde basinc agirligi : 1.00
  alan disi gomme kavram vektorunde basinc agirligi : 0.05
```

Son iki satır ölçünün tamamını taşıyor. `basinc` kavramı için ağırlık alan içi gömmede 1,00, alan
dışı gömmede 0,05. İkincisi bir kavram sinyali değil, ortak sözcüklerin bütün kavramlara eşit
dağıttığı taban gürültüsüdür: alan dışı gömme sorguyu **yirmi kavrama eşit uzaklıkta** bir noktaya
koyuyor.

#### Aynı Boyutta İki Gömme

Aşağıdaki blok beş kurulumu aynı kırk sorguda koşturur: anahtar sözcük tabanı, alan içi gömmenin
iki modeli ve alan dışı gömmenin iki modeli. Hepsi otuz iki boyutta çalışır ve aynı sayıda
koordinat saklar. Son sütun kırk sorgunun kaç **farklı** ilk-beş kümesi
ürettiğini sayar; bir sıralayıcının sorgudan sorguya değişip değişmediği oradan okunur. Son iki
satır aynı alanda kalan iki model arasındaki farkı ve alan dışına düşmenin kaybını ayrı yazar.

```python
K = 5
ILGILI = {k: sum(1 for d in BELGE if d["ana"] == k) for k in ANAHTAR}
BELIRTEC = [set(belirtecle(metin(d))) for d in BELGE]

# Ayni aileden IKINCI gomme modeli: yalnizca izdusum tohumu farkli (20260219).
IZDUS2 = []
for i in range(len(ANAHTAR)):
    r = uretec((TOHUM + 1) ^ (i + 1) * 2654435761)
    IZDUS2.append([r() * 2 - 1 for _ in range(64)])


def gom2(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS2[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def olc(sirala):
    """Dort sayi ve kirk sorgunun urettigi FARKLI ilk-bes kumesi adedi."""
    kesinlik = anma = kavram = sinif = 0.0
    kume = set()
    for q in SORGU:
        ust = sirala(q)[:K]
        kume.add(tuple(sorted(ust)))
        t = sum(BELGE[i]["ana"] == q["kavram"] for i in ust)
        kesinlik += t / K
        anma += t / ILGILI[q["kavram"]]
        kavram += BELGE[ust[0]]["ana"] == q["kavram"]
        sinif += BELGE[ust[0]]["sinif"] == q["sinif"]
    n = len(SORGU)
    return kesinlik / n, anma / n, kavram / n, sinif / n, len(kume)


def anahtar_sirala(q):
    qb = set(belirtecle(q["metin"]))
    return sorted(range(len(BELGE)), key=lambda i: (-len(qb & BELIRTEC[i]), i))


def gomme_sirala(gomucu, alan, boyut=BOYUT):
    vek = [gomucu(metin(d), boyut, alan) for d in BELGE]

    def sirala(q):
        qv = gomucu(q["metin"], boyut, alan)
        return sorted(range(len(BELGE)), key=lambda i: (-aci(qv, vek[i]), i))
    return sirala


print("kurulum                kesinlik    anma  kavram   sinif  kume")
sonuc = {}
for ad, sirala in (("anahtar sozcuk", anahtar_sirala),
                   ("alan ici  , model 1", gomme_sirala(gom, True)),
                   ("alan ici  , model 2", gomme_sirala(gom2, True)),
                   ("alan disi , model 1", gomme_sirala(gom, False)),
                   ("alan disi , model 2", gomme_sirala(gom2, False))):
    sonuc[ad] = olc(sirala)
    print(f"{ad:<21} " + " ".join(f"{x:7.4f}" for x in sonuc[ad][:4])
          + f" {sonuc[ad][4]:5d}")

ic1, ic2 = sonuc["alan ici  , model 1"], sonuc["alan ici  , model 2"]
di1 = sonuc["alan disi , model 1"]
print("\niki model arasindaki fark (alan ici) :",
      " ".join(f"{abs(a - b):7.4f}" for a, b in zip(ic1[:4], ic2[:4])))
print("alan disina dusmenin kaybi (model 1) :",
      " ".join(f"{a - b:7.4f}" for a, b in zip(ic1[:4], di1[:4])))
print(f"saklanan sayi her kurulumda ayni : {len(BELGE) * BOYUT}")
```

```
kurulum                kesinlik    anma  kavram   sinif  kume
anahtar sozcuk         0.1200  0.0616  0.0500  0.2500    20
alan ici  , model 1    0.4600  0.2223  0.5000  1.0000    17
alan ici  , model 2    0.4050  0.2035  0.5250  1.0000    17
alan disi , model 1    0.0650  0.0316  0.0500  0.2500     1
alan disi , model 2    0.0450  0.0247  0.0250  0.2500     1

iki model arasindaki fark (alan ici) :  0.0550  0.0188  0.0250  0.0000
alan disina dusmenin kaybi (model 1) :  0.3950  0.1907  0.4500  0.7500
saklanan sayi her kurulumda ayni : 6400
```

Tablonun en dikkat çeken satırı alan dışı gömmenin kavram ve sınıf sütunlarıdır: **0,0500** ve
**0,2500**. Bu iki sayı anahtar sözcük tabanınınkilerle **birebir aynı**. Alan dışı gömme vektör
üretiyor, açı benzerliği hesaplıyor, sıralama yapıyor ve ilk sonuçta sözcük eşleşmesinden
fazlasını elde etmiyor. Boyut, saklama ve karşılaştırma aynı; düzeneğin tamamı silinmiş durumda.

Getirilen kümeye bakıldığında durum daha ağırdır. Alan dışı gömmenin erişim kesinliği 0,0650,
anması 0,0316; anahtar sözcük tabanı ise 0,1200 ve 0,0616. Yani beş belgelik küme, hiç gömme
kullanılmadığı duruma göre **daha kötü**. Eklenen düzenek sayıyı yükseltmedi, düşürdü. Nedeni son
sütunda yazılı: alan dışı kurulum kırk sorguda **tek bir** ilk-beş kümesi üretiyor. Bütün sorgular
aynı noktaya düştüğü için hepsine aynı beş belge gidiyor. Anahtar sözcük tabanı yirmi ayrı küme,
alan içi gömme on yedi ayrı küme üretiyor.

Kaybın ölçülmüş sayılıp sayılmayacağına son iki satır karar veriyor. İki model arasındaki fark
kesinlikte 0,0550, anmada 0,0188, kavram isabetinde 0,0250, sınıf isabetinde 0,0000. Alan dışına
düşmenin kaybı ise 0,3950, 0,1907, 0,4500 ve 0,7500; kavram isabetinde model farkının **on sekiz
katı**. Model API'leri kursunda boyutu yarıya indirmenin kaybı model farkıyla aynı büyüklükte
çıkmış ve **ölçülmemiş** sayılmıştı. Buradaki kayıp o eşiğin çok üstündedir: **alan uyumu, boyutla
aynı kefeye konacak bir ayar değildir.**

Bir gömme modelinin dil listesi bu ölçünün yerine geçmez. Listede bir dilin bulunması modelin o
dildeki **belge** metinlerini gördüğü anlamına gelir, kullanıcının aynı kavramı hangi sözcüklerle
sorduğunu gördüğü anlamına gelmez.

#### Boyutun Nerede Öldüğü

Alan uyumu sabitlenip boyut süpürülürse ne olur. Aşağıdaki blok alan içi kurulumu beş boyutta iki
modelle koşturur.

```python
print("boyut  saklanan  model 1 kavram / sinif  model 2 kavram / sinif")
for d in (64, 32, 16, 8, 4):
    a = olc(gomme_sirala(gom, True, d))
    b = olc(gomme_sirala(gom2, True, d))
    print(f"{d:>5} {len(BELGE) * d:>9} {a[2]:>16.4f} {a[3]:>7.4f}"
          f" {b[2]:>15.4f} {b[3]:>7.4f}")
```

```
boyut  saklanan  model 1 kavram / sinif  model 2 kavram / sinif
   64     12800           0.4250  1.0000          0.4500  1.0000
   32      6400           0.5000  1.0000          0.5250  1.0000
   16      3200           0.4500  1.0000          0.4000  0.9500
    8      1600           0.6000  0.9500          0.4750  0.8250
    4       800           0.2750  0.5500          0.3000  0.6500
```

Kavram sütunları 64 ile 8 arasında **monoton değil**. Birinci model 0,4250, 0,5000, 0,4500, 0,6000
veriyor ve en yükseği en küçük boyutta alıyor; ikinci model 0,4500, 0,5250, 0,4000, 0,4750 veriyor
ve en yükseği otuz ikide alıyor. İki model **hangi boyutun daha iyi olduğunda anlaşmıyor** ve
sekiz boyuttaki fark 0,1250, yani otuz ikideki model farkının beş katı. Bu aralıkta boyut
sıralaması **ölçülmemiştir**; tek modelin süpürmesine bakarak sekize inmek bir çekilişe dayanmak
olur.

Sınıf sütunu daha kararlıdır ve asıl bilgiyi o taşıyor. Birinci modelde sekiz boyuta kadar 0,9500
altına inmiyor; ikinci modelde on altıda 0,9500'e, sekizde 0,8250'ye iniyor. Dört boyutta ikisi
birlikte çöküyor: 0,5500 ve 0,6500. **Uçurum sekiz ile dört boyut arasındadır** ve nedeni
sayılabilir: yirmi kavram dört koordinata sıkıştırıldığında iki kavramın aynı yöne düşmesi
kaçınılmazdır.

Saklama tarafı okumayı tamamlıyor. Altmış dört boyuttan sekize inmek saklanan sayıyı 12800'den
1600'e indiriyor ve sınıf isabetinde birinci modelde ölçülmüş bir kayıp bırakmıyor; dörde inmek saklamayı yalnız
yarı yarıya daha azaltıp sınıf isabetini yarıya düşürüyor. Boyut kararının biçimi Model API'leri
kursunda görülenle aynı yöndedir: uzun bir aralıkta bedelsiz, sonra bir anda pahalı.

#### Özet

- Alan uyumu, bir gömme modelinin sorgu dilindeki yüzeyi belge dilindeki yüzeyle aynı kavrama
  bağlayıp bağlamamasıdır; dil desteği aynı sorunun başka adıdır.
- Aynı otuz iki boyutta ve aynı 6400 saklanan sayıda alan içi gömme 0,4600 kesinlik ve 0,5000
  kavram isabeti, alan dışı gömme 0,0650 ve 0,0500 veriyor.
- Alan dışı gömmenin kavram ve sınıf isabeti anahtar sözcük tabanıyla birebir aynıdır; getirilen
  kümede tabanın altına düşer, çünkü kırk sorguya tek bir ilk-beş kümesi verir.
- İki model arasındaki fark kavram isabetinde 0,0250, alan dışına düşmenin kaybı 0,4500; ilki
  ölçülmemiş, ikincisi ölçülmüş bir farktır.
- Boyut süpürmesinde iki model 64 ile 8 arasında anlaşmıyor; o aralıkta ölçülmüş bir sıra yoktur.
- Uçurum 8 ile 4 boyut arasındadır ve eşik kavram sayısından gelir: yirmi kavram dörde sığmaz.

#### Sonraki Adım

Bu iki derste benzerlik tek bir yordamla hesaplandı: karşılıklı koordinatlar çarpılıp toplandı ve
vektörler bundan önce birim uzunluğa getirildi. İkinci adım sessiz bir karardır. Normalleştirme
yapılmazsa aynı çarpım başka bir sıralama üretir ve uzun belgeler daha yüksek puan almaya başlar.
Sonraki ders açı benzerliği ile iç çarpımı aynı kırk sorguda yan yana koyar: ilk üç sonuç kaç
sorguda ayrışıyor, hangi ölçüt uzunluğa yanlı ve bu yanlılık getirilen parçanın doğruluğunu ne
yönde oynatıyor.

### Benzerlik Ölçütleri

Source: https://academia.sh/tr/kurslar/rag/benzerlik-olcutleri

Aynı vektörlerin iki ayrı ölçütle sıralanması ve seçimin getirilen parçayı ne kadar değiştirdiği. İç çarpım, açı benzerliğinin iki vektörün boyuyla çarpımıdır; bir sorgu için sorgu boyu sabit olduğundan bütün sıra farkı belge vektörünün boyundan gelir ve bu boy en kısa çeyrekte 4,6864, en uzun çeyrekte 5,3966'dır. Kırk sorgunun otuzunda ilk üç sonuç ayrışıyor; açı benzerliği 0,4600 erişim kesinliği ve 0,5000 kavram isabeti verirken iç çarpım 0,3900 ve 0,4250'de kalıyor ve ikinci bir gömme modelinde de aynı yön çıkıyor. Uzunluk yanlılığı iç çarpımdadır: getirilen kümenin ortalaması 64,3 belirteç, açı benzerliğinde 54,6, dağarcıkta 61,5; ilgili belgelerin ortalaması da 61,5 olduğuna göre uzunluk ilgililik taşımıyor.

Önceki iki ders benzerliği hep aynı yordamla hesapladı: vektörler birim uzunluğa getirildi,
sonra karşılıklı koordinatlar çarpılıp toplandı. Birinci adım sessiz bir karardı ve hiç
tartışılmadı. Vektörler birim uzunluğa getirilmezse aynı çarpım başka bir sayı verir ve başka bir
sıralama üretir.

İki ölçüt bu iki durumun adıdır. **Açı benzerliği** iki vektör arasındaki açıyı ölçer ve
uzunluklarını yok sayar. **İç çarpım** koordinat çarpımlarını doğrudan toplar ve uzunluğu içinde
taşır. Aralarındaki bağıntı tek satırdır:

$$\text{iç çarpım}(u, v) = \text{açı benzerliği}(u, v) \cdot \lVert u \rVert \cdot \lVert v \rVert$$

Bir sorgu sabitken $\lVert u \rVert$ bütün belgeler için aynıdır. Buradan çıkan sonuç bu dersin
ekseni: iki ölçüt arasındaki **bütün sıra farkı** $\lVert v \rVert$ değerinden, yani **belge
vektörünün boyundan** gelir.

- **GM18.** Kod **benzeticidir**, dağarcık ve gömme yordamı **kurgudur**, tohum **20260218**.
  Boyut otuz iki, getirilen parça beş, ilgili belge tanımı önceki iki dersle aynı, gömme alan içi.
- **GM19.** **Tek vektör kümesi, iki ölçüt.** Paylaşılan gömme yordamı vektörü birim uzunluğa
  getirir, ham yordam getirmez; açı benzerliği birim vektörlerin iç çarpımıdır.
- **GM20.** Yukarıdaki bağıntı blokta **sayıyla denetlenir**.
- **GM21.** Belge uzunluğu **belirteç sayısıyla** ölçülür; dağarcıkta otuz iki ile doksan altı
  arası değişiyor.
- **GM22. Ayrışma** ilk **üç** sonucun **kümesi** üzerinden sayılır: iki ölçüt aynı üç belgeyi
  getiriyorsa sıraları farklı olsa bile ayrışmamış sayılır.
- **GM23.** **Uzunluk yanlılığı iki tabana karşı okunur**: getirilen kümenin ortalama belirteci
  dağarcık ortalamasına, ilk beşte en uzun çeyreğin payı o çeyreğin dağarcıktaki payına karşı.
- **GM24.** Koşumdan bağımsız ölçü **aynı aileden ikinci bir gömme modelidir** (izdüşüm tohumu
  20260219). Sıralama iki modelde aynı yönde çıkmazsa **ölçülmüş sayılmaz**.

#### Tek Vektör Kümesi, İki Ölçüt

İlk blok dağarcığı kurar, normalleştirilmemiş vektörü üreten yordamı ekler ve iki şeyi gösterir:
belge vektörünün boyu uzunlukla nasıl büyüyor ve bağıntı tutuyor mu.

```python
# BENZETICI -- KURGUDUR. Gercek bir gomme uc noktasi cagrilmaz. Dagarcik,
# kavram ekseni, gomme yordami ve sorgu kumesi KURGUDUR; hicbir gercek
# kurum, urun ya da belge degildir.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# Iki olcut, tek vektor kumesi: paylasilan gom() vektoru birim uzunluga getirir,
# ham() getirmez. Aci benzerligi birim vektorlerin ic carpimidir.
def ham(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    return v


def uzunluk(v):
    return sum(x * x for x in v) ** 0.5


BELIRTEC = [len(belirtecle(metin(d))) for d in BELGE]
NORM = [uzunluk(ham(metin(d))) for d in BELGE]
sirali = sorted(range(len(BELGE)), key=lambda i: BELIRTEC[i])
c = len(BELGE) // 4
kisa, uz = sirali[:c], sirali[-c:]
print(f"dagarcik: belirtec ortalamasi {sum(BELIRTEC) / len(BELGE):.1f} ,"
      f" en kisa {BELIRTEC[sirali[0]]} , en uzun {BELIRTEC[sirali[-1]]}")
print(f"  en kisa ceyrek : ortalama {sum(BELIRTEC[i] for i in kisa) / c:.1f} belirtec ,"
      f" ham vektor uzunlugu {sum(NORM[i] for i in kisa) / c:.4f}")
print(f"  en uzun ceyrek : ortalama {sum(BELIRTEC[i] for i in uz) / c:.1f} belirtec ,"
      f" ham vektor uzunlugu {sum(NORM[i] for i in uz) / c:.4f}")
q, d = SORGU[0], BELGE[0]
qh, bh = ham(q["metin"]), ham(metin(d))
print(f"\nozdeslik denetimi , sorgu 1 ile {d['kod']}:")
print(f"  ic carpim                  {aci(qh, bh):.6f}")
print(f"  aci benzerligi             {aci(gom(q['metin']), gom(metin(d))):.6f}")
print(f"  aci * iki vektorun boyu    "
      f"{aci(gom(q['metin']), gom(metin(d))) * uzunluk(qh) * uzunluk(bh):.6f}")
```

```
dagarcik: belirtec ortalamasi 61.5 , en kisa 32 , en uzun 96
  en kisa ceyrek : ortalama 37.7 belirtec , ham vektor uzunlugu 4.6864
  en uzun ceyrek : ortalama 85.8 belirtec , ham vektor uzunlugu 5.3966

ozdeslik denetimi , sorgu 1 ile BK001:
  ic carpim                  -0.218248
  aci benzerligi             -0.011168
  aci * iki vektorun boyu    -0.218248
```

Çeyrek satırları mekanizmayı veriyor. En kısa çeyrekte belge ortalama 37,7 belirteç ve ham vektör
boyu 4,6864; en uzun çeyrekte 85,8 belirteç ve 5,3966. Belge iki buçuk katına çıkarken boy yalnız
yüzde on beş büyüyor, ama iç çarpım o boyla **çarpıldığı** için bu yüzde on beş doğrudan puana
giriyor. Nedeni yordamda yazılı: bir belge ne kadar çok kavram anıyorsa kavram vektörüne o kadar
çok ağırlık düşüyor.

Özdeşlik denetimi bağıntının tuttuğunu gösteriyor: iç çarpım doğrudan hesaplandığında ve açı
benzerliği iki boyla çarpıldığında altı basamağa kadar aynı sayı çıkıyor. İki ölçüt ayrı yordamlar
değil; **biri öbürünün boylarla çarpılmış hâlidir**.

#### Ölçüt Değişince Sıra Ne Kadar Değişiyor

Aşağıdaki blok aynı kırk sorguyu iki ölçütle koşturur ve bunu iki gömme modelinde tekrarlar. Her
model için önce ilk üç sonucu ayrışan sorgu sayısı, sonra dört erişim ölçüsü ve getirilen kümenin
ortalama belirteci basılır.

```python
K = 5
ILGILI = {k: sum(1 for d in BELGE if d["ana"] == k) for k in ANAHTAR}

# Ayni aileden ikinci gomme modeli: yalniz izdusum tohumu farkli (20260219).
IZDUS2 = []
for i in range(len(ANAHTAR)):
    r = uretec((TOHUM + 1) ^ (i + 1) * 2654435761)
    IZDUS2.append([r() * 2 - 1 for _ in range(64)])


def ham2(m, boyut=BOYUT):
    k = _kavramla(m)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS2[i][j % 64]
    return v


def birim(v):
    n = uzunluk(v)
    return [x / n for x in v] if n else v


def diz(qv, vek):
    return sorted(range(len(BELGE)), key=lambda i: (-aci(qv, vek[i]), i))


def olc(gomucu):
    hv = [gomucu(metin(d)) for d in BELGE]
    av = [birim(v) for v in hv]
    sayi = {"aci": [0.0] * 5, "ic carpim": [0.0] * 5}
    ayrisan = 0
    for q in SORGU:
        qh = gomucu(q["metin"])
        a, b = diz(birim(qh), av), diz(qh, hv)
        ayrisan += set(a[:3]) != set(b[:3])
        for ad, ust in (("aci", a[:K]), ("ic carpim", b[:K])):
            t = sum(BELGE[i]["ana"] == q["kavram"] for i in ust)
            s = sayi[ad]
            s[0] += t / K
            s[1] += t / ILGILI[q["kavram"]]
            s[2] += BELGE[ust[0]]["ana"] == q["kavram"]
            s[3] += BELGE[ust[0]]["sinif"] == q["sinif"]
            s[4] += sum(BELIRTEC[i] for i in ust) / K
    n = len(SORGU)
    return ayrisan, {ad: [x / n for x in s] for ad, s in sayi.items()}


for etiket, gomucu in (("model 1", ham), ("model 2", ham2)):
    ayrisan, sonuc = olc(gomucu)
    print(f"{etiket} : ilk uc sonucu ayrisan sorgu {ayrisan}/{len(SORGU)}")
    print("  olcut      kesinlik    anma  kavram   sinif  ortalama belirtec")
    for ad, s in sonuc.items():
        print(f"  {ad:<10} " + " ".join(f"{x:7.4f}" for x in s[:4]) + f" {s[4]:15.1f}")
```

```
model 1 : ilk uc sonucu ayrisan sorgu 30/40
  olcut      kesinlik    anma  kavram   sinif  ortalama belirtec
  aci         0.4600  0.2223  0.5000  1.0000            54.6
  ic carpim   0.3900  0.1879  0.4250  0.9500            64.3
model 2 : ilk uc sonucu ayrisan sorgu 27/40
  olcut      kesinlik    anma  kavram   sinif  ortalama belirtec
  aci         0.4050  0.2035  0.5250  1.0000            52.6
  ic carpim   0.3400  0.1680  0.3500  0.9500            57.9
```

İlk satır ölçüt seçiminin bir ayrıntı olmadığını söylüyor: kırk sorgunun **otuzunda** iki ölçüt
farklı bir ilk üçlü getiriyor. Aynı vektörler, aynı dağarcık, aynı sorgular; değişen tek şey
puanın normalleştirilmiş vektörlerden mi ham vektörlerden mi okunduğu.

Dört ölçüde açı benzerliği her sütunda önde: kesinlik 0,4600'e karşı 0,3900, anma 0,2223'e karşı
0,1879, kavram isabeti 0,5000'e karşı 0,4250, sınıf isabeti 1,0000'e karşı 0,9500. İkinci gömme
modelinde sayılar değişiyor ama **yön değişmiyor**: 0,4050'ye karşı 0,3400 ve 0,5250'ye karşı
0,3500. Ölçüt sıralaması tek bir izdüşümün çekilişi değil.

Son sütun farkın nereden geldiğini gösteriyor. Açı benzerliğinin getirdiği beş belgenin ortalaması
54,6 belirteç, iç çarpımınki 64,3. Aradaki 9,7 belirteçlik kayma bir yan ürün değil, ölçütün
tanımının doğrudan sonucudur.

#### Uzunluğun İlgililik Taşımadığı Yerde Uzunluğa Bakmak

Bir kaymanın yanlılık sayılabilmesi için uzunluğun **ilgililik taşımadığının** gösterilmesi
gerekir. Aşağıdaki blok iki tabanı basar: dağarcığın ortalama uzunluğu ile ilgili belgelerin
ortalama uzunluğu ve en uzun çeyreğin iki ölçütün ilk beşindeki payı.

```python
c = len(BELGE) // 4
enuzun = set(sorted(range(len(BELGE)), key=lambda i: -BELIRTEC[i])[:c])
ilg = {k: [i for i, d in enumerate(BELGE) if d["ana"] == k] for k in ANAHTAR}
print(f"dagarcik ortalamasi {sum(BELIRTEC) / len(BELGE):.1f} belirtec ,"
      f" en uzun ceyregin payi {c / len(BELGE):.4f}")
print("ilgili belgelerin ortalamasi %.1f belirtec"
      % (sum(sum(BELIRTEC[i] for i in ilg[q["kavram"]]) / len(ilg[q["kavram"]])
             for q in SORGU) / len(SORGU)))
hv = [ham(metin(d)) for d in BELGE]
av = [birim(v) for v in hv]
print("\nolcut      ilk beste en uzun ceyregin payi")
for ad, vek, qf in (("aci", av, lambda q: birim(ham(q["metin"]))),
                    ("ic carpim", hv, lambda q: ham(q["metin"]))):
    p = sum(sum(1 for i in diz(qf(q), vek)[:K] if i in enuzun) / K
            for q in SORGU) / len(SORGU)
    print(f"{ad:<10} {p:32.4f}")
```

```
dagarcik ortalamasi 61.5 belirtec , en uzun ceyregin payi 0.2500
ilgili belgelerin ortalamasi 61.5 belirtec

olcut      ilk beste en uzun ceyregin payi
aci                                  0.0800
ic carpim                            0.2500
```

İlk iki satır kararı veriyor. Dağarcığın ortalaması 61,5 belirteç; ilgili belgelerin ortalaması da
61,5. Uzunluk ile ilgililik arasında bu dağarcıkta bir bağ yok, yani uzun bir belgenin sorguya
yanıt verme şansı kısa bir belgeden fazla değil.

Alt tablo bunun sıralamaya nasıl yansıdığını yazıyor. En uzun çeyrek dağarcığın 0,2500'ünü
oluşturuyor. İç çarpımın ilk beşinde bu çeyreğin payı **0,2500**, yani taban oranın tam kendisi;
açı benzerliğinin ilk beşinde **0,0800**, yani taban oranın üçte birinden az. İki ölçüt uzunluğa
karşı iki ayrı yerde duruyor: iç çarpım uzun belgeleri dağarcıktaki paylarında tutuyor, açı
benzerliği onları eliyor.

Elemenin niçin işe yaradığı boyun tanımından okunur. Uzun belge daha çok kavram anıyor; ham
vektörü daha uzun ama **daha dağınık**. Açı benzerliği boyu bölerek attığı için kalan soru "kaç
kavram anılmış" değil, "hangi kavrama ne oranda yer verilmiş" oluyor; sorgu tek bir kavramı
hedeflediğine göre kazanan yoğunlaşmış belge oluyor.

Buradan çıkan sonuç ölçüt adlarından bağımsızdır. **Bütün vektörler birim uzunluktaysa iki ölçüt
aynı sıralamayı verir**; boylar bire eşit olduğunda çarpım hiçbir şeyi değiştirmez. Asıl karar
"hangi ölçüt" değil, **vektörler saklanırken normalleştiriliyor mu** kararıdır. Normalleştirme
yapılıyorsa iç çarpım bir bölme işleminden tasarruf eder ve sonuç aynıdır; yapılmıyorsa ölçüt
seçimi kırk sorgunun otuzunda getirilen parçayı değiştirir.

#### Özet

- İç çarpım, açı benzerliğinin iki vektörün boyuyla çarpımıdır; sabit bir sorguda bütün sıra farkı
  belge vektörünün boyundan gelir.
- Belge vektörünün boyu uzunlukla büyür: en kısa çeyrekte 4,6864, en uzun çeyrekte 5,3966.
- Kırk sorgunun otuzunda iki ölçüt farklı bir ilk üçlü getiriyor.
- Açı benzerliği dört ölçüde de önde (0,4600 / 0,2223 / 0,5000 / 1,0000 karşısında 0,3900 / 0,1879
  / 0,4250 / 0,9500) ve ikinci gömme modelinde yön aynı kalıyor.
- Uzunluk yanlılığı iç çarpımdadır: getirilen kümenin ortalaması 64,3 belirteç, açı benzerliğinde
  54,6, dağarcıkta 61,5; en uzun çeyreğin ilk beşteki payı 0,2500 ile 0,0800.
- İlgili belgelerin ortalaması da 61,5 belirteçtir, yani uzunluk ilgililik taşımaz; vektörler birim
  uzunlukta saklanıyorsa iki ölçüt aynı sıralamayı verir.

#### Sonraki Adım

Üç derste erişimin üç kararı ölçüldü: sözcük mü anlam mı, hangi gömme modeli, hangi ölçüt. Üçünde
de ortak kalan ve hiç sorulmayan bir şey vardı: her sorgu **bütün dağarcıkla** karşılaştırıldı,
kırk sorgu ve iki yüz belge için 8000 karşılaştırma yapıldı, tam sıralama her seferinde baştan
kuruldu. İki yüz belgede bu bir sorun değil; dağarcık yüz binlerce parçaya çıktığında her sorgu
için bütün vektörlere dokunmak sürdürülemez. Sonraki ders vektörleri bir **dizin** içine koyar ve
tam taramayı taban alarak sorar: bütün belgelere dokunmadan getirilen küme dokunularak
getirilenden ne kadar sapıyor ve karşılaştırma sayısı karşılığında hangi anma veriliyor.

### Vektör Veritabanları

Source: https://academia.sh/tr/kurslar/rag/vektor-veritabanlari

Sorgunun bütün dağarcıkla karşılaştırılması varsayımının kaldırılması ve yaklaşıklığın bedelinin ölçülmesi. İki yüz kurgu belgede tam tarama sorgu başına 200 karşılaştırma ister; kovalı dizin kova 16 ve sonda 2 ile anmayı 0,9600'de tutup karşılaştırmayı 47,2'ye indiriyor, sonda 4'te anma 1,0000 ve karşılaştırma 69,2. Sonda 1'de anma 0,7000'e, ilk beşin kavram kesinliği 0,4600'den 0,3600'e düşüyor: dizin yalnız aday kümesini değil yanıtı da bozuyor. Komşuluk çizgesi derece 8'de giriş düğümünden yalnız 27 belgeye erişebiliyor ve anması 0,0800; derece 48'de 9600 kenar saklayıp 84,7 karşılaştırmayla 0,7650'de kalıyor, yani kovalı dizinden hem pahalı hem kötü. İki dizin kurulumu arasındaki fark 0,0200 ve bu iş yükünün eşiği budur.

Önceki üç ders gömmeyi bir arama anahtarı olarak kurdu, alan uyumunun ne kadarını taşıdığını
ölçtü ve iki benzerlik ölçütünün aynı sorguda ayrıştığı yeri saydı. Üçünün de ortak bir sessiz
varsayımı vardı: bir sorgu geldiğinde dağarcıktaki **her belgeyle** karşılaştırılıyordu. İki yüz
belgede bu varsayım ucuzdur. Dağarcık büyüdüğünde ucuz olmaktan çıkar, çünkü karşılaştırma sayısı
belge sayısıyla doğru orantılı büyür ve her sorgu dağarcığın tamamını okumak zorunda kalır.

Vektör deposu bu yükü bir **dizin** ile azaltır: sorgu geldiğinde dağarcığın yalnız bir kısmına
bakılır. Bir kısmına bakmak, doğru komşunun bakılmayan kısımda kalabilmesi demektir; bu yüzden
dizinli aramaya **yaklaşık komşu arama** denir ve tam taramanın verdiği yanıtı vermek zorunda
değildir. Bu dersin ölçtüğü şey o farktır: **yaklaşıklığın kaybettirdiği**. Tam tarama tabanına
karşı iki dizin yapısının **anması** ile **karşılaştırma sayısı** yan yana basılır ve ikisinden
birinin saklamayı katlamasına karşın tabanın hem altında hem de pahalı kaldığı gösterilir.

- **GM31.** Dağarcık, gömme yordamı ve sorgu kümesi **kurgudur**; gerçek bir gömme uç noktası ya da
  vektör deposu çağrılmaz. Tohum **20260218**.
- **GM32.** Benzetici yüzeyi önce kavrama, kavramı sonra otuz iki boyuta indirir; belge dili ile
  sorgu dili hiçbir belirteç paylaşmaz. Bu dersin bütün ölçümleri alan içi gömmeyle yapılır.
- **GM33.** Taban **tam taramadır**: her sorgu iki yüz belgenin hepsiyle karşılaştırılır ve ilk beş
  sonuç alınır.
- **GM34. Erişim anması** bu derste dizine karşı okunur: dizinin ilk beşi ile tam taramanın ilk
  beşinin kesişiminin beşe oranı. Anma 1,0000 dizinin tabanla **aynı** yanıtı verdiği anlamına
  gelir, doğru yanıtı verdiği anlamına gelmez.
- **GM35. Kavram kesinliği** getirilen beş belgenin sorgunun hedef kavramını taşıma payıdır ve
  tabanın kendi kalitesini gösterir.
- **GM36. Karşılaştırma sayısı** tek bir sorguda hesaplanan açı benzerliği adedidir. Süre
  yazılmaz; dizinin kurulum bedeli ayrıca **saklanan kenar** ya da **temsilci sayısı** olarak
  sayılır.
- **GM37.** Dizin yapıları **davranışlarıyla** anılır: kovalı dizin ve komşuluk çizgesi. Hiçbir
  vektör deposu, kitaplık ya da yöntem adı yazılmaz.
- **GM38.** Kovalı dizinin kurulumu **tohuma bağlıdır**. Bu dersin iki koşumu aynı sorgu kümesinin
  iki ayrı dizin kurulumunda ölçülmesidir; aradaki fark bu iş yükünün **eşiğidir** ve altındaki
  farklar ölçülmemiş sayılır.

En yakın komşu yordamının kendisi Makine Öğrenmesi ve Veri Bilimi müfredatının Denetimsiz Öğrenme
kursunda kuruldu ve ölçüldü; burada tekrarlanmaz. Eklenen tek şey, o yordamın **tamamını
çalıştırmamanın** bedelidir.

#### Tam Taramanın Tabanı

Aşağıdaki blok kurgu dağarcığı ve gömme benzeticisini kurar, sonra tabanı basar. Taban iki sayı
verir: dizinin kaçırdığını ölçeceğimiz sonuç kümesi ve o kümenin **kendi** kalitesi.

```python
# KURGU dagarcik ve KURGU gomme benzeticisi. Gercek bir uc nokta cagrilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


def _kavramla(m):                # yuzey once kavrama cevrilir
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        if KAVRAM[k][1] in dm:
            v[i] += 1.0
        if KAVRAM[k][2] in dm:
            v[i] += 1.0
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT):         # kavram sonra boyuta dusurulur
    v = [0.0] * boyut
    for i, a in enumerate(_kavramla(m)):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


SORGU = []                       # KURGU sorgu kumesi: sorgu dili belge dilinden ayri
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

K = 5
VEK = [gom(metin(d)) for d in BELGE]
QV = [gom(q["metin"]) for q in SORGU]
TABAN = [sorted(range(len(VEK)), key=lambda i: -aci(qv, VEK[i]))[:K] for qv in QV]


def kavram_kesinligi(getirilen):
    d = sum(BELGE[i]["ana"] == SORGU[n]["kavram"]
            for n, g in enumerate(getirilen) for i in g)
    return d / (len(getirilen) * K)


print(f"dagarcik {len(BELGE)} belge , farkli vektor "
      f"{len({tuple(v) for v in VEK})} , sorgu {len(SORGU)}")
print(f"tam tarama: sorgu basina {len(VEK)} karsilastirma , "
      f"toplam {len(VEK) * len(SORGU)}")
print(f"ilk {K} sonucun kavram kesinligi {kavram_kesinligi(TABAN):.4f}")
```

```
dagarcik 200 belge , farkli vektor 52 , sorgu 40
tam tarama: sorgu basina 200 karsilastirma , toplam 8000
ilk 5 sonucun kavram kesinligi 0.4600
```

İkinci satır dizin gerekçesinin tamamıdır: kırk sorgu için sekiz bin açı hesabı. Üçüncü satır ise
tabanın kendisini ölçüyor. Tam tarama, getirdiği beş belgenin ancak 0,4600'ünde sorgunun hedef
kavramını taşıyor. Taban **kusursuz değildir**; dizin bunun üstüne çıkamaz, ancak buna yaklaşır ya
da bundan uzaklaşır.

İlk satırın son sayısı sonraki bölümde işe yarayacak: iki yüz belge var ama yalnız **52 farklı
vektör**. Belgeler kavram kümelerini paylaşıyor, dolayısıyla vektör uzayında üst üste biniyorlar.

#### Kovalı Dizin

Kovalı dizin dağarcığı önceden bölümlere ayırır. Tohumla seçilen bir avuç belge **temsilci**
olur, her belge kendisine en benzeyen temsilcinin kovasına girer. Sorgu geldiğinde önce
temsilcilerle karşılaştırılır, sonra yalnız en yakın **sonda** kadar kovanın içine bakılır.

```python
def kovali_kur(kova, tohum):
    """KURGU kovali dizin: tohumla secilen temsilcilere tek gecislik atama."""
    r, temsil = uretec(tohum), []
    while len(temsil) < kova:
        i = int(r() * len(VEK))
        if i not in temsil:
            temsil.append(i)
    uye = [[] for _ in temsil]
    for i in range(len(VEK)):
        uye[max(range(kova), key=lambda c: aci(VEK[i], VEK[temsil[c]]))].append(i)
    return temsil, uye


def kovali_ara(qv, temsil, uye, sonda, k=K):
    sira = sorted(range(len(temsil)), key=lambda c: -aci(qv, VEK[temsil[c]]))
    aday = [i for c in sira[:sonda] for i in uye[c]]
    return sorted(aday, key=lambda i: -aci(qv, VEK[i]))[:k], len(temsil) + len(aday)


def anma(bulunan, taban):
    return len(set(bulunan) & set(taban)) / len(taban)


def kovali_olc(kova, sonda, tohum=TOHUM):
    temsil, uye = kovali_kur(kova, tohum)
    a = kars = 0
    getirilen = []
    for n, qv in enumerate(QV):
        b, c = kovali_ara(qv, temsil, uye, sonda)
        getirilen.append(b)
        a += anma(b, TABAN[n])
        kars += c
    return a / len(QV), kars / len(QV), kavram_kesinligi(getirilen)


print("kova sonda   anma  karsilastirma  kavram kesinligi")
for kova, sonda in ((8, 1), (16, 1), (16, 2), (16, 4), (25, 2), (25, 4)):
    a, c, kk = kovali_olc(kova, sonda)
    print(f"{kova:>4} {sonda:>5} {a:>6.4f} {c:>14.1f} {kk:>17.4f}")
u = [kovali_olc(16, 2, TOHUM + t)[0] for t in (0, 1)]
print(f"iki kurulum kova=16 sonda=2: {u[0]:.4f} , {u[1]:.4f}"
      f" -- fark {abs(u[0] - u[1]):.4f}")
```

```
kova sonda   anma  karsilastirma  kavram kesinligi
   8     1 0.5600           39.7            0.4150
  16     1 0.7000           34.8            0.3600
  16     2 0.9600           47.2            0.4500
  16     4 1.0000           69.2            0.4600
  25     2 0.9000           45.0            0.4300
  25     4 1.0000           61.6            0.4600
iki kurulum kova=16 sonda=2: 0.9600 , 0.9400 -- fark 0.0200
```

Son satır bu dersin eşiğini veriyor. Aynı sorgu kümesi, aynı ayar, yalnız temsilcileri seçen tohum
farklı: 0,9600 ve 0,9400. Kurulum farkı **0,0200** taşıyor, dolayısıyla tablodaki bu büyüklükteki
farklar ölçülmüş sayılmaz. Kovalı dizin belirlenmiş bir yapı değildir; **hangi belgelerin temsilci
olduğu** sonucu oynatır.

Tablonun ana okuması dört sayıdadır. Kova 16 ve sonda 4'te anma **1,0000**: dizin tam taramanın
verdiği beş belgenin beşini de veriyor ve bunu 200 yerine **69,2** karşılaştırmayla yapıyor.
Sonda 2'ye inince anma 0,9600'e düşer, karşılaştırma 47,2'ye. Aradaki 0,0400 eşiğin iki katıdır,
yani gerçek bir kayıptır; karşılıkta karşılaştırmanın üçte biri kazanılır. Sonda 1'de tablo
kırılır: anma 0,7000 ve karşılaştırma 34,8. Yalnız bir kova daha az okumak, karşılaştırmanın
dörtte birini kazandırıp anmanın dörtte birini götürüyor.

Son sütun bunun yanıtta ne demek olduğunu söylüyor. Tam taramanın kavram kesinliği 0,4600'dü; kova
16 sonda 1'de **0,3600**'e iniyor. Dizin yalnız aday kümesini daraltmıyor, **getirilen belgelerin
doğruluğunu** da düşürüyor. Kaybın anma sütunundaki 0,3000'lik düşüşten küçük görünmesinin nedeni
tabanın zaten yarısından azını doğru getirmesidir: dizin, tabanın kaçırdıklarını kaçırmaya devam
ederken tabanın yakaladıklarının bir kısmını da kaçırır. Bir ölçüde okunmayan bir bedel budur ve
kursun kuralı bu yüzden iki sütun ister.

#### Komşuluk Çizgesi ve Erişilebilirlik

İkinci yapı dağarcığı bölmez, **bağlar**. Her belge kendisine en benzeyen belirli sayıda belgeye
bir kenarla bağlanır; arama bir giriş düğümünden başlar ve komşuları arasında sorguya daha yakın
biri varsa oraya geçer. Karşılaştırma yalnız yürünen yolda yapılır.

```python
def cizge_kur(derece):
    """KURGU komsuluk cizgesi: her belge en benzer 'derece' belgeye baglanir."""
    c = []
    for i in range(len(VEK)):
        s = sorted(range(len(VEK)), key=lambda j: -aci(VEK[i], VEK[j]))
        c.append([j for j in s if j != i][:derece])
    return c


def erisilebilir(cizge, giris=0):
    gor, yigit = {giris}, [giris]
    while yigit:
        for j in cizge[yigit.pop()]:
            if j not in gor:
                gor.add(j)
                yigit.append(j)
    return len(gor)


def cizge_ara(qv, cizge, giris=0, k=K):
    puan, kars, acilan = {giris: aci(qv, VEK[giris])}, 1, set()
    while True:
        bek = [i for i in puan if i not in acilan]
        if not bek or max(puan[i] for i in bek) < max(puan.values()):
            break
        i = max(bek, key=lambda x: puan[x])
        acilan.add(i)
        for j in cizge[i]:
            if j not in puan:
                puan[j] = aci(qv, VEK[j])
                kars += 1
    return sorted(puan, key=lambda x: -puan[x])[:k], kars


print("derece  kenar  erisilebilir   anma  karsilastirma")
for derece in (8, 16, 32, 48):
    cizge = cizge_kur(derece)
    a = kars = 0
    for n, qv in enumerate(QV):
        b, c = cizge_ara(qv, cizge)
        a += anma(b, TABAN[n])
        kars += c
    print(f"{derece:>6} {derece * len(VEK):>6} {erisilebilir(cizge):>13}"
          f" {a / len(QV):>6.4f} {kars / len(QV):>14.1f}")
```

```
derece  kenar  erisilebilir   anma  karsilastirma
     8   1600            27 0.0800           14.0
    16   3200            31 0.1750           26.0
    32   6400           200 0.5250           60.6
    48   9600           200 0.7650           84.7
```

Erişilebilirlik sütunu bu tablonun açıklamasıdır ve hiçbir sorguya bağlı değildir: giriş
düğümünden kenarları izleyerek **kaç belgeye ulaşılabildiğini** sayar. Derece 8'de bu sayı 200
değil **27**'dir. Çizge parçalı; giriş düğümünün bulunduğu bileşen dağarcığın yedide birinden
küçük. Arama ne kadar bütçe alırsa alsın kalan 173 belgeye bakamaz, dolayısıyla anma 0,0800'de
tavan yapar. Bu, aramanın değil **yapının** sayısıdır ve koşumdan bağımsızdır.

Parçalılığın nedeni ilk bloktaki 52 sayısıdır. İki yüz belge yalnız 52 farklı vektöre oturuyor,
yani her belgenin en yakın komşuları kendisiyle **aynı** vektöre sahip belgeler. Derece 8 iken bir
düğümün sekiz komşusunun tamamı kendi ikizidir ve kenarlar o adacığın dışına çıkmaz. Derece 32'de
ikizlerin sayısı aşılıyor, kenarlar başka kavramlara uzanıyor ve erişilebilirlik bir anda 200
oluyor.

Bağlanan çizge bile tabanı yakalayamıyor. Derece 48'de anma **0,7650** ve karşılaştırma **84,7**.
Aynı sorgu kümesinde kovalı dizin, kova 16 ve sonda 2 ile 0,9600 anmayı **47,2** karşılaştırmayla
veriyordu. Çizge hem daha az doğru hem daha pahalı, üstelik 9600 kenar saklıyor; kovalı dizinin
sakladığı ise 16 temsilci ile 200 üyelik kaydı, yani 216 sayıdır. Eklenen düzenek burada işi **iyileştirmiyor**, iki eksende
birden kötüleştiriyor. Yaklaşık komşu aramanın hangi yapıyla kurulacağı bir zevk meselesi değildir;
dağarcığın vektör uzayındaki dağılımı bir yapıyı çalışır, öbürünü çalışmaz kılar. Tekrar eden
belgelerin çok olduğu bir dağarcıkta çizge tıkanır, bölümleme tıkanmaz.

#### Özet

- Tam tarama sorgu başına 200 karşılaştırma ister ve getirdiği beş belgenin 0,4600'ünde hedef
  kavramı taşır; taban kusursuz değildir ve dizin bunun üstüne çıkamaz.
- Kovalı dizin kova 16 sonda 4 ile anmayı 1,0000'de tutup karşılaştırmayı 69,2'ye, sonda 2 ile
  0,9600 anmayla 47,2'ye indirir; sonda 1'de anma 0,7000'e düşer.
- Dizin yalnız aday kümesini değil yanıtı da bozar: kova 16 sonda 1'de ilk beşin kavram kesinliği
  0,4600'den 0,3600'e iner.
- Komşuluk çizgesinde anmanın tavanı **erişilebilirliktir**; derece 8'de giriş düğümünden yalnız 27
  belgeye ulaşılabildiği için anma 0,0800'de kalır ve bu sayı koşumdan bağımsızdır.
- Bağlanmış çizge bile kovalı dizinin altında kalır: derece 48'de 9600 kenar, 84,7 karşılaştırma ve
  0,7650 anma; eklenen düzenek burada iki eksende birden kaybettirir.
- İki dizin kurulumu arasındaki fark 0,0200'dür; bu iş yükünde daha küçük farklar ölçülmemiş
  sayılır.

#### Sonraki Adım

Bu dersin bütün ölçümlerinde sorgu dağarcığın **tamamına** yöneltildi; dizin yalnız o dağarcığın
neresine bakılacağını kısıtladı. Gerçek bir erişim isteği çoğu zaman böyle gelmez: yalnız belirli
bir sınıftaki, belirli bir dönemdeki ya da belirli bir bölgeye ait belgeler istenir. Bu kısıt
vektör aramasının önüne mi arkasına mı konur ve ikisi arasındaki fark nedir. Sonraki ders bir meta
veri süzgecini kovalı dizinle yan yana koyar ve süzgeç seçiciliği arttıkça anmaya ne olduğunu
sayar: dizin bütün dağarcık üzerine kurulduğu için, süzgeç daraldıkça bakılan kovaların içinde
ayakta kalan aday sayısı çöker ve bir noktadan sonra dizinsiz arama dizinliden hem daha doğru hem
daha ucuz hâle gelir.

### Meta Veri Süzme

Source: https://academia.sh/tr/kurslar/rag/meta-veri-suzme

Vektör aramasının bir meta veri kısıtıyla birleştirilmesi ve süzgeç daraldıkça komşuluğun bozulmasının ölçülmesi. İki yüz kurgu belge on altı bölgeye dağıtılıyor; süzgeçsiz kovalı dizin 0,9600 anmayı 47,2 karşılaştırmayla veriyor. Süzgeç aramadan sonra uygulandığında anma 0,4450'ye ve 0,0900'e düşüyor, kırk sorgunun kırkı beş sonuçtan azını döndürüyor; elliye çıkarılmış getirme bunu 0,8700 ve 0,4750'ye çekiyor ama dizin içinde süzmenin tavanını aşamıyor. Dizin içinde süzmede süzgeç genişliği 16'dan 1'e inerken aday sayısı 31,2'den 2,8'e, anma 0,9600'den 0,4750'ye iniyor; karşılaştırma 47,2'den 18,8'e inerken süzülmüş kümenin tam taraması 200'den 18'e iniyor. Genişlik 1'de dizin 18,8 karşılaştırmayla 0,4750, tam tarama 18 karşılaştırmayla 1,0000 veriyor. İki dizin kurulumu arasındaki fark süzgeçsizken 0,0200, süzgeçliyken 0,0950 ile 0,1300 arasında.

Önceki derste sorgu dağarcığın tamamına yöneltildi ve dizin yalnız o dağarcığın neresine
bakılacağını kısıtladı. Erişim isteği çoğu zaman böyle gelmez. Saha ekibi belirli bir bölgenin
kayıtlarını, destek masası belirli bir sınıftaki belgeleri, denetim belirli bir dönemi ister. Bu
kısıt bir benzerlik sorusu değildir; **meta veri** üzerinde tanımlı kesin bir koşuldur ve
sağlanması ya da sağlanmaması ölçü kabul etmez.

İki yordamın birleştirilmesinin tek bir doğru sırası yoktur. Süzgeç vektör aramasından **sonra**
uygulanırsa arama dizinin tamamı üzerinde çalışır ve sonuçların bir kısmı elenir. **Önce**
uygulanırsa arama yalnız eşleşen belgeler üzerinde çalışır, ama dizin bütün dağarcık üzerine
kurulmuştur ve daraltılmış uzayda ne söz verdiği belirsizdir. Bu ders iki sırayı da ölçer ve
üçüncü bir sayıyı yanlarına koyar: süzgeci uygulayıp **dizini hiç kullanmamanın** bedeli. Süzgeç
daraldıkça bu üçüncü seçeneğin hem daha doğru hem daha ucuz hâle geldiği bir nokta çıkar.

- **GM39.** Dağarcık, gömme yordamı, sorgu kümesi ve meta veri katmanı **kurgudur**; gerçek bir
  vektör deposu ya da gömme uç noktası çağrılmaz. Tohum **20260218**.
- **GM40. Meta veri** bu derste tek alandır: her belgeye tohumdan türeyen bir **bölge kodu**
  (1 ile 16 arası) verilir. Süzgeç `bölge <= genişlik` koşuludur; genişlik küçüldükçe süzgeç
  seçicileşir.
- **GM41.** Süzgeç **kesindir**: eşleşmeyen bir belge hiçbir benzerlik değerinde sonuca giremez.
  Bu, benzerlik eşiğinden farklı bir kısıttır.
- **GM42. Doğru yanıt** her genişlikte **süzülmüş kümenin tam taramasıdır**: eşleşen belgelerin
  hepsiyle karşılaştırma ve ilk beş. Anma, yordamın getirdiği kümenin bu beşlikle kesişiminin
  oranıdır; eşleşen belge sayısı beşten azsa payda o sayıdır.
- **GM43. Süzgeç sonrası** yordam dizinden ilk `getir` sonucu alır ve içlerinden eşleşmeyenleri
  atar. **Dizin içinde süzme** aynı kovalara bakar ama eşleşmeyen belgeleri **aday kümesine hiç
  almaz**.
- **GM44.** Dizin önceki derste ölçülen ayarla kurulur: kovalı dizin, 16 kova, 2 sonda. Bu ayar
  süzgeçsiz durumda 0,9600 anma veriyordu ve bu dersin karşılaştırma tabanıdır.
- **GM45. Karşılaştırma sayısı** tek sorguda hesaplanan açı benzerliği adedidir: temsilci sayısı
  artı bakılan aday sayısı. Süzgecin kendisi bir eşitlik sınamasıdır ve bu sayıya girmez.
- **GM46. Aday sayısı** sondalanan kovaların içinde süzgeci geçen belge adedidir; komşuluğun
  bozulması bu sütunda görünür.
- **GM47.** İki koşum aynı sorgu kümesinin **iki ayrı dizin kurulumunda** ölçülmesidir. Önceki
  derste bu fark süzgeçsiz durumda 0,0200 çıkmıştı; bu dersin bir bulgusu farkın süzgeçle birlikte
  büyümesidir.

Süzgeçli sorgunun kendisi Veritabanları müfredatının İleri SQL ile Arama Motorları ve Metin Erişimi
kurslarında kuruldu ve ölçüldü; süzme yordamı burada tekrarlanmaz. Eklenen tek şey, süzgecin
**vektör komşuluğuna** ne yaptığıdır.

#### Süzgecin Daralttığı Uzay

Aşağıdaki blok dağarcığı ve gömme benzeticisini kurar, üstüne meta veri katmanını ekler ve
süzgeçsiz tabanı basar.

```python
# KURGU dagarcik, KURGU gomme benzeticisi ve KURGU meta veri. Gercek uc nokta yok.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


def _kavramla(m):                # yuzey once kavrama cevrilir
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        if KAVRAM[k][1] in dm:
            v[i] += 1.0
        if KAVRAM[k][2] in dm:
            v[i] += 1.0
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT):         # kavram sonra boyuta dusurulur
    v = [0.0] * boyut
    for i, a in enumerate(_kavramla(m)):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


SORGU = []                       # KURGU sorgu kumesi: sorgu dili belge dilinden ayri
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

K, SONDA = 5, 2
GENISLIK = (16, 8, 4, 2, 1)
VEK = [gom(metin(d)) for d in BELGE]
QV = [gom(q["metin"]) for q in SORGU]
BOLGE = [1 + int(uretec(TOHUM ^ (i + 1) * 40503)() * 16) for i in range(len(BELGE))]


def esleseni(g):
    return [i for i in range(len(VEK)) if BOLGE[i] <= g]


def gercek(qv, g, k=K):          # dogru yanit: suzulmus kumenin tam taramasi
    return sorted(esleseni(g), key=lambda i: -aci(qv, VEK[i]))[:k]


def kovali_kur(kova, tohum):
    r, temsil = uretec(tohum), []
    while len(temsil) < kova:
        i = int(r() * len(VEK))
        if i not in temsil:
            temsil.append(i)
    uye = [[] for _ in temsil]
    for i in range(len(VEK)):
        uye[max(range(kova), key=lambda c: aci(VEK[i], VEK[temsil[c]]))].append(i)
    return temsil, uye


def sondalanan(qv, temsil, uye):
    sira = sorted(range(len(temsil)), key=lambda c: -aci(qv, VEK[temsil[c]]))
    return [i for c in sira[:SONDA] for i in uye[c]]


def anma(bulunan, dogru):
    return len(set(bulunan) & set(dogru)) / max(1, len(dogru))


TEMSIL, UYE = kovali_kur(16, TOHUM)
tam = sum(anma(sorted(sondalanan(qv, TEMSIL, UYE),
                      key=lambda i: -aci(qv, VEK[i]))[:K], gercek(qv, 16)) for qv in QV)
print(f"dagarcik {len(BELGE)} belge , 16 bolge , sorgu {len(SORGU)}")
print("suzgec genisligi " + " / ".join(str(g) for g in GENISLIK)
      + " -> eslesen " + " / ".join(str(len(esleseni(g))) for g in GENISLIK))
print(f"suzgecsiz taban: kovali dizin (kova 16 , sonda {SONDA}) anma {tam / len(QV):.4f} , "
      f"{len(TEMSIL) + sum(len(sondalanan(qv, TEMSIL, UYE)) for qv in QV) / len(QV):.1f}"
      f" karsilastirma , tam tarama {len(VEK)}")
```

```
dagarcik 200 belge , 16 bolge , sorgu 40
suzgec genisligi 16 / 8 / 4 / 2 / 1 -> eslesen 200 / 101 / 52 / 27 / 18
suzgecsiz taban: kovali dizin (kova 16 , sonda 2) anma 0.9600 , 47.2 karsilastirma , tam tarama 200
```

Beş genişlik dağarcığı 200'den 18 belgeye kadar daraltıyor. Süzgeçsiz taban önceki dersin
satırıdır: dizin tam taramanın verdiği beşliğin 0,9600'ünü 47,2 karşılaştırmayla getiriyor.
Sorulacak soru şu: bu sayı süzgeç eklendiğinde de geçerli mi.

#### Süzgeci Sonra Uygulamak

En az iş isteyen birleştirme, aramayı hiç değiştirmeden sonucu elemektir. Dizin ilk `getir` kadar
belgeyi verir, eşleşmeyenler atılır, kalanın ilk beşi döndürülür.

```python
def suzgec_sonrasi(qv, g, getir):
    ust = sorted(sondalanan(qv, TEMSIL, UYE), key=lambda i: -aci(qv, VEK[i]))[:getir]
    return [i for i in ust if BOLGE[i] <= g][:K]


print("genislik  anma(getir 5)  eksik sonuc  anma(getir 15)  anma(getir 50)")
for g in GENISLIK[1:]:
    s, eksik = [0.0, 0.0, 0.0], 0
    for qv in QV:
        d = gercek(qv, g)
        for n, getir in enumerate((5, 15, 50)):
            s[n] += anma(suzgec_sonrasi(qv, g, getir), d)
        eksik += len(suzgec_sonrasi(qv, g, 5)) < len(d)
    print(f"{g:>8} {s[0] / len(QV):>14.4f} {eksik:>12} {s[1] / len(QV):>15.4f}"
          f" {s[2] / len(QV):>15.4f}")
```

```
genislik  anma(getir 5)  eksik sonuc  anma(getir 15)  anma(getir 50)
       8         0.4450           37          0.8700          0.8700
       4         0.1950           40          0.6900          0.7700
       2         0.1050           40          0.3850          0.6250
       1         0.0900           40          0.2600          0.4750
```

İlk sütun süzgeçsiz 0,9600'den başlıyordu; genişlik 8'de **0,4450**'ye, genişlik 1'de
**0,0900**'e iniyor. Üçüncü sütun nedeni söylüyor: genişlik 4'ten aşağıda kırk sorgunun
**kırkı** doğru yanıttan daha az sonuç döndürüyor. Dizin beş belge veriyor, süzgeç dördünü ya da
beşini atıyor, geriye ya bir sonuç kalıyor ya hiçbiri. Ortada bir sıralama sorunu yok; sonuç
kutusu **boşalıyor**.

Bilinen çare fazladan getirmektir: beş yerine on beş, elli belge alıp öyle elemek. Son iki sütun
bunun ne kadar işe yaradığını gösteriyor. Genişlik 8'de on beşe çıkmak 0,4450'yi 0,8700'e
taşıyor ve elliye çıkmak **hiçbir şey eklemiyor**. Genişlik 1'de elli belge getirmek ancak
0,4750 veriyor. Fazladan getirme bir tavana çarpıyor ve o tavan bir sonraki bölümün ilk
sütunudur: sondalanan kovaların içinde süzgeci geçen belge sayısı. Elli belge istemek, kovalarda
o kadar uygun belge yoksa elli belge getirmez.

#### Süzgeci Dizinin İçinde Uygulamak

İkinci yordam eşleşmeyen belgeyi aday kümesine hiç almaz. Aynı kovalara bakılır, ama sayılan ve
sıralanan yalnız süzgeci geçenlerdir.

```python
def dizin_icinde(qv, g, temsil, uye):
    aday = [i for i in sondalanan(qv, temsil, uye) if BOLGE[i] <= g]
    return sorted(aday, key=lambda i: -aci(qv, VEK[i]))[:K], len(aday)


IKINCI = kovali_kur(16, TOHUM + 1)
print("genislik  aday  anma  karsilastirma  tam tarama  iki kurulum farki")
for g in GENISLIK:
    a = b = 0.0
    ad = 0
    for qv in QV:
        d = gercek(qv, g)
        r1, n1 = dizin_icinde(qv, g, TEMSIL, UYE)
        a += anma(r1, d)
        b += anma(dizin_icinde(qv, g, *IKINCI)[0], d)
        ad += n1
    print(f"{g:>8} {ad / len(QV):>5.1f} {a / len(QV):>5.4f} "
          f"{len(TEMSIL) + ad / len(QV):>14.1f} {len(esleseni(g)):>11}"
          f" {abs(a - b) / len(QV):>19.4f}")
```

```
genislik  aday  anma  karsilastirma  tam tarama  iki kurulum farki
      16  31.2 0.9600           47.2         200              0.0200
       8  15.7 0.8700           31.6         101              0.1300
       4   7.8 0.7700           23.9          52              0.0950
       2   4.0 0.6250           20.0          27              0.1250
       1   2.8 0.4750           18.8          18              0.1100
```

Aday sütunu komşuluğun bozulmasıdır. Süzgeçsizken dizin sorgu başına 31,2 belge tartıyor;
genişlik 1'de **2,8**. Kovalar dağarcığın tamamı üzerine kurulmuştu ve bir kova, bölgelere göre
değil benzerliğe göre doldu. Süzgeç daraldıkça bir kovanın içinde ayakta kalan belge sayısı
düşüyor ve dizin, beş sonuç seçmesi gereken yerde üç belge arasından seçim yapar duruma geliyor.
Anma 0,9600'den **0,4750**'ye bu yüzden iniyor.

Asıl karar son üç sütunda okunuyor. Karşılaştırma 47,2'den 18,8'e düşerken **tam tarama sütunu**
200'den 18'e düşüyor. Süzgeçsiz durumda dizin tam taramanın dörtte biri kadar iş yapıyordu;
genişlik 1'de **daha çok** iş yapıyor. Genişlik 1 satırı yan yana şu iki şeyi söylüyor: dizin
18,8 karşılaştırmayla 0,4750, süzülmüş kümenin tam taraması 18 karşılaştırmayla 1,0000. Yaklaşık
arama burada hem pahalı hem yanlıştır. Kesişme genişlik 2 ile 1 arasındadır: genişlik 2'de dizin
hâlâ yedi karşılaştırma ucuzdur ama 0,3750 anma bırakır, genişlik 1'de ucuzluğu da biter. Bu
noktanın altında dizini atlayıp eşleşen belgeleri baştan sona taramak her iki eksende kazanır. Eklenen düzeneğin işi
kötüleştirmesi bu dersin ikinci örneğidir ve nedeni dizinin kötü kurulmuş olması değildir:
dizin, **sorgunun soracağı kısıttan habersiz** kurulmuştur.

Son sütun bir de kararsızlık ekliyor. Süzgeçsizken iki dizin kurulumu arasındaki fark 0,0200'dü,
yani önceki dersin eşiği. Süzgeçliyken fark 0,0950 ile 0,1300 arasında, eşiğin beş katı. Aynı
dağarcık, aynı sorgu, aynı ayar; değişen yalnız hangi belgelerin temsilci olduğu. Dar bir süzgeçle
çalışan bir kurulumda ölçülen anma, o kurulumun sayısıdır ve tekrar kurulduğunda taşınmaz.

#### Özet

- Meta veri süzgeci kesin bir kısıttır ve benzerlik eşiğinden farklıdır; eşleşmeyen belge hiçbir
  benzerlik değerinde sonuca giremez.
- Süzgeci aramadan sonra uygulamak sonuç kutusunu boşaltır: genişlik 4 ve altında kırk sorgunun
  kırkı beş sonuçtan azını döndürür ve anma 0,9600'den 0,0900'e iner.
- Fazladan getirme bu kaybı kısmen kapatır ama bir tavana çarpar; genişlik 8'de elli belge
  getirmek on beş belge getirmenin verdiği 0,8700'ün üstüne çıkmaz.
- Dizin içinde süzmede aday sayısı 31,2'den 2,8'e, anma 0,9600'den 0,4750'ye iner; kovalar
  benzerliğe göre doldurulduğu için süzgeç kovanın içini boşaltır.
- Genişlik 1'de dizin 18,8 karşılaştırmayla 0,4750, süzülmüş kümenin tam taraması 18
  karşılaştırmayla 1,0000 verir; eşik genişlik 2 civarındadır ve altında dizin iki eksende birden
  kaybettirir.
- İki dizin kurulumu arasındaki fark süzgeçsizken 0,0200, süzgeçliyken 0,0950 ile 0,1300
  arasındadır; dar süzgeçle ölçülen anma kuruluma bağlıdır.

#### Sonraki Adım

Bu dersin bütün ölçümlerinde sorgu ile belge arasındaki bağ tek bir yerden kuruldu: gömme
vektörlerinin açısı. Süzgeç bu bağı daralttı ama değiştirmedi. Oysa dağarcıkta sorgunun
sözcüklerini birebir taşıyan belgeler de var ve onları bulmak için gömmeye hiç gerek yok; bir
belge kodu, bir tarih ya da bir hata numarası arandığında anlam benzerliği aranan şeyin yanından
geçer. Sonraki ders anahtar sözcük eşleşmesi ile gömme aramasını aynı sorgu kümesinde ayrı ayrı
ölçer, sonra ikisinin sıralarını birleştirir ve birleştirmenin ne kattığını sayar. Beklenen şey
toplamın parçalarından iyi olmasıdır; ölçülen şey bir sorgu sınıfında birleşiğin **ikisinden de**
kötü kalmasıdır.

### Karma Arama

Source: https://academia.sh/tr/kurslar/rag/karma-arama

Anahtar sözcük eşleşmesi ile gömme aramasının ayrı ayrı ve birlikte ölçülmesi. Üç kurgu sorgu sınıfında üç kurulum yan yana koşuluyor: abone dilinde anahtar sözcük 0,0500, gömme 0,5000; belge dilinde ikisi de 0,5000; belge kodu sorgusunda anahtar sözcük 1,0000, gömme 0,0000. Sıra temelli birleştirme belge dili sınıfında 0,4000 veriyor, yani ikisinden de kötü; bu sabit 5, 20 ve 60'ta sürüyor. Kod sınıfında birleştirme hedef belgeyi ilk beşte tutma payını 1,0000'den 0,0500'e düşürüyor. Nedeni iki listenin ilk beşinin ortak belge sayısıdır: abone dilinde 0,20, belge dilinde 1,05. İki listede de ikinci sırada duran bir belge, birinde birinci öbüründe yok olan belgeyi geçiyor. Birleştirme yirminci sıraya kadar anmayı 0,7122'den 0,7209'a çıkarıyor; kazandığı yer derinlik, kaybettiği yer ilk sıradır.

Önceki derste sorgu ile belge arasındaki bağ tek bir yerden kuruldu: gömme vektörlerinin açısı.
Süzgeç bu bağı daralttı, değiştirmedi. Oysa bir destek dağarcığında aranan şey her zaman bir anlam
değildir. Bir belge kodu, bir hata numarası ya da bir yordamın tam adı arandığında sorulan soru
"buna benzer ne var" değil, "bu tam olarak nerede geçiyor" sorusudur. Anlam benzerliği bu sorunun
yanından geçer.

**Karma arama** iki sıralamayı aynı sorgu için birlikte çalıştırıp sonuçlarını tek listede
toplamaktır. Beklenti toplamın parçalarından iyi olmasıdır: gömmenin göremediği tam eşleşmeyi
anahtar sözcük, anahtar sözcüğün göremediği eş anlamı gömme yakalasın. Bu ders üç kurulumu
(yalnız anahtar sözcük, yalnız gömme, birleşik) üç sorgu sınıfında yan yana ölçer. Sonuçlardan
biri beklentiyi karşılamaz: bir sorgu sınıfında birleşik, **iki yordamdan da** kötü kalır.

- **GM48.** Dağarcık, gömme yordamı, belirteçleyici ve sorgu sınıfları **kurgudur**; gerçek bir
  arama motoru, vektör deposu ya da gömme uç noktası çağrılmaz. Tohum **20260218**.
- **GM49.** Belgenin **arama metni** kodu ile birlikte tutulur. Kod bir kavram yüzeyi olmadığı
  için gömme vektörünü değiştirmez; blokta gösterilir.
- **GM50. Üç sorgu sınıfı** aynı belgelerden türetilir ve yalnız yüzeyleri ayrılır: **abone dili**
  sorgu yüzeyini, **belge dili** belge yüzeyini, **kod sorgusu** belge kodunu taşır. Üçü de kırk
  sorgudur.
- **GM51. Anahtar sözcük sıralaması** örtüşen belirteç sayısıdır. İlgililik puanlaması
  Veritabanları müfredatının Arama Motorları ve Metin Erişimi kursunda kuruldu ve ölçüldü; burada
  tekrarlanmaz. Bu derste anahtar sözcük tarafının tek işlevi **ikinci bir sıralama** üretmektir.
- **GM52. Birleştirme sıra temellidir**: bir belgenin puanı iki listedeki sırasının tersleri
  toplamıdır, `1 / (sabit + sıra)`. Sabit varsayılan olarak 20'dir ve 5 ile 60'ta da sınanır.
- **GM53. İlk sıra isabeti** ilk sonucun hedef kavramı taşıma payı, **erişim kesinliği** ilk beş
  sonucun aynı payı, **erişim anması** hedef kavramı taşıyan belgelerin ilk yirmide yakalanma
  payıdır. **Hedef belge** sütunu sorgunun türetildiği belgenin ilk beşte olma payıdır.
- **GM54.** Her kavramı birden çok belge taşır; bu yüzden kesinlik ve anma farklı derinliklerde
  okunur ve tek sayıya indirilmez.
- **GM55.** Üç sıralama da **belirlenmiştir**: aynı sorgu iki koşumda aynı listeyi verir. Bu dersin
  koşumdan bağımsız ölçüsü **iki listenin ilk beşindeki ortak belge sayısıdır** ve sorgudan
  bağımsız olarak yordam çiftinin bir özelliğidir.
- **GM56.** Hiçbir kavram yüzeyi taşımayan bir sorgu **sıfır vektör** üretir; bütün benzerlikler
  sıfır olur ve sıra saklama sırasına düşer. Bu bir kusur değil, gömmenin tanım alanının dışına
  çıkmasıdır ve kod sınıfında ölçülür.
- **GM57.** Bu ders konunun kapanışıdır; getirilen parçanın modele ne yaptığı ölçülmez, sonraki
  konuya bırakılır.

#### Üç Sorgu Sınıfı

```python
# KURGU dagarcik, KURGU gomme benzeticisi, KURGU sorgu siniflari. Gercek uc nokta yok.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):               # KURGU belirtecleyici, parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


def _kavramla(m):                # yuzey once kavrama cevrilir
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        if KAVRAM[k][1] in dm:
            v[i] += 1.0
        if KAVRAM[k][2] in dm:
            v[i] += 1.0
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT):         # kavram sonra boyuta dusurulur
    v = [0.0] * boyut
    for i, a in enumerate(_kavramla(m)):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


K, SABIT = 5, 20
ARAMA = [d["kod"] + " " + metin(d) for d in BELGE]   # kod belgenin arama metnine girer
VEK = [gom(a) for a in ARAMA]
BEL = [set(belirtecle(a)) for a in ARAMA]


def sorgular(kip):               # ayni belgelerden uc ayri yuzey
    q = []
    for i in range(40):
        r = uretec(TOHUM + 104729 * i)
        d = BELGE[int(r() * len(BELGE))]
        o = ORTAK[int(r() * len(ORTAK))]
        q.append({"metin": {"abone": f"{KAVRAM[d['ana']][2]} {o}",
                            "belge": f"{KAVRAM[d['ana']][1]} {o}",
                            "kod": f"{d['kod']} numarali belge"}[kip],
                  "kavram": d["ana"], "kod": d["kod"]})
    return q


SINIFLAR = {k: sorgular(k) for k in ("abone", "belge", "kod")}


def anahtar_sira(m):             # ortusen belirtec sayisina gore
    qb = set(belirtecle(m))
    return sorted(range(len(BELGE)), key=lambda i: -len(qb & BEL[i]))


def gomme_sira(m):
    qv = gom(m)
    return sorted(range(len(BELGE)), key=lambda i: -aci(qv, VEK[i]))


def birlesik_sira(m, sabit=SABIT):   # sira temelli birlestirme
    pa = {i: 1.0 / (sabit + n) for n, i in enumerate(anahtar_sira(m))}
    pg = {i: 1.0 / (sabit + n) for n, i in enumerate(gomme_sira(m))}
    return sorted(range(len(BELGE)), key=lambda i: -(pa[i] + pg[i]))


for k, s in SINIFLAR.items():
    print(f"{k:6s} ornek sorgu: {s[0]['metin']}")
print(f"belge kodu gommeyi degistirmiyor: "
      f"{gom(ARAMA[0]) == gom(metin(BELGE[0]))} , kod sorgusunun vektor uzunlugu "
      f"{sum(x * x for x in gom(SINIFLAR['kod'][0]['metin'])):.1f}")
```

```
abone  ornek sorgu: nasil kaydediliyor form
belge  ornek sorgu: okuma yordami form
kod    ornek sorgu: SY194 numarali belge
belge kodu gommeyi degistirmiyor: True , kod sorgusunun vektor uzunlugu 0.0
```

Üç sorgu aynı belgeden türedi ve aynı şeyi soruyor; ayrıldıkları yer yalnız yüzey. Son satır iki
şeyi ölçüyor. Belge kodunun arama metnine eklenmesi gömme vektörünü **değiştirmiyor**: kod bir
kavram yüzeyi değil, dolayısıyla gömme onu görmüyor. İkincisi daha sert: kod sorgusunun vektör
uzunluğu **0,0**. Sorguda tanınan hiçbir kavram olmadığı için vektör sıfırdır, bütün açı
benzerlikleri sıfır çıkar ve sıralama saklama sırasına düşer. Gömme bu sorguda yanılmıyor,
**tanım alanının dışında** kalıyor.

#### Üç Kurulumun Tablosu

```python
def olc(S, sirala):
    ilk = kes = an = hed = 0.0
    for q in S:
        ilgili = {i for i, d in enumerate(BELGE) if d["ana"] == q["kavram"]}
        s = sirala(q["metin"])
        ilk += s[0] in ilgili
        kes += len(set(s[:K]) & ilgili) / K
        an += len(set(s[:20]) & ilgili) / len(ilgili)
        hed += any(BELGE[i]["kod"] == q["kod"] for i in s[:K])
    return [x / len(S) for x in (ilk, kes, an, hed)]


YORDAM = (("anahtar", anahtar_sira), ("gomme", gomme_sira), ("birlesik", birlesik_sira))
print("sinif  yordam     ilk1  kesinlik@5  anma@20  hedef belge@5")
for kip, S in SINIFLAR.items():
    for ad, f in YORDAM:
        d = olc(S, f)
        print(f"{kip:6s} {ad:8s} {d[0]:>6.4f} {d[1]:>11.4f} {d[2]:>8.4f} {d[3]:>15.4f}")
print("belge dili sinifinda birlesigin ilk1 degeri , sabit 5 / 20 / 60: "
      + " / ".join(f"{olc(SINIFLAR['belge'], lambda m, c=c: birlesik_sira(m, c))[0]:.4f}"
                   for c in (5, 20, 60)))
```

```
sinif  yordam     ilk1  kesinlik@5  anma@20  hedef belge@5
abone  anahtar  0.0500      0.1200   0.1183          0.0500
abone  gomme    0.5000      0.4600   0.7014          0.1500
abone  birlesik 0.4500      0.2800   0.4472          0.1250
belge  anahtar  0.5000      0.3650   0.6722          0.1750
belge  gomme    0.5000      0.4700   0.7122          0.1500
belge  birlesik 0.4000      0.4250   0.7209          0.1250
kod    anahtar  1.0000      0.2500   0.1950          1.0000
kod    gomme    0.0000      0.0800   0.1078          0.0250
kod    birlesik 0.0000      0.0850   0.1950          0.0500
belge dili sinifinda birlesigin ilk1 degeri , sabit 5 / 20 / 60: 0.4500 / 0.4000 / 0.4000
```

İlk iki üçlü karma aramanın gerekçesini kuruyor. Abone dilinde anahtar sözcük 0,0500, gömme
0,5000; kod sorgusunda anahtar sözcük **1,0000**, gömme **0,0000**. İki yordam aynı dağarcıkta
birbirinin tam tersi yerlerde çalışıyor ve tek bir yordam seçmek sorgu sınıflarından birini
tamamen feda etmek demek.

Birleşik satırlar bu feragatin ortadan kalkmadığını gösteriyor. Abone dilinde birleşik 0,4500 ile
gömmenin biraz altında; beklenen bedel budur. Belge dilinde ise iki yordam da 0,5000 verirken
birleşik **0,4000**. Toplam, iki parçasının **ikisinden de** kötü. Son satır bunun bir sabit
seçiminin oyunu olmadığını söylüyor: 5, 20 ve 60'ta 0,4500 / 0,4000 / 0,4000, üçü de 0,5000'in
altında.

Kod sınıfı en pahalı satırdır. Anahtar sözcük hedef belgeyi kırk sorgunun kırkında ilk beşe
sokuyor; birleşik bunu **0,0500**'e düşürüyor. Karma aramanın var olma gerekçesi olan sorgu
sınıfında, birleştirme çalışan yordamı çalışmayanla birlikte batırıyor. Sebep tablonun kendi
içinde: gömme tarafı bu sınıfta sıfır vektörle çalışıyor ve ürettiği sıra bilgi taşımıyor, ama
birleştirme bunu bilmiyor ve o sıraya **eşit ağırlık** veriyor.

Bir sütun ters yöne bakıyor. Belge dilinde anma@20 anahtar sözcükte 0,6722, gömmede 0,7122,
birleşikte **0,7209**. Yirminci sıraya kadar birleştirme gerçekten kazandırıyor. Kod sınıfında da
anma@20 0,1078'den 0,1950'ye çıkıyor. Birleştirmenin kazandığı yer **derinliktir**, kaybettiği yer
**ilk sıradır** ve bir erişim hattında isteme giren şey ilk birkaç parçadır.

#### Birleştirmenin Kaybettirdiği

```python
print("sinif  ilk besin ortak belgesi  ikisi dogru birlesik yanlis")
for kip, S in SINIFLAR.items():
    ortak = kayip = 0
    for q in S:
        ilgili = {i for i, d in enumerate(BELGE) if d["ana"] == q["kavram"]}
        a, g, b = (f(q["metin"]) for _, f in YORDAM)
        ortak += len(set(a[:K]) & set(g[:K]))
        kayip += a[0] in ilgili and g[0] in ilgili and b[0] not in ilgili
    print(f"{kip:6s} {ortak / len(S):>22.2f} {kayip:>28}")

def ilgilisi(q):
    return {i for i, d in enumerate(BELGE) if d["ana"] == q["kavram"]}


q = next(x for x in SINIFLAR["belge"]
         if anahtar_sira(x["metin"])[0] in ilgilisi(x)
         and gomme_sira(x["metin"])[0] in ilgilisi(x)
         and birlesik_sira(x["metin"])[0] not in ilgilisi(x))
print(f"\nsorgu: {q['metin']}  --  hedef kavram: {q['kavram']}")
for ad, f in YORDAM:
    print(f"  {ad:8s}", [f"{BELGE[i]['kod']}/{BELGE[i]['ana']}" for i in f(q["metin"])[:3]])
```

```
sinif  ilk besin ortak belgesi  ikisi dogru birlesik yanlis
abone                    0.20                            1
belge                    1.05                            3
kod                      4.03                            0

sorgu: basinc dususu bolge  --  hedef kavram: basinc
  anahtar  ['AR002/basinc', 'AR015/ekip', 'AR018/basinc']
  gomme    ['AR079/basinc', 'AR088/basinc', 'AR101/ekip']
  birlesik ['AR033/ekip', 'AR015/ekip', 'AR018/basinc']
```

Ortak belge sütunu hiçbir sorguya değil, yordam çiftinin kendisine ait bir sayıdır ve koşumdan
bağımsızdır. Abone dilinde iki listenin ilk beşi ortalama **0,20** belge paylaşıyor: yordamlar
neredeyse hiç anlaşmıyor. Belge dilinde 1,05, yani beşte bir.

Örnek bu sayının sonucunu gösteriyor. Anahtar sözcük AR002'yi, gömme AR079'u ilk sıraya koyuyor;
ikisi de hedef kavramı taşıyor, yani **iki yordam da doğru**. Birleşik ilk sıraya AR033'ü koyuyor
ve o belge `ekip` kavramına ait. AR002 bir listede birinci, öbüründe çok geride; puanı tek bir
büyük terimden geliyor. AR033 ise iki listede de üst sıralarda ama hiçbirinde birinci değil ve
iki orta terimin toplamı bir büyük terimi geçiyor. Sıra temelli birleştirme **uzlaşma belgesini**
ödüllendirir; iki taraf aynı fikirde değilken ikisinin de ikinci tercihi kazanır. Belge dili
sınıfında bu kırk sorgunun üçünde oluyor ve ters yönde hiç olmuyor: birleşiğin, iki yordamın da
yanıldığı bir sorguda doğruyu bulduğu tek bir örnek yok. İlk sıradaki dört sorguluk düşüşün
karşılığı sıfır kazançtır.

Kod satırındaki 4,03 tuzaktır. Yüksek örtüşme burada anlaşma değildir: gömme tarafı sıfır
vektörle çalıştığı için listesi saklama sırasıdır, anahtar sözcük tarafının tam eşleşmeden sonraki
kuyruğu da aynı sıradır. İki liste **aynı bilgisiz kuyruğu** paylaşıyor. Birleştirme, iki listenin
aynı olmasıyla ikisinin de boş olmasını ayırt edemez; ayırt edebilseydi bu sınıfta anahtar sözcüğe
tam ağırlık verirdi. Karma arama bir ortalama değil, bir **karar** ister: hangi sorguda hangi
tarafın söz sahibi olduğu.

#### Özet

- Üç sorgu sınıfında iki yordam birbirinin tersi yerlerde çalışır: abone dilinde anahtar sözcük
  0,0500 ve gömme 0,5000, kod sorgusunda anahtar sözcük 1,0000 ve gömme 0,0000.
- Kavram yüzeyi taşımayan bir sorgu sıfır vektör üretir; gömme yanılmaz, tanım alanının dışına
  çıkar ve sıralaması saklama sırasına düşer.
- Belge dili sınıfında iki yordam da 0,5000 verirken sıra temelli birleştirme 0,4000 verir;
  birleşik ikisinden de kötüdür ve bu sabit 5, 20 ve 60'ta sürer.
- Nedeni iki listenin ilk beşinin 1,05 belge paylaşmasıdır: iki listede de ikinci sırada duran
  uzlaşma belgesi, birinde birinci olup öbüründe bulunmayan belgeyi geçer.
- Kod sınıfında birleştirme hedef belgenin ilk beşte olma payını 1,0000'den 0,0500'e düşürür;
  bilgisiz bir listeye eşit ağırlık vermek çalışan yordamı da batırır.
- Birleştirme derinlikte kazandırır: belge dilinde anma@20 0,7122'den 0,7209'a çıkar. Kazanç
  yirminci sırada, kayıp ilk sıradadır ve isteme giren ilk sıradır.

#### Sonraki Adım

Altı ders boyunca tek bir soru soruldu ve her seferinde daha iyi cevaplandı: dağarcıktaki hangi
parça bu sorguya ait. Gömme bir arama anahtarı oldu, alan uyumu ölçüldü, benzerlik ölçütü seçildi,
dizinin kaybettirdiği sayıldı, süzgecin komşuluğu bozduğu nokta bulundu ve iki sıralamanın
birleşimi tartıldı. Bu derslerin hepsi **erişim** tarafındadır ve hepsinin ölçüsü getirilen
parçanın kendisidir.

Ölçülmeyen şey bundan sonra olandır. Bulunan parça bir isteme konur ve bir modele verilir; o
noktadan itibaren doğru parçanın doğru yanıt ürettiği bir varsayımdır ve bu konuda hiç
sınanmadı. Doğru parça getirildiği hâlde yanlış yanıt üretilebilir, yanlış parça getirildiği hâlde
model şans eseri doğru yanıt verebilir ve en kötüsü, getirilen parça modelin erişimsiz hâlinden
**daha kötü** bir yanıt üretmesine yol açabilir. Sonraki konu erişim hattını baştan sona kurar ve
ilk dersinde iki sütunu ayırır: doğru parça getirildi mi ve getirilenle doğru yanıt üretildi mi.

## Erişim Hattı

Getirilen parçanın modele ne yaptığının ve hattın her adımının kendi bedelinin sayılması: erişimsiz taban, erişimli ve yanlış parçalı üç koşumun karşılaştırılması ve yanlış parçalı koşumun tabanın altına düşmesi, belge hazırlığının erişim anmasına kattığı ile hazırlığın attığı bilgi, parça boyutu ve örtüşme arttıkça yükselen anma ile katlanan parça sayısı ve belirteç, yenileme aralığı uzadıkça büyüyen bayatlık payı ve yeniden gömülen parça sayısı, tek adımlı sorgu dönüştürmenin eklediği çağrı ile kısa sorguda kazandırıp uzun sorguda kaybettirdiği, yeniden sıralamanın ilk k kesinliğine kattığı ile büyüyen aday sayısı ve gecikme sınıfı, bağlam sınırına sığan parça sayısı ile aynı parçaların farklı sırada verilmesinin değiştirdiği yanıt payı, doğru parça ile doğru yanıtın dört durumlu tablosu ve tek sayının bu dördünü gizlemesi, bilgi tazeliği, biçim uyumu ve alan dili görevlerinde erişim ile ince ayarın kattığı, tablo taşıyan kaynağın satır bazlı ve blok bazlı parçalanmasının anmaya yaptığı.

### Erişim Artırılmış Üretim Nedir

Source: https://academia.sh/tr/kurslar/rag/erisim-artirilmis-uretim-nedir

İki yüz belgelik kurgu bir dağarcıkta aynı kırk sorgunun üç kurulumda koşturulması ve erişim ile üretimin iki ayrı sütun olarak basılması: erişimsiz taban üretimde 0,1750 tutarken alan içi gömmeyle kurulan hat erişim anmasını 0,9500'e, üretimi 0,9250'ye çıkarıyor, alan dışı gömmeyle kurulan aynı hat ise anmayı 0,1750'de bırakıp üretimi 0,0500'e, yani tabanın altına düşürüyor. Bedel yan yana yazılıyor: 3174 belirteçten 5343 belirtece, sıfır erişim adımından yirmi yedi bin yedi yüz yirmi adıma, doğru yanıt başına 453,4 belirteçten 144,4 belirtece ve yanlış parçalı kurulumda 2706,5 belirtece. Altı tohumun koşumu bu iş yükünün eşiğini 0,0750 olarak veriyor ve doğru parça gelen otuz sekiz sorgunun biri yine de yanlış yanıtlanıyor.

Önceki konunun altı dersi tek bir işi yaptı: bir sorguya karşılık dağarcıktan bir parça buldu.
Gömme bir arama anahtarı olarak kuruldu, alan uyumunun kaybı ölçüldü, benzerlik ölçütü seçildi,
tam taramanın yerine dizinli arama kondu, meta veri süzgeci eklendi ve iki sıralama birleştirildi.
Altısında da ölçü aynı yerdeydi: getirilen parça doğru muydu.

Sorulmayan şey, o parçanın modele verildiğinde ne yaptığıdır. **Erişim artırılmış üretim**,
dağarcıktan seçilen parçaları isteme koyup modeli o parçalarla çağırmaktır. Bu dersin kurduğu
kural on altı ders boyunca sürer: **erişim ile üretim ayrı ölçülür.** İkisi tek sayıya
indirildiğinde hangi aşamanın bozduğu görünmez.

- **EH1.** Kod bir **benzeticidir**; gerçek bir gömme ya da model uç noktası çağrılmaz. Dağarcık,
  kavram ekseni ve sorgular **kurgudur**, tohum **20260218**.
- **EH2.** Gömmenin tanımı, açı benzerliği ve komşuluk M27/K06'nın doğal dil işleme kursunda
  ölçüldü ve **tekrarlanmaz**. Burada gömme yalnız bir **arama anahtarıdır**.
- **EH3.** Her kavramın **belge dilinde** bir yüzeyi (`kademe esigi`), **sorgu dilinde** başka bir
  yüzeyi (`hangi dilimdeyim`) vardır ve ikisi hiçbir belirteç paylaşmaz: abonenin sorduğu sözcükle
  kaydın yazıldığı sözcük aynı değildir.
- **EH4.** Benzeticinin iç izi **belge dilini** tanır, sorgu dilinin ise yalnız yedi kavramlık
  bölümünü tanır. Erişimsiz tabanın tek kaynağı budur.
- **EH5.** Erişim birimi bu derste kaynağın **kendi paragraf sınırıdır** ve buna **parça** denir;
  sınırın bir karar olduğu üçüncü derste ölçülür.
- **EH6.** **Erişim anması**, hedef kavramı taşıyan en az bir parçanın ilk üçte bulunma payıdır;
  **erişim kesinliği**, ilk üçteki hedef kavramlı parçaların oranı; **sınıf isabeti** ilk üçün
  hedef sınıftan gelme oranı. Sınıf isabeti kolay ölçüttür, kavram isabeti zor olandır.
- **EH7.** **Üretim ölçüsü**, yanıtın hedef kavramı adıyla vermesidir ve erişim ölçüsüyle aynı
  sütunda toplanmaz. Hız sınırı çağrı sayısına bağlıdır: kırk çağrının otuz yedincisi boş döner,
  üç kurulumda da aynı yerde olduğu için karşılaştırmayı bozmaz.

#### Dağarcık ve Ölçü Birimi

Aşağıdaki blok kurgu dağarcığı, kavram ekseni, gömme benzeticisi ve sorgu kümesini kurar. Yirmi
kavramın her biri bir sınıfa bağlıdır ve iki yüzeyle yazılır.

```python
# KURGUDUR. Asagidaki dagarcik, kavram ekseni ve gomme bir benzeticidir; gercek bir
# gomme uc noktasi cagrilmaz. Tohum 20260218.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# ---- parca: bu derste birim, kaynagin kendi paragraf siniridir
PARCA = [{"kod": d["kod"], "sinif": d["sinif"], "metin": p,
          "kavram": [k for k in ANAHTAR if KAVRAM[k][1] in p]}
         for d in BELGE for p in d["par"]]

print("belge %d  parca %d  kavram %d  sorgu %d  parca basina %.1f belirtec"
      % (len(BELGE), len(PARCA), len(ANAHTAR), len(SORGU),
         sum(len(belirtecle(x["metin"])) for x in PARCA) / len(PARCA)))
print("sinif", {s: sum(d["sinif"] == s for d in BELGE) for s in SINIF})
```

```
belge 200  parca 693  kavram 20  sorgu 40  parca basina 16.3 belirtec
sinif {'tarife': 52, 'ariza': 46, 'sayac': 39, 'kesinti': 32, 'bakim': 31}
```

Ölçek buradan okunur: altı yüz doksan üç parça, parça başına on altı belirteç. Bir sorgunun yanıtı
on bin belirteçlik yığının içindedir ve bağlam penceresine sığan şey bunun yüzde biri kadardır.

#### Üç Kurulum

İkinci blok dil modeli benzeticisini kurar ve aynı kırk sorguyu üç kurulumda koşturur. Benzetici
M28/K01'de kurulan aileden gelir: belirteç sayar, bağlam penceresi ve durdurma koşulu taşır, hız
sınırına takılabilir, aynı istemi aynı tohumla çağırdığında aynı yanıtı verir. Tek uyarlama yanıt
uzayıdır: model yirmi kavramdan birini yazar.

**Erişimsiz taban** modeli yalnız sorguyla çağırır. **Erişimli** kurulum alan içi gömmeyle en
yakın üç parçayı isteme koyar. **Yanlış parçalı** kurulum aynı hattı alan dışı bir gömmeyle kurar
ve elle bozulmuş bir düzenek değildir: sorgu dilini tanımayan bir gömme seçildiğinde ortaya çıkan
hattın kendisidir.

```python
import math
# ---- KURGU dil modeli benzeticisi: yanit uzayi yirmi kavram
PENCERE, EN_UZUN = 240, 24
ON_BILGI = {"sizinti", "basinc", "sure", "degisim", "vana", "duyuru", "gecis"}
SERBEST = ["talep {k} kavramina baglandi ve kayda gecti",
           "{k} kaydi olusturuldu ilgili birime iletildi",
           "kaydiniz alindi ilgili birim donus yapacak"]
SAYAC = [0]


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    b = belirtecle(istem)
    if len(b) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(b), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:                               # hiz siniri cagri sayisina bagli
        return {"durum": "hiz_siniri", "giris": len(b), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    dm = " " + istem.lower() + " "
    p = {k: 0.15 for k in ANAHTAR}
    for k in ANAHTAR:
        p[k] += 2.0 * dm.count(KAVRAM[k][1])             # belge dilini model taniyor
        if k in ON_BILGI and KAVRAM[k][2] in dm:
            p[k] += 2.0                                  # sorgu dilinin bilinen payi
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])
    else:
        w = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [x / sum(w) for x in w])]
    y = k if "tek" in b else SERBEST[int(r() * 3)].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:
        cb, y = cb[:en_uzun], " ".join(cb[:en_uzun])
    return {"durum": "tamam", "giris": len(b), "cikis": len(cb), "yanit": y}


def oku(y):
    return next((s for s in y.split() if s in ANAHTAR), None)


YONERGE = ("Talebi su kavramlardan birine bagla: " + " , ".join(ANAHTAR) +
           " . Yanit olarak tek kavram yaz . ")
VEK = {True: [gom(x["metin"]) for x in PARCA],
       False: [gom(x["metin"], alan=False) for x in PARCA]}


def kosum(kip, tohum=TOHUM, k=3):
    SAYAC[0] = 0
    anma = kes = snf = dog = gir = cik = 0
    for s in SORGU:
        if kip == "erisimsiz":
            istem = YONERGE + "Talep: " + s["metin"]
        else:
            alan = kip == "erisimli"
            v = gom(s["metin"], alan=alan)
            ug = sorted(range(len(PARCA)), key=lambda i: -aci(v, VEK[alan][i]))[:k]
            istem = (YONERGE + "Kaynak: " + " . ".join(PARCA[i]["metin"] for i in ug) +
                     " . Talep: " + s["metin"])
            h = [s["kavram"] in PARCA[i]["kavram"] for i in ug]
            anma += any(h)
            kes += sum(h) / k
            snf += sum(PARCA[i]["sinif"] == s["sinif"] for i in ug) / k
        y = cagir(istem, tohum)
        gir, cik = gir + y["giris"], cik + y["cikis"]
        dog += oku(y["yanit"]) == s["kavram"]
    n = len(SORGU)
    return {"anma": anma / n, "kes": kes / n, "snf": snf / n, "uretim": dog / n,
            "bel": gir + cik, "parca": 0 if kip == "erisimsiz" else k * n,
            "adim": 0 if kip == "erisimsiz" else len(PARCA) * n, "dogru": dog}


print("kurulum        ERISIM: anma kesinlik  sinif  URETIM  BEDEL: belirtec parca"
      "   adim  belirtec/dogru")
for kip in ("erisimsiz", "erisimli", "yanlis parca"):
    a = kosum("yanlis" if kip.startswith("yanlis") else kip)
    e = ("       -        -      -" if kip == "erisimsiz"
         else "  %.4f   %.4f %.4f" % (a["anma"], a["kes"], a["snf"]))
    print("%-13s%s  %.4f          %6d %5d %6d %14.1f"
          % (kip, e, a["uretim"], a["bel"], a["parca"], a["adim"],
             a["bel"] / a["dogru"]))
```

```
kurulum        ERISIM: anma kesinlik  sinif  URETIM  BEDEL: belirtec parca   adim  belirtec/dogru
erisimsiz           -        -      -  0.1750            3174     0      0          453.4
erisimli       0.9500   0.9500 0.9500  0.9250            5343   120  27720          144.4
yanlis parca   0.1750   0.1750 0.2500  0.0500            5413   120  27720         2706.5
```

#### Tablonun Üç Okuması

Birinci okuma erişimin ne kattığıdır. Erişimsiz taban **0,1750**'dir: kırk sorgunun yedisi doğru
ve o yedisi benzeticinin sorgu dilinden tanıdığı kavramlara denk gelenlerdir. Alan içi gömmeyle
kurulan hat üretimi **0,9250**'ye çıkarıyor; fark **+0,7500**, yani otuz sorgu.

İkinci okuma bedeldir. Toplam belirteç **3174'ten 5343'e** çıkıyor (1,68 kat), her sorgu için üç
parça getiriliyor ve dağarcığın tamamı taranıyor: sorgu başına altı yüz doksan üç karşılaştırma,
kırk sorguda **27720 erişim adımı**. Bu adım bir model çağrısı değildir ama bedavaya da gelmez.
Doğru yanıt başına okunduğunda hesap tersine döner: **453,4 belirteçten 144,4 belirtece**.

Üçüncü okuma bu kursun ikinci iddiasıdır: **erişim de bozar.** Yanlış parçalı kurulum tabandan
**daha çok** belirteç harcıyor (5413) ve üretimi **0,0500**'e, yani tabanın **0,1750**'sinin
altına düşürüyor. Getirilen parçalar belge dilinde yazılmıştır ve model belge dilini tanır, bu
yüzden yanlış kavramları **güvenle** okur; erişimsiz modelin belirsiz tahmini, yanlış kaynağın
kesin yanlışına dönüşüyor. Doğru yanıt başına bedel **2706,5 belirtece** çıkıyor.

Erişim sütunu da iki sayıyla okunur: alan dışı kurulumda sınıf isabeti **0,2500**, yani beş sınıf
arasından rastgele seçim düzeyinde, kavram isabeti **0,1750**. Tek bir isabet sayısı basılsaydı
hangi ölçütün konuşulduğu belirsiz kalırdı.

#### Eşik ve İki Sütunun Ayrılması

Bir fark ancak koşum değişkenliğinden büyükse fark sayılır. Bu eşik M28/K03'te kendi iş yükünde
ölçülmüştü; bu kurs onu **devralmaz**. Üçüncü blok aynı üç kurulumu altı tohumla koşturur ve
ardından erişim ile üretim sütunlarının ayrıldığı yeri sayar.

```python
print("kurulum        alti tohumun uretim isabeti                         yayilim")
esik = 0.0
for kip in ("erisimsiz", "erisimli", "yanlis"):
    v = [kosum(kip, TOHUM + i)["uretim"] for i in range(6)]
    esik = max(esik, max(v) - min(v))
    print("%-13s %s   %.4f" % (kip, " ".join("%.4f" % x for x in v), max(v) - min(v)))
print("bu kursun esigi %.4f  (kirk sorgunun %d'i)" % (esik, round(esik * 40)))

SAYAC[0] = 0
gd = gy = 0
for s in SORGU:
    v = gom(s["metin"])
    ug = sorted(range(len(PARCA)), key=lambda i: -aci(v, VEK[True][i]))[:3]
    if not any(s["kavram"] in PARCA[i]["kavram"] for i in ug):
        continue
    istem = (YONERGE + "Kaynak: " + " . ".join(PARCA[i]["metin"] for i in ug) +
             " . Talep: " + s["metin"])
    d = oku(cagir(istem)["yanit"]) == s["kavram"]
    gd, gy = gd + d, gy + (not d)
print("dogru parca gelen %d sorgu: %d dogru yanit, %d yanlis yanit" % (gd + gy, gd, gy))
```

```
kurulum        alti tohumun uretim isabeti                         yayilim
erisimsiz     0.1750 0.2250 0.2250 0.2000 0.2250 0.1500   0.0750
erisimli      0.9250 0.9250 0.9250 0.9250 0.9250 0.9250   0.0000
yanlis        0.0500 0.0500 0.0750 0.0750 0.1000 0.0500   0.0500
bu kursun esigi 0.0750  (kirk sorgunun 3'i)
dogru parca gelen 38 sorgu: 37 dogru yanit, 1 yanlis yanit
```

Bu kursun eşiği **0,0750**'dir: kırk sorgunun üçü. Bundan küçük bir üretim farkı bu iş yükünde
**ölçülmemiş** sayılır. Yayılım kurulumdan kuruluma da değişiyor: erişimsiz tabanda 0,0750,
erişimli hatta **0,0000**. Kaynak verilmiş bir modelin çıktısı tohuma bağlı kalmıyor, çünkü doğru
kavram öbürlerinin çok üstünde puan alıyor. Belirsizlik bilginin olmadığı yerde büyür; erişimin az
yazılan ikinci kazancı budur.

Erişim ölçüsü ise tohumdan bağımsızdır, çünkü gömme ve sıralama belirlenimlidir. Eşik bu yüzden
yalnız **üretim** sütununa uygulanır. İki sütunu ayrı tutmanın karşılığı son satırdır: doğru parça
gelen **otuz sekiz** sorgunun otuz yedisi doğru yanıtlanıyor, **biri** yanlış. O sorguda arıza
üretim aşamasındadır; tek bir sayı basılsaydı bu sorgu, parçayı getiremeyen iki sorguyla aynı
kutuya düşerdi.

#### Özet

- Erişim artırılmış üretim, dağarcıktan seçilen parçaların isteme konup modelin o parçalarla
  çağrılmasıdır; kursun kuralı, erişim ile üretimin **ayrı ölçülmesidir**.
- Aynı kırk sorguda erişimsiz taban 0,1750, alan içi gömmeyle kurulan hat 0,9250 üretim veriyor.
- Bedel yazılmadan kazanç okunmaz: toplam belirteç 3174'ten 5343'e çıkıyor, sorgu başına üç parça
  ve 693 karşılaştırma ekleniyor; doğru yanıt başına belirteç ise 453,4'ten 144,4'e iniyor.
- Alan dışı gömmeyle kurulan aynı hat üretimi 0,0500'e, yani erişimsiz tabanın **altına**
  düşürüyor ve bunu daha çok belirteç harcayarak yapıyor: erişim de bozar.
- Bu iş yükünün ölçüm eşiği altı tohumlu koşumdan 0,0750 çıkıyor; erişimli hatta yayılım 0,0000.
- Doğru parça gelen otuz sekiz sorgunun biri yine de yanlış yanıtlanıyor.

#### Sonraki Adım

Bu derste dağarcık hazır geldi: temiz paragraflar, yerli yerinde sınırlar, ayrı tutulmuş kod ve
sınıf alanları. Gerçek bir kaynak böyle gelmez; saha kayıtları form başlıkları, sayfa altlıkları,
satır ortasından bölünmüş cümleler ve metnin içine gömülmüş kod alanları taşır. Bu artıkların
erişime ne yaptığı hiç sorulmadı: hangi hazırlığın anmayı yükselttiği ve hazırlığın kendisinin
**neyi attığı**. Sonraki ders aynı dağarcığın ham hâlinden başlar, üç hazırlık düzeyini aynı sorgu
kümesinde ölçer ve kaba bir temizleme kuralının attığı satırları sayar.

### Belge Hazırlama

Source: https://academia.sh/tr/kurslar/rag/belge-hazirlama

Aynı kurgu dağarcığın ham hâlinden başlayarak dört hazırlık düzeyinin aynı kırk sorguda ölçülmesi: belge başına tek blok olarak bırakılan kaynak erişim anmasını 1,0000 ile en yükseğe çıkarıyor ama isteklerin tamamı bağlam penceresini aşıyor ve üretim 0,0000'a iniyor, yani tek sütun basılsaydı en kötü kurulum kazanırdı. Satır bazlı kaba bölme 1805 parça saklıyor ve üretimde 0,9000 veriyor, yapıya duyarlı hazırlık ise 693 parçayla 0,9250 ve önceki dersin başladığı yeri birebir üretiyor; aradaki 0,0250 bu kursun 0,0750 eşiğinin altındadır ve ölçülmemiş sayılır. Yinelenen satır süzgeci 798 satır ve 6962 belirteç atarken 568 kavram-belge bağının 96'sını yok ediyor ve sekiz belgede ana kavramın kanıtını siliyor; eşik ikiye indiğinde kayıp 283 bağa ve altmış belgeye çıkıyor. Erişim ve üretim sütunları bu kaybın hiçbirini göstermiyor.

Önceki ders dağarcığı hazır bulmuştu: iki yüz belge, altı yüz doksan üç temiz paragraf, ayrı
tutulmuş kod ve sınıf alanları. O hazırlık kendiliğinden olmadı. Saha ekibinin kayıtları bir form
başlığı, bir kod satırı, satır ortasından bölünmüş cümleler ve bir sayfa altlığı taşır; erişim
hattına giren şey bunların hepsidir.

Bu dersin sorusu tek: **hazırlık erişim anmasına ne katıyor ve hazırlığın kendisi neyi atıyor.**
İkinci yarısı birincisi kadar önemlidir, çünkü temizleme bir seçme işidir ve seçilmeyen her satır
dağarcıktan silinir. Ayrıştırma, temizleme ve meta veri çıkarma **yordamı** M26/K03'ün veri toplama
ve hazırlama kursunda ölçüldü ve burada **tekrarlanmaz**; buraya eklenen tek şey, o yordamın
erişim hattındaki karşılığıdır.

- **EH8.** Kod bir **benzeticidir**; dağarcık, ham kaynak biçimi ve sorgular **kurgudur**, tohum
  **20260218**. Gömme ve dil modeli önceki dersteki tanımlardır.
- **EH9.** Ham kaynak dört artık taşır: her belgede yinelenen **form başlığı**, metnin içine
  gömülü **kod ve sınıf alanı**, paragrafların **0,45**'inde satır ortasından bölünme ve her
  belgede yinelenen **sayfa altlığı**. Devam satırı iki boşlukla girintilidir.
- **EH10.** Bölünme noktası paragrafın birinci, beşinci ya da yedinci sözcüğünden sonradır.
  Birinci ve yedinci nokta bir **belge yüzeyini ortadan böler** ve o yüzeyi arama için görünmez
  kılar; beşinci nokta iki yüzeyi de sağlam bırakır.
- **EH11.** **Ham blok** belge başına tek parça bırakır. **Satır bazlı** her ham satırı ayrı parça
  sayar. **Yinelenen satır süzgeci** üçten çok belgede geçen satırı atar. **Yapıya duyarlı
  hazırlık** devam satırlarını birleştirir, bilinen başlık ile altlığı atar, kod ve sınıf alanını
  metinden çıkarıp alana yazar.
- **EH12.** Ölçütler önceki dersin tanımlarıdır ve ilk üç parça getirilir; eşik **0,0750**. Bedel
  iki birimledir: **saklanan parça sayısı** (her parça bir vektör tutar, vektör başına otuz iki
  sayı) ve **saklanan belirteç**.
- **EH13.** **Kavram-belge bağı**, bir belgenin metninde bir kavramın belge yüzeyinin geçmesidir.
  Bu sayı sorgu kümesinden ve koşumdan **bağımsızdır**.

#### Ham Kaynağın Hâli

İlk blok kurgu dağarcığı kurar, üstüne ham kaynak biçimini uygular ve bir belgenin ham hâlini
basar. Yazdırılan belgede üç bölünme vardır ve üçü de ayrı noktadadır.

```python
# KURGUDUR. Dagarcik, kavram ekseni, gomme ve ham kaynak bicimi benzeticidir; gercek bir
# gomme uc noktasi cagrilmaz. Tohum 20260218.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# ---- KURGU ham kaynak: form basligi, kod alani, bolunmus paragraflar, sayfa altligi
BASLIK, ALTLIK = "bolge mudurlugu saha kayit formu", "ic kullanim icindir dagitilamaz"
HAM = []
for i, d in enumerate(BELGE):
    r = uretec(TOHUM + 3011 * i)
    s = [BASLIK, f"belge kodu {d['kod']} sinif {d['sinif']}", d["baslik"]]
    for p in d["par"]:
        w = p.split()
        if r() < 0.45:
            k = [1, 5, 7][ayrik(r(), [0.4, 0.25, 0.35])]
            s += [" ".join(w[:k]), "  " + " ".join(w[k:])]   # devam satiri iki bosluk girintili
        else:
            s.append(p)
    HAM.append(s + [ALTLIK])

j = next(i for i, s in enumerate(HAM)
         if sum(x.startswith("  ") for x in s) >= 2 and len(s) <= 10)
print("ham kaynak %s, %d satir:" % (BELGE[j]["kod"], len(HAM[j])))
for x in HAM[j]:
    print("  |" + x)
print("toplam ham satir %d, hazir paragraf %d"
      % (sum(len(s) for s in HAM), sum(len(d["par"]) for d in BELGE)))
```

```
ham kaynak SY003, 10 satir:
  |bolge mudurlugu saha kayit formu
  |belge kodu SY003 sinif sayac
  |okuma yordami yordami
  |okuma dogrulamasi icin not tutulur
  |  ve okuma yordami ile birlikte yazilir
  |sayac degisimi icin form tutulur ve okuma
  |  yordami ile birlikte yazilir
  |okuma
  |  yordami icin islem tutulur ve okuma yordami ile birlikte yazilir
  |ic kullanim icindir dagitilamaz
toplam ham satir 1805, hazir paragraf 693
```

Sekizinci satır tek bir sözcüktür: `okuma`. Devamı bir alt satırdadır. Bu belgede `okuma yordami`
yüzeyi üç kez geçiyor ama satır sınırı yüzeyi ortadan böldüğü için o geçişlerden biri arama
tarafında **yok** sayılır. Altıncı satır da aynı şeyi yapıyor. Bölünme kayıp değildir; **hazırlık
yapılmadığı sürece** kayıptır.

#### Dört Hazırlık Düzeyi

İkinci blok dil modeli benzeticisini kurar, dört hazırlık düzeyini üretir ve dördünü aynı kırk
sorguda ölçer. Yönerge tek kavramlık yanıt dayattığı için model doğrudan etiketi yazar.

```python
import math
# ---- KURGU dil modeli benzeticisi: onceki dersin benzeticisi, yanit uzayi yirmi kavram
PENCERE = 240
ON_BILGI = {"sizinti", "basinc", "sure", "degisim", "vana", "duyuru", "gecis"}
SAYAC = [0]


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


def cagir(istem, tohum=TOHUM, sicaklik=0.6):
    SAYAC[0] += 1
    b = belirtecle(istem)
    if len(b) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(b), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(b), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    dm = " " + istem.lower() + " "
    p = {k: 0.15 for k in ANAHTAR}
    for k in ANAHTAR:
        p[k] += 2.0 * dm.count(KAVRAM[k][1])             # belge dilini model taniyor
        if k in ON_BILGI and KAVRAM[k][2] in dm:
            p[k] += 2.0
    w = [math.exp(p[a] / sicaklik) for a in sorted(p)]
    y = sorted(p)[ayrik(r(), [x / sum(w) for x in w])]
    return {"durum": "tamam", "giris": len(b), "cikis": len(belirtecle(y)), "yanit": y}


YONERGE = ("Talebi su kavramlardan birine bagla: " + " , ".join(ANAHTAR) +
           " . Yanit olarak tek kavram yaz . ")


def birlestir(s):
    c = []
    for x in s:
        if x.startswith("  ") and c:
            c[-1] += " " + x.strip()                     # devam satiri geriye eklenir
        else:
            c.append(x)
    return c


SAY = {}
for s in HAM:
    for x in set(birlestir(s)):
        SAY[x] = SAY.get(x, 0) + 1


def hazirla(kip, esik=3):
    p, atilan = [], []
    for i, s in enumerate(HAM):
        if kip == "ham blok":
            c = [" ".join(s)]
        elif kip == "satir bazli":
            c = [x.strip() for x in s]
        elif kip == "yinelenen suzme":
            c = [x for x in birlestir(s) if SAY[x] < esik]
            atilan += [x for x in birlestir(s) if SAY[x] >= esik]
        else:
            c = [x for x in birlestir(s) if x not in (BASLIK, ALTLIK, BELGE[i]["baslik"])
                 and not x.startswith("belge kodu")]
        p += [{"kod": BELGE[i]["kod"], "sinif": BELGE[i]["sinif"], "metin": x,
               "kavram": [k for k in ANAHTAR if KAVRAM[k][1] in x]} for x in c]
    return p, atilan


def olc(p, k=3):
    SAYAC[0] = 0
    v = [gom(x["metin"]) for x in p]
    a = [0] * 6
    for s in SORGU:
        q = gom(s["metin"])
        ug = sorted(range(len(p)), key=lambda i: -aci(q, v[i]))[:k]
        h = [s["kavram"] in p[i]["kavram"] for i in ug]
        a[0] += any(h)
        a[1] += sum(h) / k
        a[2] += sum(p[i]["sinif"] == s["sinif"] for i in ug) / k
        y = cagir(YONERGE + "Kaynak: " + " . ".join(p[i]["metin"] for i in ug) +
                  " . Talep: " + s["metin"])
        a[3] += y["durum"] == "baglam_asimi"
        a[4] += y["giris"] + y["cikis"]
        a[5] += y["yanit"] == s["kavram"]
    return [x / len(SORGU) for x in a[:4]] + [a[4], a[5] / len(SORGU)]


print("hazirlik         parca saklanan   anma kesinlik  sinif  uretim  asim belirtec")
for kip in ("ham blok", "satir bazli", "yinelenen suzme", "yapiya duyarli"):
    p, at = hazirla(kip)
    m = olc(p)
    print("%-16s%6d %8d %6.4f %8.4f %6.4f %7.4f %5.2f %8d"
          % (kip, len(p), sum(len(belirtecle(x["metin"])) for x in p),
             m[0], m[1], m[2], m[5], m[3], m[4]))
```

```
hazirlik         parca saklanan   anma kesinlik  sinif  uretim  asim belirtec
ham blok           200    16183 1.0000   0.9667 0.9667  0.0000  1.00    12345
satir bazli       1805    16183 0.9500   0.9500 0.9500  0.9000  0.00     4412
yinelenen suzme    695     9221 0.9500   0.9500 0.9500  0.9250  0.00     5341
yapiya duyarli     693    11281 0.9500   0.9500 0.9500  0.9250  0.00     5343
```

Birinci satır bu dersin en önemli sayısıdır. Hazırlanmamış kaynak, **erişim sütununun en iyisidir**:
anma **1,0000**, kesinlik ve sınıf isabeti **0,9667**. Sebep açık, çünkü belge başına tek parça
tutulduğunda o parça belgedeki bütün kavramları taşır ve hedefi kaçırması güçleşir. Aynı satırın
üretim isabeti **0,0000**'dır. Bağlam aşımı payı **1,00**: kırk isteğin kırkı da pencereye
sığmamıştır, çünkü üç belge birden istemin içine konmuştur. **Tek sütun basılsaydı bu kurulum
kazanırdı.**

Satır bazlı bölme öbür uçtur. Anma **0,9500**'e iner, çünkü bölünmüş yüzeyler artık aranamaz;
buna karşılık istek başına belirteç en düşük değerdedir (**4412**), zira getirilen satırlar
kısadır. Bedeli saklanan parça sayısında ödenir: **1805** vektör, yani yapıya duyarlı hazırlığın
**2,6 katı**, üstelik saklanan belirteç aynı kalarak. Üretim **0,9000**'dır ve yapıya duyarlı
hazırlığın **0,9250**'siyle arasındaki fark **0,0250**, yani bu kursun **0,0750** eşiğinin
altındadır: **ölçülmemiş** sayılır. Bu iki kurulum arasındaki ölçülmüş fark isabette değil,
**saklanan vektör sayısındadır**.

Son satır önceki dersin başladığı yerdir: 693 parça, 0,9500 anma, 0,9250 üretim, 5343 belirteç.
Yapıya duyarlı hazırlığın çıktısı, birinci dersin girdisidir.

#### Hazırlığın Attığı

Üçüncü satır ucuz görünüyor: saklanan belirteci **11281'den 9221'e** indiriyor ve isabetin hiçbir
sütununu oynatmıyor. Yinelenen satır süzgeci bir tahmine dayanır: aynı metin çok belgede
geçiyorsa artıktır. Form başlığı ve sayfa altlığı için doğrudur. Kayıt dili **kalıplı** olduğu
için gerçek paragraflar da yinelenir.

```python
def baglar(p):
    return {(x["kod"], k) for x in p for k in x["kavram"]}


tam = baglar(hazirla("yapiya duyarli")[0])
print("yapiya duyarli hazirligin kurdugu kavram-belge bagi:", len(tam))
print("esik  parca  atilan satir  atilan belirtec  kaybolan bag  anasiz belge    anma  uretim")
for e in (2, 3, 4):
    p, at = hazirla("yinelenen suzme", e)
    b = baglar(p)
    m = olc(p)
    print("%4d %6d %13d %16d %13d %13d  %6.4f  %6.4f"
          % (e, len(p), len(at), sum(len(belirtecle(x)) for x in at), len(tam - b),
             sum((d["kod"], d["ana"]) not in b for d in BELGE), m[0], m[5]))
```

```
yapiya duyarli hazirligin kurdugu kavram-belge bagi: 568
esik  parca  atilan satir  atilan belirtec  kaybolan bag  anasiz belge    anma  uretim
   2    427          1066            11357           283            60  0.9500  0.9250
   3    695           798             6962            96             8  0.9500  0.9250
   4    835           658             4714            17             0  0.9500  0.9250
```

Üç eşiğin üçünde de anma **0,9500**, üretim **0,9250**. Sorgu kümesi hiçbir şey görmüyor. Oysa
eşik üçte süzgeç **798 satır** ve **6962 belirteç** atıyor; dağarcığın kurduğu **568** kavram-belge
bağının **96'sı** yok oluyor ve **sekiz belgede** o belgenin kendi ana kavramının kanıtı kalmıyor.
Eşik ikiye indirildiğinde kayıp **283 bağa** ve **altmış belgeye** çıkıyor, saklanan belirtecin
üçte ikisi gidiyor ve iki ölçüt sütunu hâlâ kımıldamıyor.

Buradaki asıl ders ölçme üzerinedir. Kırk sorgu iki yüz belgenin yirmi kavramını örneklemez;
sorulmayan bir kavramın kanıtının silinmesi bu ölçümde **görünmez**. Kavram-belge bağı sayısı ise
koşumdan ve sorgu kümesinden bağımsızdır: dağarcığın ne kadarının hâlâ aranabilir olduğunu, hiç
sorgu koşturmadan söyler. Temizleme kuralı seçilirken bakılacak sayı budur.

#### Özet

- Hazırlığın erişim hattındaki karşılığı iki ayrı sorudur: **anmaya ne kattığı** ve **neyi attığı**.
  İkincisi erişim ve üretim sütunlarında görünmeyebilir.
- Hazırlanmamış kaynak erişim sütununun en iyisidir (anma 1,0000) ve üretim sütununun en kötüsü
  (0,0000); kırk isteğin kırkı da bağlam penceresini aşıyor.
- Satır bazlı kaba bölme 1805 vektör saklıyor, yapıya duyarlı hazırlık 693; aradaki üretim farkı
  0,0250, yani eşiğin altında. Ölçülmüş kazanç isabette değil, saklanan vektör sayısındadır.
- Yapıya duyarlı hazırlık 693 parça, 0,9500 anma ve 0,9250 üretim verir; bu, önceki dersin
  başladığı noktadır.
- Yinelenen satır süzgeci eşik üçte 798 satır ve 6962 belirteç atarken 568 kavram-belge bağının
  96'sını siliyor; eşik ikide kayıp 283 bağ ve altmış belgedir.
- Kavram-belge bağı sayısı sorgu kümesinden bağımsız bir ölçüdür ve temizleme kararının asıl
  ölçütüdür.

#### Sonraki Adım

Yapıya duyarlı hazırlık bir sınırı **verili** kabul etti: kaynağın kendi paragraf sınırı. Devam
satırları birleştirildi, başlık ve altlık atıldı, ama paragrafın nerede biteceği kaynağın kararı
olarak bırakıldı. O sınır bir karardır ve erişim hattının ölçtüğü her şeyi değiştirir. Parça
küçüldükçe kesinlik yükselir ve sınır üstündeki yüzeyler kaybolur; büyüdükçe anma yükselir ve
bağlam penceresi doluverir. Sonraki ders bu sınırı eline alır: parça boyutu ile örtüşmeyi süpürür,
her kurulumun anmasını, saklanan parça sayısını ve saklanan belirtecini yan yana basar ve
örtüşmenin kazandırdığının maliyetini karşılamayı bıraktığı noktayı sayar.

### Parçalama Stratejileri

Source: https://academia.sh/tr/kurslar/rag/parcalama-stratejileri

Parça sınırının bir karar olarak ele alınması ve boyut ile örtüşmenin aynı kurgu dağarcıkta süpürülmesi: sekiz belirteçlik parçalar kaynaktaki 693 ilişki geçişinin hiçbirini bütün tutamıyor, seksen belirteçlik parçalar 0,9784'ünü tutuyor ama isteklerin 0,25'i bağlam penceresini aşıyor ve üretim 0,9250'den 0,4750'ye iniyor. Yirmi belirteçlik parçada örtüşme sıfırdan on ikiye çıkarıldığında ilişki anması 0,4416'dan 1,0000'a yükselirken saklanan belirteç 11281'den 23145'e, yani 2,05 kata çıkıyor; kazanılan ilişki başına maliyet altıncı belirteçten sonra 16'dan 215'e sıçrıyor ve kesişme noktası oradadır. Kaynağın kendi paragraf sınırına uyan bölme ise aynı 1,0000 ilişki anmasını 693 parça ve 11281 belirteçle, yani örtüşmenin yarısı kadar yerle veriyor. Erişim anması ve üretim iki süpürmenin hiçbir satırında eşiği aşacak kadar oynamıyor.

Önceki ders hazırlığı sınıra kadar götürdü ve orada durdu: devam satırları birleştirildi, başlık
ile altlık atıldı, kod ve sınıf alanı ayrıldı, ama paragrafın nerede biteceği **kaynağın kararı**
olarak bırakıldı. Erişim hattında o sınır kaynağın değil, hattı kuranın kararıdır. Bir parça hem
dizinlenen birim, hem de modele verilen metin parçasıdır; boyutu iki ucu birden belirler.

Bu dersin ölçtüğü şey sınırın bedelidir. Parça küçüldükçe saklanan vektör sayısı artar ve
metnin içindeki **ilişkiler** kesilir; büyüdükçe bağlam penceresi dolar. Örtüşme kesilen ilişkiyi
geri alır ve aldığını belirteçle öder. Bu üçünün nerede kesiştiği ölçülebilir bir sayıdır.

- **EH14.** Kod bir **benzeticidir**; dağarcık, gömme ve sorgular **kurgudur**, tohum
  **20260218**. Gömme ile dil modeli önceki derslerin tanımlarıdır.
- **EH15.** Parça sınırları **sözcük** üzerinde çizilir, parça boyutu **belirteç** cinsinden
  verilir: pencere, belirteç bütçesi dolana kadar sözcük ekleyerek büyür. Belirteç ortasından
  bölme yapılmaz, çünkü bölünmüş bir belirteç aramada hiçbir yüzeyle eşleşmez.
- **EH16.** **Örtüşme** de belirteç cinsindendir: bir sonraki pencere, öncekinin son
  örtüşme kadar belirtecini yeniden alarak başlar.
- **EH17.** **İlişki geçişi**, bir paragrafın iki kavram yüzeyini birlikte taşıyan aralıktır ve
  kaynağın asıl bilgi birimidir: hangi kaydın hangi yordamla birlikte tutulduğu. Dağarcıkta
  **693** ilişki geçişi vardır.
- **EH18.** **İlişki anması**, bu geçişlerin **tek bir parçanın içinde bütün kalma** payıdır.
  Sorgu kümesinden ve koşumdan **bağımsızdır**; parçalama kararının kaynağa ne yaptığını
  sorgu koşturmadan söyler.
- **EH19.** Erişim anması, üretim isabeti ve bağlam aşımı payı önceki derslerin tanımlarıdır;
  ilk üç parça getirilir ve eşik **0,0750**'dir.
- **EH20.** Saklanan belirteç, bütün parçaların belirteç toplamıdır. Örtüşmeyen bölmede bu sayı
  kaynağın kendi büyüklüğüne eşittir (**11281**); örtüşme onu kaçla çarptığı yazılır.

#### Sınırı Ele Almak

İlk blok dağarcığı kurar, üstüne belirteç bütçeli bir parçalayıcı koyar ve ilişki geçişlerini
işaretler. Ardından dil modeli benzeticisi gelir ve ölçüm işlevi kurulur.

```python
# KURGUDUR. Dagarcik, kavram ekseni, gomme ve dil modeli benzeticidir; gercek bir uc
# nokta cagrilmaz. Tohum 20260218.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# ---- parcalama: parca sinirlari sozcukte, boyut belirtecte olculur
GOVDE = [" ".join(d["par"]).split() for d in BELGE]
ILISKI = [(i, 11 * t, 11 * t + 8)              # paragrafin iki yuzeyini birlikte tasiyan aralik
          for i, d in enumerate(BELGE) for t in range(len(d["par"]))]


def pencereler(w, boy, ort):
    kt = [len(belirtecle(x)) for x in w]
    pen, i = [], 0
    while True:
        j, t = i, 0
        while j < len(w) and t + kt[j] <= boy:
            t += kt[j]
            j += 1
        j = max(j, i + 1)
        pen.append((i, j))
        if j >= len(w):
            return pen
        yeni, g = j, 0
        while yeni > i + 1 and g + kt[yeni - 1] <= ort:      # ortusme kadar geri sarilir
            yeni -= 1
            g += kt[yeni]
        i = yeni


def parcala(boy, ort, yapi=False):
    p, pen = [], {}
    for i, d in enumerate(BELGE):
        w = GOVDE[i]
        pen[i] = ([(11 * t, 11 * t + 11) for t in range(len(d["par"]))] if yapi
                  else pencereler(w, boy, ort))
        for a, b in pen[i]:
            m = " ".join(w[a:b])
            p.append({"kod": d["kod"], "sinif": d["sinif"], "metin": m,
                      "kavram": [k for k in ANAHTAR if KAVRAM[k][1] in m]})
    kalan = sum(any(a <= s and e <= b for a, b in pen[i]) for i, s, e in ILISKI)
    return p, kalan / len(ILISKI)


import math
# ---- KURGU dil modeli benzeticisi: onceki derslerin benzeticisi
PENCERE = 240
ON_BILGI = {"sizinti", "basinc", "sure", "degisim", "vana", "duyuru", "gecis"}
SAYAC = [0]


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


def cagir(istem, tohum=TOHUM, sicaklik=0.6):
    SAYAC[0] += 1
    b = belirtecle(istem)
    if len(b) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(b), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(b), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    dm = " " + istem.lower() + " "
    p = {k: 0.15 for k in ANAHTAR}
    for k in ANAHTAR:
        p[k] += 2.0 * dm.count(KAVRAM[k][1])
        if k in ON_BILGI and KAVRAM[k][2] in dm:
            p[k] += 2.0
    w = [math.exp(p[a] / sicaklik) for a in sorted(p)]
    y = sorted(p)[ayrik(r(), [x / sum(w) for x in w])]
    return {"durum": "tamam", "giris": len(b), "cikis": len(belirtecle(y)), "yanit": y}


YONERGE = ("Talebi su kavramlardan birine bagla: " + " , ".join(ANAHTAR) +
           " . Yanit olarak tek kavram yaz . ")


def olc(p, k=3):
    SAYAC[0] = 0
    v = [gom(x["metin"]) for x in p]
    a = [0] * 4
    for s in SORGU:
        q = gom(s["metin"])
        ug = sorted(range(len(p)), key=lambda i: -aci(q, v[i]))[:k]
        a[0] += any(s["kavram"] in p[i]["kavram"] for i in ug)
        y = cagir(YONERGE + "Kaynak: " + " . ".join(p[i]["metin"] for i in ug) +
                  " . Talep: " + s["metin"])
        a[1] += y["yanit"] == s["kavram"]
        a[2] += y["giris"] + y["cikis"]
        a[3] += y["durum"] == "baglam_asimi"
    return (sum(len(belirtecle(x["metin"])) for x in p), a[0] / 40, a[1] / 40, a[2],
            a[3] / 40)


print("boyut  parca saklanan  iliski    anma  uretim  istek belirteci  asim")
for boy in (8, 12, 20, 32, 48, 80):
    p, il = parcala(boy, 0)
    m = olc(p)
    print("%5d %6d %8d  %.4f  %.4f  %.4f %11d %8.2f"
          % (boy, len(p), m[0], il, m[1], m[2], m[3], m[4]))
```

```
boyut  parca saklanan  iliski    anma  uretim  istek belirteci  asim
    8   1538    11281  0.0000  0.9500  0.9250        4294     0.00
   12   1044    11281  0.3175  0.9500  0.9250        4733     0.00
   20    667    11281  0.4416  0.9500  0.9250        5360     0.00
   32    455    11281  0.8557  1.0000  0.9250        5999     0.00
   48    328    11281  0.9394  1.0000  0.8750        6839     0.00
   80    227    11281  0.9784  1.0000  0.4750        8484     0.25
```

Boyut süpürmesi iki ayrı bozulmayı iki ayrı uçta gösteriyor. Sekiz belirteçlik parçalar kaynağın
**693 ilişki geçişinin hiçbirini** bütün tutamıyor (**0,0000**), çünkü bir ilişki ortalama on iki
belirteç yer kaplıyor ve pencereye sığmıyor. Bu parçalar kavram yüzeylerini korudukları için
erişim anmasını düşürmüyor: **0,9500**. Kesilen şey kavram değil, kavramlar arasındaki bağdır.

Öbür uç görünür biçimde bozuluyor. Seksen belirteçlik parçalar ilişkilerin **0,9784**'ünü tutuyor
ve erişim anması **1,0000**'a çıkıyor, ama üç parça isteme konduğunda kırk isteğin **0,25**'i
bağlam penceresini aşıyor. Üretim **0,9250'den 0,4750'ye** iniyor. Fark **0,4500**, yani eşiğin
altı katı: **ölçülmüş bir bozulmadır**. Erişim sütununun en iyi olduğu satır, üretim sütununun en
kötüsüdür. Kırk sekiz belirteçte üretim 0,8750'dir ve tabandan farkı 0,0500, yani **eşiğin
altında**: bu satırın isabeti düşürüp düşürmediği bu ölçümle bilinemez.

Kullanılabilir bant ortadadır: yirmi ile otuz iki belirteç arasında bağlam aşımı yok, erişim
anması en yüksek düzeyde ve ilişki anması 0,4416 ile 0,8557 arasında. Bu bandı yukarı çekmenin
yolu boyutu büyütmek değildir; örtüşmedir.

#### Örtüşmenin Fiyatı

İkinci blok yirmi belirteçlik parçada örtüşmeyi sıfırdan on ikiye süpürür ve her adımda kaç
ilişki kazanıldığını, karşılığında kaç belirteç saklandığını yazar. Son satır örtüşme yerine
kaynağın kendi paragraf sınırını kullanır.

```python
print("ortusme  parca saklanan   kat  iliski  kazanc  ek belirtec  iliski basi   anma  uretim")
onc = None
for ort in (0, 2, 4, 6, 8, 10, 12):
    p, il = parcala(20, ort)
    m = olc(p)
    e = ""
    if onc:
        k = round((il - onc[0]) * len(ILISKI))
        e = "%7d %12d %11d" % (k, m[0] - onc[1], (m[0] - onc[1]) // k)
    print("%7d %6d %8d %5.2f  %.4f%s %7.4f %7.4f"
          % (ort, len(p), m[0], m[0] / 11281, il, e or " " * 31, m[1], m[2]))
    onc = (il, m[0])
p, il = parcala(0, 0, yapi=True)
m = olc(p)
print("yapiya duyarli sinir: parca %d, saklanan %d, iliski %.4f, anma %.4f, uretim %.4f"
      % (len(p), m[0], il, m[1], m[2]))
```

```
ortusme  parca saklanan   kat  iliski  kazanc  ek belirtec  iliski basi   anma  uretim
      0    667    11281  1.00  0.4416                                 0.9500  0.9250
      2    683    12135  1.08  0.5729     91          854           9  0.9500  0.9250
      4    746    13265  1.18  0.8052    161         1130           7  1.0000  0.9250
      6    814    14743  1.31  0.9322     88         1478          16  0.9500  0.9250
      8    900    16682  1.48  0.9452      9         1939         215  0.9500  0.9250
     10   1029    19385  1.72  0.9899     31         2703          87  0.9500  0.9250
     12   1213    23145  2.05  1.0000      7         3760         537  0.9500  0.9250
yapiya duyarli sinir: parca 693, saklanan 11281, iliski 1.0000, anma 0.9500, uretim 0.9250
```

İlişki anması örtüşmeyle birlikte **0,4416'dan 1,0000'a** düzenli biçimde yükseliyor. Bedel aynı
düzenle yükselmiyor, **katlanıyor**: saklanan belirteç 11281'den **23145'e** (2,05 kat), saklanan
parça 667'den 1213'e. Her parça bir vektör tuttuğu için saklanan sayı adedi de aynı oranda
büyüyor.

Kesişme noktası son sütunda okunur. İlk üç adım ucuzdur: kazanılan her ilişki için sırasıyla
**9, 7 ve 16** belirteç saklanıyor. Dördüncü adımda, yani örtüşme altıdan sekize çıkarken, ilişki
başına maliyet **215 belirtece** sıçrıyor. Ondan sonrası da toparlanmıyor: 87 ve **537**. Kaynağın
ilişki uzunluğu ortalama on iki belirteç olduğu için örtüşme altıya kadar kesilen ilişkilerin
büyük bölümünü kurtarıyor; kalanlar pencere sınırına en talihsiz biçimde denk gelen az sayıda
geçiştir ve onları kurtarmak bütün dağarcığın yeniden saklanmasını gerektiriyor. **Örtüşme altı
belirteçtir**; bu iş yükünde ondan sonrası ilişki değil, kopya satın alır.

Erişim anması ve üretim sütunlarına bakıldığında süpürmenin tamamı düzdür: anma bir satır dışında
0,9500, üretim yedi satırda da **0,9250**. Örtüşmenin bu sorgu kümesinde **isabete kattığı
ölçülmemiştir**; saklanan belirtece kattığı ölçülmüştür. Bedeli yazılmayan düzenek ölçülmemiş
sayılır ve bu satırlarda ölçülen tek şey bedeldir.

Son satır tartışmayı bitiriyor. Kaynağın kendi paragraf sınırına uyan bölme, ilişki anmasını
**1,0000** yapıyor: örtüşme on ikinin ulaştığı yer. Karşılığında **693 parça** ve **11281
belirteç** saklıyor, yani örtüşmeli kurulumun **yarısı kadar**. Örtüşme, kaynağın yapısı
bilinmediğinde ödenen sigortadır; yapı biliniyorsa fiyatı boşunadır.

#### Özet

- Parça sınırı kaynağın değil hattı kuranın kararıdır; boyut hem saklanan vektör sayısını hem de
  isteme giren metni belirler.
- İlişki anması, kaynağın bilgi birimlerinin kaç parçada bütün kaldığını sorgu koşturmadan ölçer
  ve parçalama kararının asıl ölçütüdür.
- Küçük parça ilişkiyi keser ama kavram yüzeyini korur: sekiz belirteçte ilişki anması 0,0000
  iken erişim anması 0,9500'dür.
- Büyük parça ilişkiyi korur ama pencereyi doldurur: seksen belirteçte isteklerin 0,25'i bağlam
  aşımına uğrar ve üretim 0,9250'den 0,4750'ye iner.
- Örtüşme ilişki anmasını 0,4416'dan 1,0000'a çıkarır, saklanan belirteci 2,05 katına götürür ve
  ilişki başına maliyet altıdan sonra 16'dan 215'e sıçrar: kesişme noktası örtüşme altıdır.
- Yapıya duyarlı bölme aynı 1,0000 ilişki anmasını örtüşmenin yarısı kadar yerle verir.

#### Sonraki Adım

Üç derste dağarcık **durağan** kabul edildi. Belgeler bir kez hazırlandı, bir kez parçalandı, bir
kez gömüldü ve dizin bir daha ele alınmadı. Saha kayıtları böyle davranmaz: bir yordam
güncellenir, bir eşik değişir, bir kayıt yürürlükten kalkar. Dizin o anda değil, bir sonraki
yenilemede haberdar olur ve arada geçen sürede modele **doğru parçayı** getirmeye devam eder,
ama parçanın içindeki bilgi artık geçerli değildir. Sonraki ders yenileme aralığını süpürür:
aralık uzadıkça bayat parça payının, yanlış yanıt payının ve yenilemede yeniden gömülen parça
sayısının nasıl değiştiğini ölçer ve erişim sütununun bu bozulmanın hiçbirini göstermediğini
gösterir.

### Dizinleme ve Güncelleme

Source: https://academia.sh/tr/kurslar/rag/dizinleme-ve-guncelleme

Dizinin bir anlık görüntü olduğunun ve kaynak değiştikçe bayatladığının ölçülmesi: on iki dönemlik kurgu bir değişiklik akışında yenileme aralığı birden on ikiye çıkarıldığında bayat parça payı 0,0000'dan 0,2562'ye, yanlış yanıt payı 0,0750'den 0,3875'e çıkıyor. Erişim sütunu bu bozulmanın hiçbirini göstermiyor: erişim anması altı aralıkta da 0,9500, kavram isabeti 0,9250; düşen tek sütun, yanıtın kopyaladığı yürürlük kaydının güncel olma payıdır. Yenileme maliyeti iki politikada ayrı okunuyor: tam yeniden dizinleme aralık birde 8316 parça gömüyor, artımlı yenileme 881. Aralığı on iki katına çıkarmak artımlı yenilemede güncel yanıt başına gömülen parçayı yalnız 1,98'den 1,77'ye indiriyor, yani kazancı yüzde on bir; aynı kararın bedeli güncel yanıt payında 0,3125'tir. İki koşumun farkı bütün satırlarda 0,0000.

Önceki üç ders dağarcığı **durağan** kabul etti. Belgeler bir kez hazırlandı, bir kez parçalandı,
bir kez gömüldü; dizin kurulduktan sonra bir daha ele alınmadı. Saha kayıtları böyle davranmaz.
Bir yordam yeniden yayımlanır, bir eşik güncellenir, bir kayıt yürürlükten kalkar. Kaynak
değiştiğinde dizin değişmez; dizin bir **anlık görüntüdür** ve ne zaman çekildiği yazılmadıkça
neyi gösterdiği bilinmez.

Bu dersin ölçtüğü bozulma öncekilerden başka türlüdür. Erişim yanlış parça getirmiyor: getirilen
parça hâlâ doğru belgeden, doğru kavramdan. Bozulan şey parçanın **içeriğidir**. Bu yüzden erişim
sütunu sessiz kalır ve arıza yalnız üretim sütununda görünür.

- **EH21.** Kod bir **benzeticidir**; dağarcık, değişiklik akışı ve sorgular **kurgudur**, tohum
  **20260218**. Gömme ve dil modeli önceki derslerin tanımlarıdır.
- **EH22.** Her belge bir **yürürlük kaydı** taşır. Belge yeniden yayımlandığında kayıt bir artar;
  parça dizinden servis edilirken kaydıyla birlikte verilir. Değişim akışı on iki dönemdir ve her
  dönemde belgelerin **0,10**'u yeniden yayımlanır.
- **EH23.** Yeniden yayım parçanın **gövdesini** değil kaydını değiştirir. Bu, ölçümü sadeleştiren
  bir varsayımdır: gömme oynamadığı için erişim sıralaması bütün aralıklarda aynı kalır ve düşen
  sütunun **yalnız** bayatlıktan düştüğü kesinleşir.
- **EH24.** Benzeticiye tek bir davranış eklenir: model, seçtiği kavramın yüzeyini taşıyan ilk
  kaynak parçadaki **yürürlük kaydını olduğu gibi kopyalar**. Alıntılayan bir modelin yaptığı
  budur ve bayatlığın yanıta geçtiği yer burasıdır.
- **EH25.** **Bayat parça payı**, servis edilen parçaların kaydı ile kaynağın o dönemdeki gerçek
  kaydının uyuşmama oranıdır. **Güncel yanıt payı**, kavramı doğru olan **ve** kopyaladığı kaydı
  kaynağın güncel kaydına eşit olan yanıtların oranıdır.
- **EH26.** İki yenileme politikası ölçülür: **tam yeniden dizinleme** her yenilemede bütün
  parçaları yeniden gömer, **artımlı yenileme** yalnız o aralıkta değişmiş belgelerin parçalarını.
  Bir aralıkta iki kez değişen belge bir kez gömülür.
- **EH27.** Ölçüm on iki dönemin **hepsinde** yapılır; her dönem kırk sorgu sorulur, yani her
  aralık için 480 istek. Bayat parça payı ile gömülen parça sayısı koşumdan bağımsızdır.

#### Bayatlığın Yanıta Geçtiği Yer

İlk blok dağarcığı kurar, üstüne değişiklik akışını ve yürürlük kaydını koyar, benzeticiyi
kopyalama davranışıyla birlikte tanımlar ve yenileme aralığını süpürür.

```python
# KURGUDUR. Dagarcik, kavram ekseni, gomme, degisim akisi ve dil modeli benzeticidir;
# gercek bir uc nokta cagrilmaz. Tohum 20260218.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

import math
# ---- KURGU degisim akisi: on iki donem, her donemde bir bolum belge yeniden yayimlanir
DONEM = 12
DEGISIM = []
for t in range(1, DONEM + 1):
    r = uretec(TOHUM + 6007 * t)
    DEGISIM.append([i for i in range(len(BELGE)) if r() < 0.10])


def damga(i, t):
    """i numarali belgenin t doneminin sonundaki yururluk kaydi."""
    return "Y%02d" % sum(i in DEGISIM[u] for u in range(t))


PARCA = [{"belge": i, "kod": d["kod"], "sinif": d["sinif"], "govde": p,
          "kavram": [k for k in ANAHTAR if KAVRAM[k][1] in p]}
         for i, d in enumerate(BELGE) for p in d["par"]]
VEK = [gom(x["govde"]) for x in PARCA]          # damga gommeyi degistirmez
UST = []
for s in SORGU:
    q = gom(s["metin"])
    UST.append(sorted(range(len(PARCA)), key=lambda i: -aci(q, VEK[i]))[:3])

# ---- KURGU dil modeli benzeticisi: onceki derslerin benzeticisi, tek eklenti
# baglamda gordugu yururluk kaydini kopyalamasi
PENCERE = 240
ON_BILGI = {"sizinti", "basinc", "sure", "degisim", "vana", "duyuru", "gecis"}
SAYAC = [0]


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


def cagir(istem, tohum=TOHUM, sicaklik=0.6):
    SAYAC[0] += 1
    b = belirtecle(istem)
    if len(b) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(b), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(b), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    dm = " " + istem.lower() + " "
    p = {k: 0.15 for k in ANAHTAR}
    for k in ANAHTAR:
        p[k] += 2.0 * dm.count(KAVRAM[k][1])
        if k in ON_BILGI and KAVRAM[k][2] in dm:
            p[k] += 2.0
    w = [math.exp(p[a] / sicaklik) for a in sorted(p)]
    y = sorted(p)[ayrik(r(), [x / sum(w) for x in w])]
    for x in istem.split(" . "):                # kaynaktaki kaydi oldugu gibi kopyalar
        if KAVRAM[y][1] in x and "yururluk kaydi" in x:
            y += " " + x.split("yururluk kaydi ")[1].split()[0]
            break
    return {"durum": "tamam", "giris": len(b), "cikis": len(belirtecle(y)), "yanit": y}


YONERGE = ("Talebi su kavramlardan birine bagla ve kaynagin yururluk kaydini yaz: " +
           " , ".join(ANAHTAR) + " . Yanit olarak tek kavram ve kayit yaz . ")


def kosum(aralik, tohum=TOHUM):
    SAYAC[0] = 0
    bayat = kavram = guncel = anma = n = 0
    gomulen = tam = 0
    for t in range(1, DONEM + 1):
        son = (t // aralik) * aralik            # dizinin gordugu son donem
        if t % aralik == 0:                     # bu donem yenileme var
            deg = {i for u in range(t - aralik, t) for i in DEGISIM[u]}
            gomulen += sum(x["belge"] in deg for x in PARCA)
            tam += len(PARCA)
        for s, ug in zip(SORGU, UST):
            metin = {i: "%s yururluk kaydi %s" % (PARCA[i]["govde"],
                                                  damga(PARCA[i]["belge"], son)) for i in ug}
            bayat += sum(damga(PARCA[i]["belge"], son) != damga(PARCA[i]["belge"], t)
                         for i in ug) / 3
            anma += any(s["kavram"] in PARCA[i]["kavram"] for i in ug)
            y = cagir(YONERGE + "Kaynak: " + " . ".join(metin[i] for i in ug) +
                      " . Talep: " + s["metin"], tohum)
            kv, _, dg = y["yanit"].partition(" ")
            kay = next((i for i in ug if KAVRAM[kv][1] in metin[i]), None) if kv in ANAHTAR \
                else None
            kavram += kv == s["kavram"]
            guncel += (kv == s["kavram"] and kay is not None
                       and dg == damga(PARCA[kay]["belge"], t))
            n += 1
    return bayat / n, anma / n, kavram / n, guncel / n, gomulen, tam


print("donem %d, toplam yeniden yayim %d, hic degismeyen belge %d"
      % (DONEM, sum(len(x) for x in DEGISIM),
         sum(1 for i in range(len(BELGE)) if all(i not in d for d in DEGISIM))))
print("aralik  yenileme  gomulen(artimli)  gomulen(tam)  bayat parca   anma  kavram  guncel")
for a in (1, 2, 3, 4, 6, 12):
    b, an, kv, gu, go, tm = kosum(a)
    print("%6d %9d %17d %13d %12.4f %6.4f  %.4f  %.4f"
          % (a, DONEM // a, go, tm, b, an, kv, gu))
```

```
donem 12, toplam yeniden yayim 254, hic degismeyen belge 51
aralik  yenileme  gomulen(artimli)  gomulen(tam)  bayat parca   anma  kavram  guncel
     1        12               881          8316       0.0000 0.9500  0.9250  0.9250
     2         6               839          4158       0.0347 0.9500  0.9250  0.8917
     3         4               774          2772       0.0625 0.9500  0.9250  0.8771
     4         3               741          2079       0.0937 0.9500  0.9250  0.8208
     6         2               662          1386       0.1278 0.9500  0.9250  0.7708
    12         1               519           693       0.2562 0.9500  0.9250  0.6125
```

Tablonun ilk okuması iki sütunun ayrı tutulmasının en açık gerekçesidir. **Erişim anması altı
satırda da 0,9500, kavram isabeti altı satırda da 0,9250.** Yenileme aralığı bir dönemden on iki
döneme çıkarken erişim sütununda **hiçbir şey** değişmiyor, çünkü dizin doğru belgeleri getirmeye
devam ediyor. Getirdiği parçaların **0,2562**'si artık kaynakta olmayan bir metni gösteriyor ve
bunu erişim ölçütlerinden hiçbiri söylemiyor.

Düşen tek sütun güncel yanıt payıdır: **0,9250'den 0,6125'e**. Aradaki 0,3125 eşiğin dört katından
fazladır. Bunun kullanıcıya görünen karşılığı şudur: model doğru yordamı buluyor, doğru kavramı
adlandırıyor ve yanına **yürürlükten kalkmış** bir kayıt yazıyor. Bu yanıt bir halüsinasyon
değildir; kaynağa sadıktır. Kaynağın kendisi bayattır. Kaynağa bağlama, kaynağın tazeliğini
garanti etmez.

Bayat parça payı ile yanlış yanıt payı da bire bir örtüşmüyor. Aralık on ikide parçaların
**0,2562**'si bayat ama yanıtların **0,3875**'i yanlış. Fark, kavram isabetinin zaten 0,9250
olmasından ve bayat parçanın seçilen kavramı taşıyan parça olma olasılığının kendi başına bir
dağılım taşımasından gelir. Bayatlık bir **girdi** ölçütüdür, yanlış yanıt bir **çıktı** ölçütü;
ikisi aynı sayı değildir ve birbirinin yerine yazılamaz.

#### Yenilemenin Fiyatı

Gömme maliyeti iki politikada tamamen ayrı davranıyor. **Tam yeniden dizinleme** her yenilemede
altı yüz doksan üç parçayı yeniden gömüyor: aralık birde **8316**, aralık on ikide **693**. Bu
politikada aralık, maliyeti doğrudan bölen bir kaldıraçtır. **Artımlı yenileme** yalnız değişmiş
belgelerin parçalarını gömüyor: aralık birde **881**, yani tam dizinlemenin **9,4'te biri**.

İkinci blok bu iki politikayı doğru iş başına okur ve ölçümün kendi kararlılığını sınar.

```python
print("aralik  yanlis yanit payi  artimli/guncel  tam/guncel  2. tohum guncel   fark")
for a in (1, 2, 4, 12):
    b, an, kv, gu, go, tm = kosum(a)
    g2 = kosum(a, TOHUM + 1)[3]
    n = gu * DONEM * len(SORGU)
    print("%6d %17.4f %15.2f %11.2f %17.4f %6.4f"
          % (a, 1 - gu, go / n, tm / n, g2, abs(gu - g2)))
```

```
aralik  yanlis yanit payi  artimli/guncel  tam/guncel  2. tohum guncel   fark
     1            0.0750            1.98       18.73            0.9250 0.0000
     2            0.1083            1.96        9.71            0.8917 0.0000
     4            0.1792            1.88        5.28            0.8208 0.0000
    12            0.3875            1.77        2.36            0.6125 0.0000
```

Artımlı sütun aralığın neden yanlış kaldıraç olduğunu gösteriyor. Aralık birden on ikiye
çıkarıldığında gömülen parça 881'den 519'a iniyor, yani ancak **yüzde kırk bir**. Sebep, bir
aralıkta birden çok kez yeniden yayımlanan belgenin yalnız bir kez gömülmesidir; aralık uzadıkça
bu birleşme artar ama toplam değişen belge sayısı değişmez. Güncel yanıt başına okunduğunda kazanç
daha da eriyor: **1,98'den 1,77'ye**, yani yüzde on bir. Aynı kararın bedeli güncel yanıt payında
**0,3125**'tir. Artımlı yenilemede aralık uzatmak, neredeyse hiçbir şey karşılığında dörtte bir
doğruluk satmaktır.

Tam dizinleme sütununda tablo tersine görünüyor: güncel yanıt başına **18,73'ten 2,36'ya**. Bu
satır aralığı uzatmayı haklı çıkarmaz, tam yeniden dizinlemeyi bırakmayı haklı çıkarır. Aralık
biri artımlı politikayla kurmak, aralık on ikiyi tam dizinlemeyle kurmaktan hem ucuzdur
(881'e karşı 693, aynı büyüklük sınıfı) hem de 0,3125 daha doğrudur.

Son iki sütun ölçümün kendi kararlılığıdır. İkinci tohumla koşulduğunda güncel yanıt payı dört
satırda da **birebir aynı** çıkıyor, fark **0,0000**. Bu, ilk dersin bulgusunun sürmesidir:
kaynağı verilmiş bir çağrının çıktısı tohuma bağlı kalmıyor. Tablodaki farkların hepsi bu yüzden
eşiğin çok üstündedir ve **ölçülmüştür**.

#### Özet

- Dizin bir anlık görüntüdür; kaynak değiştiğinde dizin değişmez ve arada geçen sürede doğru
  parçayı bayat içerikle servis eder.
- Yenileme aralığı birden on ikiye çıkarken bayat parça payı 0,0000'dan 0,2562'ye, yanlış yanıt
  payı 0,0750'den 0,3875'e çıkıyor.
- Erişim sütunu bu bozulmanın hiçbirini göstermiyor: anma altı aralıkta da 0,9500, kavram isabeti
  0,9250. Kaynağa bağlama, kaynağın tazeliğini garanti etmez.
- Bayat parça payı bir girdi ölçütü, yanlış yanıt payı bir çıktı ölçütüdür; 0,2562 ile 0,3875
  aynı şeyin iki adı değildir.
- Tam yeniden dizinleme aralık birde 8316 parça gömüyor, artımlı yenileme 881; aralık uzatmak
  artımlı politikada gömülen parçayı yalnız yüzde kırk bir azaltıyor.
- Güncel yanıt başına gömülen parça artımlı politikada 1,98'den 1,77'ye iniyor: yüzde on birlik
  kazanç karşılığında 0,3125 doğruluk satılıyor.

#### Sonraki Adım

Dört derste hat girdi tarafından kuruldu: kaynak hazırlandı, parçalandı, gömüldü, dizin yenilendi.
Bu dört kararın hepsi **belgenin** tarafındaydı. Hattın öbür ucundaki metin, yani abonenin yazdığı
sorgu, dört derste de olduğu gibi kullanıldı: kısa, eksik, kaydın dilinden başka bir dilde. Oysa
erişimin bulduğu şeyi belirleyen iki metinden biri odur. Sorgunun genişletilmesi, yeniden
yazılması ya da bir model çağrısıyla kaydın diline çevrilmesi anmayı yükseltebilir ve o çağrının
kendisi hattın bedeline eklenir. Sonraki ders sorguyu ele alır ve dönüştürmenin kattığı anmayı
eklediği çağrıyla birlikte ölçer.

### Sorgu Dönüştürme

Source: https://academia.sh/tr/kurslar/rag/sorgu-donusturme

Kullanıcının yazdığı sorgunun dizine gitmeden önce tek bir model çağrısıyla belge diline çevrilmesi ve bu adımın kazandırdığı ile kaybettirdiğinin ayrı ayrı sayılması: kırk sorguluk kurgu kümede kısa yazımın tabanı 0,3750 anma ve 0,2000 üretim iken genişletme ikisini 0,7500 ve 0,7000'e çıkarıyor, yani dizin dilinde yazılmış sorgunun bıraktığı yere geliyor. Aynı düzenek uzun yazımda tabanı 0,5500'den 0,3500'e, yeniden yazma ise 0,2500'e düşürüyor, çünkü dönüştürücünün doğru kavramı bulma payı 0,9500'den 0,3500'e iniyor. Bedel her iki kümede de sorgu başına bir çağrı ve dokuz yüz doksandan iki bin üç yüz altmışa kadar ek belirteçtir; iki koşum farkı anmada 0,0500, üretimde 0,1000 ölçüldü.

Önceki dört ders hattın belge tarafını kurdu: dağarcık hazırlandı, parçalara bölündü, dizinlendi
ve yenilendi. Dördünde de sessiz kalan bir varsayım vardı: **sorgu, kullanıcının yazdığı biçimiyle
dizine gider**.

Abone "hangi dilim" yazar, dağarcıkta "kademe esigi" geçer. Boşluğu kapatmanın bir yolu, sorguyu
dizine göndermeden önce bir modele verip **belge diline çevirtmektir**; bedeli sorgu başına bir
çağrıdır. Dönüştürme **tek adımlıdır**; sonucu görüp yeniden sorgulamak M28/K05'in konusudur.

- **EH41.** Kod bir **benzeticidir**; gerçek bir gömme ya da model uç noktası çağrılmaz. Dağarcık,
  kavramlar, sorgular ve kullanıcı yazımları **kurgudur**, tohum **20260218**.
- **EH42. Hedef iki parçalıdır.** Sorgunun hedefi hem bir **kavram** hem bir **kayıt türüdür**;
  parça ancak ikisini birden taşıyorsa ilgilidir. **Anma@k** ilk k içinde ilgili parça bulunan
  sorgu payı, **kesinlik@k** ilk k'nın ilgili olan payıdır.
- **EH43.** Hat, `gommeler/06`'da ölçülen **karma aramayı** kullanır: açı benzerliğinin yanına
  belirteç örtüşmesi eklenir. Yordamı tekrarlanmaz, ağırlık sabittir. Bu dersin tabanı
  **dönüştürmesiz erişimdir**; erişimsiz çağrının tabanı `erisim-hatti/01`'de kuruldu.
- **EH44.** Üretim benzeticisi bağlamdaki parçalardan birini seçer ve kodunu alıntılar; parçanın
  **yeri** ağırlığı değiştirir. O ağırlık `erisim-hatti/07`'nin konusudur, burada sabittir.
- **EH45.** Aynı kırk sorgunun iki yazımı ölçülür: **kısa yazım** abonenin yazdığı kısaltılmış
  biçim, **uzun yazım** aynı sorunun bağlam cümleleriyle uzatılmışı. Hedef ikisinde de aynıdır.
- **EH46.** Dönüştürme hız sınırına takılırsa hat **ham sorguya döner**; başarısız çağrının
  belirteci yine sayılır.

#### Hat ve Hedef

Hat parça düzeyinde çalışır. Aşağıdaki blok dağarcığı, gömme benzeticisini, karma getirmeyi ve
üretim benzeticisini kurar; sonra sorgu **dizinin tanıdığı biçimde** yazıldığında hattın nerede
durduğunu basar: dönüştürmenin ulaşabileceği üst sınır.

```python
# BENZETICI -- KURGUDUR. Gercek bir gomme ya da model uc noktasi cagrilmaz; dagarcik,
# kavramlar ve sorgular kurgudur, tohum 20260218.
import math
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# ---- hat: parcalar, karma getirme, hedef tanimi ve uretim
PARCA = [{"kod": d["kod"], "ana": d["ana"], "metin": p} for d in BELGE for p in d["par"]]
for p in PARCA:
    p["vek"], p["bel"] = gom(p["metin"]), set(belirtecle(p["metin"]))
for s in SORGU:
    s["kayit"] = s["metin"].split()[-1]


def getir(q, k=5, w=0.5):
    qv, qb = gom(q), set(belirtecle(q))
    s = sorted(((aci(qv, p["vek"]) + w * len(qb & p["bel"]) / len(qb | p["bel"]), i)
                for i, p in enumerate(PARCA)), key=lambda t: (-t[0], t[1]))
    return [PARCA[i] for _, i in s[:k]]


def ilgili(s, p):
    return KAVRAM[s["kavram"]][1] in p["metin"] and s["kayit"] in p["bel"]


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


PENCERE = 240
SAYAC = [0]
YON_Y = "Asagidaki parcalara bakarak yanitla ve kullandigin parcanin kodunu yaz . "


def yanitla(sorgu, parcalar, tohum=TOHUM, sicaklik=0.12):
    """KURGU uretim: baglamdan bir parca secilir, parcanin YERI agirligi degistirir."""
    SAYAC[0] += 1
    istem = YON_Y + " ".join(f"[{p['kod']}] {p['metin']} ." for p in parcalar) + " Soru: " + sorgu
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "parca": None}
    r, qb, n = uretec(tohum ^ izno(istem)), set(belirtecle(sorgu)), len(parcalar)
    p = [(1.0 if i == 0 else 0.8 if i == n - 1 else 0.45) * (0.3 + len(qb & x["bel"]) / len(qb))
         for i, x in enumerate(parcalar)]
    w = [math.exp(a / sicaklik) for a in p]
    se = parcalar[ayrik(r(), [a / sum(w) for a in w])]
    return {"durum": "tamam", "giris": len(bel), "parca": se,
            "cikis": len(belirtecle(f"{se['kod']} : {se['metin']}"))}


a = u = 0
for s in SORGU:
    g = getir(s["metin"], 5)
    a += any(ilgili(s, p) for p in g)
    u += ilgili(s, yanitla(s["metin"], g)["parca"])
print("dagarcik %d belge %d parca ; ortalama parca %.1f belirtec ; ornek sorgu %r"
      % (len(BELGE), len(PARCA), sum(len(p["bel"]) for p in PARCA) / len(PARCA),
         SORGU[0]["metin"]))
print("hedef parca kumesi ortalama %.1f parca"
      % (sum(len([p for p in PARCA if ilgili(s, p)]) for s in SORGU) / 40))
print("dizin dilinde yazilmis sorgu  k=5  anma %.4f  uretim %.4f" % (a / 40, u / 40))
```

```
dagarcik 200 belge 693 parca ; ortalama parca 15.3 belirtec ; ornek sorgu 'nasil kaydediliyor form'
hedef parca kumesi ortalama 8.9 parca
dizin dilinde yazilmis sorgu  k=5  anma 0.8000  uretim 0.7000
```

Hedef kümesi ortalama **8,9** parçadır, altı yüz doksan üçün yüzde birinin biraz üstü. Sorgu dizin dilinde
yazıldığında ilk beş parça bu kümeden birini **0,8000** payla getiriyor, üretim bunun
**0,7000**'ini yanıta çeviriyor.

#### İki Yazım ve Dönüştürücü

Abone bu cümleleri yazmaz. "nasil kaydediliyor form" bir dizin sorgusudur; abone "kaydediliyor mu
form" yazar ya da derdini uzun uzun anlatır. Aşağıdaki blok aynı kırk hedefin iki yazımını kurar
ve üç kurulumu ikisinde de koşturur: **taban** (ham sorgu), **genişletme** (üzerine belge dilindeki
terim eklenir) ve **yeniden yazma** (ham sorgu atılır, yerine belge dilinde bir cümle konur).

```python
# KURGU: kullanicinin yazdigi kisa bicim -- dizinin tanidigi yuzeyi tasimaz
KISA = {"basamak": "hangi dilim", "birim": "metrekup ucreti", "abonetip": "mesken mi isyeri",
        "gecis": "plan degisimi", "arizakod": "hata kodu", "sizinti": "kacagi olabilir",
        "basinc": "akis zayif", "ekip": "gorevli gelmedi", "endeks": "sayac rakami",
        "okuma": "kaydediliyor mu", "degisim": "cihaz yenilendi", "dogrula": "yanlis girilmis",
        "planli": "onceden duyurulan", "duyuru": "nereden bakarim", "sure": "kac saat surer",
        "geridonus": "tekrar gelir mi", "periyot": "duzenli bakim", "vana": "musluk kapatma",
        "filtre": "temizleme filtresi", "kalib": "olcum kalibrasyonu"}
ONEK = ["gecen hafta", "birkac gundur", "sabahtan beri", "dun aksam"]
BAG = ["bir de sunu soracaktim", "ayrica ilgili birime yazdim", "bu arada merak ettim",
       "daha once de aramistim"]
KISASORGU, UZUNSORGU = [], []
for i, s in enumerate(SORGU):
    r = uretec(TOHUM + 31337 * i)
    y, o2 = ANAHTAR[int(r() * 20)], ORTAK[int(r() * 7)]
    z = ANAHTAR[int(r() * 20)]
    KISASORGU.append(dict(s, metin=f"{KISA[s['kavram']]} {s['kayit']}"))
    UZUNSORGU.append(dict(s, metin=f"{ONEK[int(r() * 4)]} {KAVRAM[y][2]} {o2} "
                                   f"{BAG[int(r() * 4)]} {s['metin']} {KAVRAM[z][2]}"))

SORGU_IZ = {}                       # sorgu dili -> kavram
for k in ANAHTAR:
    for t in belirtecle(KAVRAM[k][2]):
        if len(t) > 3:
            SORGU_IZ.setdefault(t, k)
YON_D = "Sorguyu belge diline cevir . Sorgu: "


def donustur(q, kip, tohum=TOHUM, sicaklik=0.5):
    """KURGU donusturucu: tek adimli bir model cagrisi, dongu ve planlama yok."""
    SAYAC[0] += 1
    bel = belirtecle(YON_D + q)
    if SAYAC[0] % 37 == 0:                       # hiz siniri: ham sorgu
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "metin": q, "kavram": None}
    r, p = uretec(tohum ^ izno(q)), {}
    for t in bel:
        if t in SORGU_IZ:
            p[SORGU_IZ[t]] = p.get(SORGU_IZ[t], 0.0) + 1.0
    if not p:
        return {"durum": "bos", "giris": len(bel), "cikis": 0, "metin": q, "kavram": None}
    a = sorted(p)
    w = [math.exp(p[x] / sicaklik) for x in a]
    k = a[ayrik(r(), [x / sum(w) for x in w])]
    o = next((t for t in bel if t in ORTAK), "")
    y = f"{KAVRAM[k][1]} icin {o} tutulur" if kip == "yeniden yazma" else f"{q} {KAVRAM[k][1]}"
    return {"durum": "tamam", "giris": len(bel), "cikis": len(belirtecle(y)),
            "metin": y, "kavram": k}


def olc(kume, kip, tohum=TOHUM, k=5):
    SAYAC[0] = 0
    an = ur = ca = bt = ds = dk = 0
    for s in kume:
        q = s["metin"]
        if kip != "taban":
            d = donustur(q, kip, tohum)
            q, ca, bt = d["metin"], ca + 1, bt + d["giris"] + d["cikis"]
            ds, dk = ds + (d["durum"] != "tamam"), dk + (d["kavram"] == s["kavram"])
        g = getir(q, k)
        an += any(ilgili(s, p) for p in g)
        y = yanitla(s["metin"], g, tohum)
        ca, bt = ca + 1, bt + y["giris"] + y["cikis"]
        ur += y["parca"] is not None and ilgili(s, y["parca"])
    return an / 40, ur / 40, ca, bt, ds, dk / 40


print("ortalama sorgu: kisa %.1f  uzun %.1f belirtec"
      % (sum(len(belirtecle(s["metin"])) for s in KISASORGU) / 40,
         sum(len(belirtecle(s["metin"])) for s in UZUNSORGU) / 40))
print("sorgu kurulum        anma@5  uretim  cagri  belirtec  dogru kavram  basarisiz")
fark = [0.0, 0.0]
for ad, kume in (("kisa ", KISASORGU), ("uzun ", UZUNSORGU)):
    for kip in ("taban", "genisletme", "yeniden yazma"):
        a, u, c, b, ds, dk = olc(kume, kip)
        a2, u2 = olc(kume, kip, TOHUM + 1)[:2]
        fark = [max(fark[0], abs(a - a2)), max(fark[1], abs(u - u2))]
        print("%s %-14s %.4f  %.4f  %5d  %8d  %12s  %9d"
              % (ad, kip, a, u, c, b, "-" if kip == "taban" else "%.4f" % dk, ds))
print("iki kosum farki (tohum 20260219): anma en cok %.4f  uretim en cok %.4f"
      % (fark[0], fark[1]))
```

```
ortalama sorgu: kisa 4.5  uzun 21.7 belirtec
sorgu kurulum        anma@5  uretim  cagri  belirtec  dogru kavram  basarisiz
kisa  taban          0.3750  0.2000     40      5366             -          0
kisa  genisletme     0.7500  0.7000     80      6356        0.9500          1
kisa  yeniden yazma  0.7500  0.7000     80      6335        0.9500          1
uzun  taban          0.5500  0.3250     40      6166             -          0
uzun  genisletme     0.3500  0.2000     80      8526        0.3500          1
uzun  yeniden yazma  0.2500  0.0500     80      7842        0.3500          1
iki kosum farki (tohum 20260219): anma en cok 0.0500  uretim en cok 0.1000
```

#### Kısa Yazımda Kazanç

Kısa yazımın tabanı **0,3750** anma ve **0,2000** üretimdir. Üst sınırla arasındaki fark hattın
kusuru değil, **sorgunun dizine değmemesidir**: "hangi dilim" hiçbir parçada geçmez, geriye kayıt
türünün örtüşmesi kalır.

Dönüştürme boşluğu kapatıyor. Genişletme anmayı **0,7500**'e, üretimi **0,7000**'e çıkarıyor;
ikisi de iki koşum farkının (0,0500 ve 0,1000) üstünde ve üretim üst sınıra birebir yetişiyor.
Sebep tabloda yazılı: dönüştürücü doğru kavramı **0,9500** payla buluyor.

Genişletme ile yeniden yazmanın burada **aynı** sonucu vermesi rastlantı değildir: ham sorguyu
tutmanın bedeli de kazancı da yoktur, çünkü atılacak bir sinyal yoktur.

#### Uzun Yazımda Kayıp

Uzun yazımın tabanı **0,5500**'dür, kısa yazımınkinden yüksektir: abone derdini uzatırken dizinin
tanıdığı ifadeyi de yazıyor. Dönüştürme tabanı **düşürüyor** — genişletmeyle **0,3500**, yeniden
yazmayla **0,2500** — ve ikisi de iki koşum farkının üstünde, ölçülmüş bir kayıptır.

Nedeni yine doğru kavram sütunundadır: isabet **0,3500**'e iniyor. Uzun sorguda üç kavram yüzeyi
ve iki kayıt türü var; tek adımlı bir çağrı hangisinin asıl soru olduğunu seçmek zorunda ve çoğu
kez yanılıyor. Yanıldığında **genişletme** yanlış bir terim ekler ama ham sorgu yerinde kalır;
**yeniden yazma** doğru olan tek şeyi, abonenin yazdığı ifadeyi siler ve üretim **0,0500**'e
iniyor. Kursun ikinci iddiasının bu derse düşen örneği budur: eklenen düzenek işi kötüleştirdi.

#### Dönüştürmenin Faturası

**Çağrı** sorgu başına birden ikiye, kırktan seksene çıkıyor. **Belirteç** kısa yazımda 5366'dan
6356'ya, uzun yazımda 6166'dan 8526'ya gidiyor; uzun sorguyu bir de modele okutmak hattın en
pahalı satırıdır ve kırk çağrının biri hız sınırına takılıyor. Gecikme **sınıf** olarak sayılır:
hat tek çağrılık bir adımdan **iki aşamalı bir zincire** dönüşüyor. Sorgu başına yirmi beş ek
belirteç anmayı 0,3750'den 0,7500'e çıkarırken, elli dokuz ek belirteç onu 0,5500'den 0,3500'e
indiriyor.

#### Özet

- Sorgunun hedefi hem kavram hem kayıt türüdür; ilk beşte ikisini taşıyan parça bulunma payı
  erişim, o parçanın yanıta dönme payı üretim ölçüsüdür.
- Kullanıcının yazdığı kısa biçim dizine değmediği için taban 0,3750 / 0,2000'dir; dizin dilindeki
  aynı sorgu 0,8000 / 0,7000 veriyor.
- Genişletme kısa yazımda anmayı 0,7500'e, üretimi 0,7000'e çıkarıyor; doğru kavramı bulma payı
  0,9500'dür.
- Uzun yazımda aynı düzenek tabanı 0,5500'den 0,3500'e, yeniden yazma 0,2500'e düşürüyor; doğru
  kavram payı 0,3500'e iner ve yeniden yazma abonenin yazdığı ifadeyi de siler.
- Bedel sorgu başına bir çağrı ve 990 ile 2360 arası ek belirteçtir; hat zincire dönüşür.

#### Sonraki Adım

Bu dersin ölçümleri ilk beş parçayı **birlikte** sayıyor: içinde ilgili bir parça varsa anma
yazılıyor, sıra sorulmuyor. Oysa kesinlik@5 ilk beşin çoğunun ilgisiz olduğunu
söylüyor. Sonraki ders getirmeyi ikiye ayırır: geniş bir aday kümesi toplayan ucuz bir aşama ve
her adayı sorguyla birlikte okuyan pahalı bir aşama.

### Yeniden Sıralama

Source: https://academia.sh/tr/kurslar/rag/yeniden-siralama

Getirmenin iki aşamaya bölünmesi ve ikinci aşamanın kazandırdığı ile ödettiğinin yan yana sayılması: tek aşamalı hatta ilk üçün kesinliği 0,4167'de kalıyor, çünkü tek bir benzerlik puanı sorgunun kavramı ile kayıt türünü aynı anda arayamıyor. Adayları sorguyla birlikte okuyan ikinci aşama on iki adayda kesinliği 0,8000'e, yirmi dört adayda 0,9000'e çıkarıyor ve üretimi 0,7500'den 1,0000'e taşıyor. Kırk sekiz adayda kesinlik yalnızca 0,0083 artıyor, yani 0,0333'lük iki koşum farkının altında kalıyor; buna karşılık ilk üçün anması 1,0000'den 0,9500'e düşüyor, çağrı sayısı kırktan bin dokuz yüz altmışa, belirteç 4003'ten 71374'e çıkıyor.

Önceki ders sorguyu dizine göndermeden önce düzeltti ve ilk beş parçanın **birlikte** ne kadar iyi
olduğunu saydı. Geriye o beşin içindeki dağılım kaldı: getirilen kümenin **başı** neden dolu
değil ve başını düzeltmek neye mal olur.

Cevabın yarısı puanın kendisindedir. Birinci aşama sorguyu **parçayı görmeden** bir vektöre
sıkıştırır; bu vektör "şu kavramı ara" diyebilir, ama "şu kavramı **ve** şu kayıt türünü birlikte
ara" diyemez, çünkü tek bir benzerlik sayısı iki koşulun kesişimini taşımaz. **İkinci aşama**
sorgu ile parçayı **birlikte** okur ve iki koşulu ayrı ayrı arayabilir. Bedeli açıktır: her aday
için bir çağrı.

- **EH47.** Kod bir **benzeticidir**; gerçek bir gömme, sıralayıcı ya da model uç noktası
  çağrılmaz. Dağarcık, kavramlar ve sorgular **kurgudur**, tohum **20260218**.
- **EH48.** Hedefin tanımı `erisim-hatti/05`'ten sürer: sorgunun hedefi hem bir **kavram** hem bir
  **kayıt türüdür**, parça ancak ikisini birden taşıyorsa ilgilidir. Hat da aynıdır.
- **EH49.** Bu ders **dönüştürme adımını kapatır** ve sorgu kümesini tanımlandığı biçimiyle alır;
  ölçülen tek düzenek yeniden sıralamadır. Dönüştürmenin bedeli `05`'te ölçüldü.
- **EH50.** Yeniden sıralayıcı **aday başına bir model çağrısıdır** ve sorgu ile parçayı tek
  istemde görür. Puanı iki koşulun toplamıdır: kavram ortaklığı ve kayıt türü ortaklığı.
- **EH51.** Sıralayıcı da bir modeldir, puanı **gürültülüdür**. Gürültünün genliği bir koşulun
  ağırlığını aşar, yani tek koşulluk bir farkı her zaman göremez.
- **EH52.** Bağlama giren parça sayısı **üçte sabittir**; k'nın kendisi ve bağlam sınırı
  `erisim-hatti/07`'nin konusudur.
- **EH53.** Gecikme **sınıf** olarak yazılır. Adaylar birbirinden bağımsız puanlandığı için paralel
  çağrılabilir, ama aşamaların sırası zorunludur: birinci bitmeden ikincisi başlayamaz.

#### Tek Aşamanın Sınırı

Aşağıdaki blok hattı kurar ve tek aşamalı getirmede k büyüdükçe anma ile kesinliğin ne yaptığını
basar. İki sütun **zıt yönlere** gider; aradaki gerilim bu dersin sebebidir.

```python
# BENZETICI -- KURGUDUR. Gercek bir gomme ya da model uc noktasi cagrilmaz; dagarcik,
# kavramlar ve sorgular kurgudur, tohum 20260218.
import math
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# ---- hat: parcalar, karma getirme, hedef tanimi ve uretim
PARCA = [{"kod": d["kod"], "ana": d["ana"], "metin": p} for d in BELGE for p in d["par"]]
for p in PARCA:
    p["vek"], p["bel"] = gom(p["metin"]), set(belirtecle(p["metin"]))
for s in SORGU:
    s["kayit"] = s["metin"].split()[-1]


def getir(q, k=5, w=0.5):
    qv, qb = gom(q), set(belirtecle(q))
    s = sorted(((aci(qv, p["vek"]) + w * len(qb & p["bel"]) / len(qb | p["bel"]), i)
                for i, p in enumerate(PARCA)), key=lambda t: (-t[0], t[1]))
    return [PARCA[i] for _, i in s[:k]]


def ilgili(s, p):
    return KAVRAM[s["kavram"]][1] in p["metin"] and s["kayit"] in p["bel"]


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


PENCERE = 240
SAYAC = [0]
YON_Y = "Asagidaki parcalara bakarak yanitla ve kullandigin parcanin kodunu yaz . "


def yanitla(sorgu, parcalar, tohum=TOHUM, sicaklik=0.12):
    """KURGU uretim: baglamdan bir parca secilir, parcanin YERI agirligi degistirir."""
    SAYAC[0] += 1
    istem = YON_Y + " ".join(f"[{p['kod']}] {p['metin']} ." for p in parcalar) + " Soru: " + sorgu
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "parca": None}
    r, qb, n = uretec(tohum ^ izno(istem)), set(belirtecle(sorgu)), len(parcalar)
    p = [(1.0 if i == 0 else 0.8 if i == n - 1 else 0.45) * (0.3 + len(qb & x["bel"]) / len(qb))
         for i, x in enumerate(parcalar)]
    w = [math.exp(a / sicaklik) for a in p]
    se = parcalar[ayrik(r(), [a / sum(w) for a in w])]
    return {"durum": "tamam", "giris": len(bel), "parca": se,
            "cikis": len(belirtecle(f"{se['kod']} : {se['metin']}"))}


print("dagarcik %d belge %d parca ; hedef parca kumesi ortalama %.1f parca"
      % (len(BELGE), len(PARCA),
         sum(len([p for p in PARCA if ilgili(s, p)]) for s in SORGU) / 40))
print("tek asamali getirme:  k  anma@k  kesinlik@k")
for k in (1, 3, 5, 10, 20, 40):
    a = sum(any(ilgili(s, p) for p in getir(s["metin"], k)) for s in SORGU) / 40
    e = sum(sum(ilgili(s, p) for p in getir(s["metin"], k)) / k for s in SORGU) / 40
    print("                     %2d  %.4f  %.4f" % (k, a, e))
```

```
dagarcik 200 belge 693 parca ; hedef parca kumesi ortalama 8.9 parca
tek asamali getirme:  k  anma@k  kesinlik@k
                      1  0.7750  0.7750
                      3  0.7750  0.4167
                      5  0.8000  0.2700
                     10  0.9750  0.2400
                     20  1.0000  0.2250
                     40  1.0000  0.1775
```

Anma kırk sorgunun tamamını yakalamak için **yirmi** parça istiyor. Kesinlik ise tam tersini
söylüyor: k yirmi olduğunda ilk yirminin yalnızca **0,2250**'si ilgilidir, yani her doğru parçanın
yanında üç buçuk yanlış parça bağlama girer. k üçte kesinlik **0,4167**, ama anma **0,7750**'de
kalır ve sorguların dörtte biri hiç doğru parça görmez.

Bu iki sütunu aynı anda iyileştirmenin tek aşamalı bir hatta yolu yoktur, çünkü sıra tek bir
puandan çıkar. Yeniden sıralama şunu önerir: **anmayı geniş bir aday kümesinden al, kesinliği
ikinci bir puanlayıcıdan.**

#### İkinci Aşama

Aşağıdaki blok sıralayıcıyı tanımlar ve aday sayısını üçten kırk sekize çıkararak aynı kırk
sorguyu beş kez koşturur. Bağlama giren parça sayısı hep üçtür; değişen tek şey, o üçün **kaç
aday arasından** seçildiğidir.

```python
YON_S = "Sorgu ile parca ayni kaydi anlatiyor mu . Parca: "
IZ = {}                              # iki dilin belirtecleri de ayni kavrama baglanir
for k in ANAHTAR:
    for m in (KAVRAM[k][1], KAVRAM[k][2]):
        for t in belirtecle(m):
            if len(t) > 3:
                IZ.setdefault(t, k)


def sirala(q, p, tohum=TOHUM, gurultu=1.4):
    """KURGU ikinci asama: sorgu ile parcayi BIRLIKTE gorur, iki kosulu ayri ayri arar."""
    SAYAC[0] += 1
    bel = belirtecle(YON_S + p["metin"] + " Sorgu: " + q)
    r, qb = uretec(tohum ^ izno(q + p["metin"])), set(belirtecle(q))
    kavram = bool({IZ[t] for t in qb if t in IZ} & {IZ[t] for t in p["bel"] if t in IZ})
    kayit = bool(qb & p["bel"] & set(ORTAK))
    return 1.0 * kavram + 1.0 * kayit + gurultu * (r() - 0.5), len(bel) + 1


def olc(N, tohum=TOHUM, k=3):
    SAYAC[0] = 0
    an = ke = ur = ca = bt = 0
    for s in SORGU:
        aday = getir(s["metin"], max(N, k))
        if N > k:
            pu = []
            for p in aday:
                v, b = sirala(s["metin"], p, tohum)
                pu.append(v)
                ca, bt = ca + 1, bt + b
            aday = [p for _, p in sorted(zip(pu, aday), key=lambda t: -t[0])]
        ilk = aday[:k]
        an += any(ilgili(s, p) for p in ilk)
        ke += sum(ilgili(s, p) for p in ilk) / k
        y = yanitla(s["metin"], ilk, tohum)
        ca, bt = ca + 1, bt + y["giris"] + y["cikis"]
        ur += ilgili(s, y["parca"])
    return an / 40, ke / 40, ur / 40, ca, bt


print("aday  anma@3  kesinlik@3  uretim  cagri  belirtec  gecikme sinifi")
onceki, fark = None, [0.0, 0.0, 0.0]
for N in (3, 6, 12, 24, 48):
    a, e, u, c, b = olc(N)
    i = olc(N, TOHUM + 1)
    fark = [max(f, abs(x - y)) for f, x, y in zip(fark, (a, e, u), i[:3])]
    print("%4d  %.4f  %.4f      %.4f  %5d  %8d  %s"
          % (N, a, e, u, c, b, "tek asama" if N == 3 else "iki asama, %d ek cagri" % N))
print("iki kosum farki (tohum 20260219): anma %.4f  kesinlik %.4f  uretim %.4f" % tuple(fark))
```

```
aday  anma@3  kesinlik@3  uretim  cagri  belirtec  gecikme sinifi
   3  0.7750  0.4167      0.7500     40      4003  tek asama
   6  0.8000  0.4917      0.7250    280     12424  iki asama, 6 ek cagri
  12  0.9750  0.8000      0.9500    520     20851  iki asama, 12 ek cagri
  24  1.0000  0.9000      1.0000   1000     37689  iki asama, 24 ek cagri
  48  0.9500  0.9083      0.9500   1960     71374  iki asama, 48 ek cagri
iki kosum farki (tohum 20260219): anma 0.0250  kesinlik 0.0333  uretim 0.0500
```

#### Aday Sayısı Büyüdükçe

İlk satır tabandır: yeniden sıralama yok, ilk üç doğrudan bağlama giriyor, kesinlik **0,4167**,
üretim **0,7500**, kırk çağrı.

Altı adayda kesinlik **0,4917**'ye çıkıyor. Kazanç 0,0750 ve iki koşum farkının (0,0333) üstünde,
yani gerçek; ama karşılığında çağrı **kırktan iki yüz seksene**, belirteç 4003'ten 12424'e gidiyor.
Üretim bu satırda **0,7250**'ye düşüyor, düşüş 0,0250 ve üretimin iki koşum farkı 0,0500 olduğu
için bu satır "üretimi düşürdü" diye okunamaz; **bu ölçümle bilinemez** diye okunur.

On iki adayda tablo değişiyor: kesinlik **0,8000**, anma **0,9750**, üretim **0,9500**. Tabana
göre kesinlikte 0,3833, üretimde 0,2000 kazanç var ve ikisi de eşiğin çok üstünde. Yirmi dört
adayda anma **1,0000**, kesinlik **0,9000**, üretim **1,0000** oluyor; bu kurulum kırk sorgunun
hepsinde doğru parçayı bağlamın içine ve yanıtın kaynağına koyuyor.

Bedel tarafında aynı satır **bin çağrı** ve **37689 belirteç** yazıyor. Taban kırk çağrıydı; yirmi
beş kat. Gecikme sınıfı da değişti: hat tek aşamadan **iki aşamaya** geçti ve ikinci aşama aday
sayısıyla ölçekleniyor. Adaylar paralel puanlanabilir, ama birinci aşama bitmeden hiçbiri
başlayamaz, yani zincirin uzunluğu iki adımda sabit kalırken **genişliği** yirmi dörde çıkıyor.

#### Ölçülemeyen Kazanç ve Ölçülen Kayıp

Son satır bu dersin asıl bulgusudur. Aday sayısı yirmi dörtten kırk sekize çıkarıldığında kesinlik
0,9000'den **0,9083**'e gidiyor. Kazanç **0,0083**, iki koşum farkının **dörtte biri**. Bu satır
"kesinliği artırdı" diye yazılamaz; **artırıp artırmadığı bu ölçümle bilinemez**. Karşılığında
ödenen ise ölçülmüştür: çağrı 1000'den **1960**'a, belirteç 37689'dan **71374**'e çıkıyor.

Aynı satırda ölçülebilen bir şey daha var ve yönü terstir. İlk üçün anması **1,0000'den
0,9500**'e düşüyor; düşüş 0,0500 ve anmanın iki koşum farkı 0,0250, yani **gerçek**. Üretim de
1,0000'den 0,9500'e iniyor. Aday kümesi büyüdükçe gürültülü sıralayıcının önüne daha çok yanlış
parça geliyor ve bunlardan birini ilk üçe taşıma olasılığı artıyor. Sıralayıcının gürültüsü bir
koşulluk farkı örtebildiği için, kalabalıkta bir yanlış adayın doğru adayı geçmesi kaçınılmaz
hâle geliyor.

Kursun ikinci iddiasının bu derse düşen örneği budur: **erişim düzeneğini büyütmek işi
kötüleştirdi**. Doğru okuma, en yüksek kesinlik satırını seçmek değil, kazancın eşiğin altına
düştüğü yeri bulup orada durmaktır. Bu iş yükünde o yer **yirmi dört adaydır**.

#### Özet

- Tek bir benzerlik puanı sorguyu parçayı görmeden sıkıştırdığı için kavram ile kayıt türünü
  birlikte arayamaz; anma yirmi parça isterken kesinlik ilk üçte 0,4167'de kalır.
- Adayları sorguyla birlikte okuyan ikinci aşama on iki adayda kesinliği 0,8000'e, yirmi dört
  adayda 0,9000'e, üretimi 0,7500'den 1,0000'e çıkarır.
- Bedel aday başına bir çağrıdır: kırk çağrı ve 4003 belirteç, yirmi dört adayda 1000 çağrı ve
  37689 belirtece çıkar; gecikme sınıfı tek aşamadan iki aşamaya geçer.
- Kırk sekiz adayda kesinlik yalnızca 0,0083 artar ve 0,0333'lük iki koşum farkının altında kalır;
  bu satır kazandırdı diye okunamaz.
- Aynı satırda ilk üçün anması 1,0000'den 0,9500'e düşer ve bu düşüş 0,0250'lik eşiğin üstündedir:
  aday kümesini büyütmek gürültülü sıralayıcıya daha çok yanlış aday sunar.

#### Sonraki Adım

Bu dersin bütün kurulumlarında bağlama **üç** parça girdi ve hep aynı sırada, yani sıralayıcının
verdiği sırada girdi. İki sayı bu seçimin sorgulanmadığını gösteriyor: üç parça bağlamın sınırının
neresinde duruyor ve o üç parçanın **sırası** yanıtı değiştiriyor mu. Sonraki ders bağlam sınırına
kaç parçanın sığdığını sayar, sınır aşıldığında hattın ne yaptığını gösterir ve aynı parçaları
farklı sıralarda vererek yanıtın değişme payını ölçer.

### Bağlam Kurma

Source: https://academia.sh/tr/kurslar/rag/baglam-kurma

Getirilen parçaların isteme yerleştirilmesi ve bu yerleştirmenin kendi başına bir düzenek olduğunun ölçülmesi: iki yüz kırk belirteçlik pencereye yönerge ve sorgudan sonra 11,3 parça sığıyor, on birinci parçada kırk sorgunun on dördü, on üçüncüde hepsi sınırı aşıyor. Parça sayısı birden ona çıkarıldığında erişim anması 0,7750'den 0,9750'e yükselirken üretim 0,7750'den 0,4750'ye düşüyor. Bağlamda hep bir ilgili parça bırakılıp yanına dört ilgisiz parça konduğunda üretim ilgili parça başta 0,7500, sonda 0,5250, ortada 0,1000 oluyor ve aynı parçaların sırası değiştiğinde yanıtların 0,9250'si değişiyor; aynı sırada tohum değiştirildiğinde değişen pay 0,3750'dir.

Önceki iki ders neyin getirileceğini düzeltti: sorgu dizin diline çevrildi, adaylar ikinci bir
aşamada yeniden sıralandı. İkisinde de getirilen parçalar isteme **sıralandıkları gibi** ve
**kaç tane isteniyorsa o kadar** konuldu. Bu ders o adımı ölçer, çünkü bağlamı kurmak da bir
düzenektir ve iki kısıtı vardır.

Birincisi **sınırdır**: bağlam penceresi sabittir ve parça sayısı onu aşınca istek yanıtsız döner.
İkincisi **sıradır**: aynı parçalar aynı istemde farklı yerlere konduğunda modelin hangisine
baktığı değişir. Bu derste ayrıca her yanıt kullandığı parçanın kodunu **alıntılar**; kaynağa
bağlama, hatanın hangi yarıda olduğunu okunur kılar.

- **EH54.** Kod bir **benzeticidir**; gerçek bir gömme ya da model uç noktası çağrılmaz. Dağarcık,
  kavramlar ve sorgular **kurgudur**, tohum **20260218**.
- **EH55.** Hedef tanımı ve hat `erisim-hatti/05`'ten sürer. Dönüştürme ve yeniden sıralama
  **kapalıdır**; ölçülen tek düzenek bağlamın kurulmasıdır.
- **EH56.** Bağlam penceresi **240 belirteçtir**. Pencerenin tanımı M28/K01'de yapıldı ve
  tekrarlanmaz; burada bir **kısıt** olarak kullanılır.
- **EH57.** Her parça bağlama **kodu ile** girer ve yanıt kullandığı parçanın kodunu alıntılar.
  Benzetici yanıtı seçtiği parçadan kurduğu için **kaynağa sadakat tanım gereği tamdır**; ölçülen
  şey **alıntının doğruluğudur**.
- **EH58.** Pencereyi aşan istek yanıtsız döner ve o sorgu **yanlış** sayılır.
- **EH59.** Üretim benzeticisinin **konum ağırlığı** modellenmiştir: ilk parça 1,0, son parça 0,8,
  aradakiler 0,45. Bu dersin ölçtüğü şey bu ağırlığın sonucudur.
- **EH60.** Kontrollü deneyde bağlamda **hep bir ilgili parça** bulunur ve yanına j ilgisiz parça
  konur; böylece erişim sabitlenir ve yalnız bağlam ölçülür.
- **EH61. Değişme payı**, aynı parçalar farklı sırada verildiğinde **alıntılanan parçanın** değişme
  payıdır. Karşılaştırma tabanı, sıra sabitken tohumun değiştiği koşumdur.

#### Bağlam Bütçesi

Bir istemin bütçesi üç kalemden oluşur: yönerge, sorgu ve parçalar. İlk ikisi sabittir, üçüncüsü
k ile büyür. Aşağıdaki blok hattı kurar, bütçeyi çıkarır ve k'yı birden on üçe kadar artırarak
erişim ile üretimi yan yana basar.

```python
# BENZETICI -- KURGUDUR. Gercek bir gomme ya da model uc noktasi cagrilmaz; dagarcik,
# kavramlar ve sorgular kurgudur, tohum 20260218.
import math
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# ---- hat: parcalar, karma getirme, hedef tanimi ve uretim
PARCA = [{"kod": d["kod"], "ana": d["ana"], "metin": p} for d in BELGE for p in d["par"]]
for p in PARCA:
    p["vek"], p["bel"] = gom(p["metin"]), set(belirtecle(p["metin"]))
for s in SORGU:
    s["kayit"] = s["metin"].split()[-1]


def getir(q, k=5, w=0.5):
    qv, qb = gom(q), set(belirtecle(q))
    s = sorted(((aci(qv, p["vek"]) + w * len(qb & p["bel"]) / len(qb | p["bel"]), i)
                for i, p in enumerate(PARCA)), key=lambda t: (-t[0], t[1]))
    return [PARCA[i] for _, i in s[:k]]


def ilgili(s, p):
    return KAVRAM[s["kavram"]][1] in p["metin"] and s["kayit"] in p["bel"]


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


PENCERE = 240
SAYAC = [0]
YON_Y = "Asagidaki parcalara bakarak yanitla ve kullandigin parcanin kodunu yaz . "


def yanitla(sorgu, parcalar, tohum=TOHUM, sicaklik=0.12):
    """KURGU uretim: baglamdan bir parca secilir, parcanin YERI agirligi degistirir."""
    SAYAC[0] += 1
    istem = YON_Y + " ".join(f"[{p['kod']}] {p['metin']} ." for p in parcalar) + " Soru: " + sorgu
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "parca": None}
    r, qb, n = uretec(tohum ^ izno(istem)), set(belirtecle(sorgu)), len(parcalar)
    p = [(1.0 if i == 0 else 0.8 if i == n - 1 else 0.45) * (0.3 + len(qb & x["bel"]) / len(qb))
         for i, x in enumerate(parcalar)]
    w = [math.exp(a / sicaklik) for a in p]
    se = parcalar[ayrik(r(), [a / sum(w) for a in w])]
    return {"durum": "tamam", "giris": len(bel), "parca": se,
            "cikis": len(belirtecle(f"{se['kod']} : {se['metin']}"))}


def kur(sorgu, parcalar):
    return (YON_Y + " ".join(f"[{p['kod']}] {p['metin']} ." for p in parcalar)
            + " Soru: " + sorgu)


op = sum(len(belirtecle(f"[{p['kod']}] {p['metin']} .")) for p in PARCA) / len(PARCA)
os_ = sum(len(belirtecle(s["metin"])) for s in SORGU) / 40
print("pencere %d ; yonerge %d + sorgu %.1f + parca basina %.1f belirtec -> sigan parca %.1f"
      % (PENCERE, len(belirtecle(YON_Y)), os_, op, (PENCERE - len(belirtecle(YON_Y)) - os_) / op))
print(" k  baglam ort  en buyuk  asan  anma@k  uretim  alinti kavram  alinti kayit")
for k in (1, 3, 5, 8, 10, 11, 12, 13):
    bl, an, ur, asan, ak, ay = [], 0, 0, 0, 0, 0
    for s in SORGU:
        g = getir(s["metin"], k)
        bl.append(len(belirtecle(kur(s["metin"], g))))
        an += any(ilgili(s, p) for p in g)
        y = yanitla(s["metin"], g)
        if y["parca"] is None:
            asan += 1
            continue
        ak += KAVRAM[s["kavram"]][1] in y["parca"]["metin"]
        ay += s["kayit"] in y["parca"]["bel"]
        ur += ilgili(s, y["parca"])
    print("%2d  %9.1f  %8d  %4d  %.4f  %.4f  %12.4f  %12.4f"
          % (k, sum(bl) / 40, max(bl), asan, an / 40, ur / 40, ak / 40, ay / 40))
```

```
pencere 240 ; yonerge 18 + sorgu 4.8 + parca basina 19.3 belirtec -> sigan parca 11.3
 k  baglam ort  en buyuk  asan  anma@k  uretim  alinti kavram  alinti kayit
 1       43.1        46     0  0.7750  0.7750        1.0000        0.7750
 3       81.8        88     0  0.7750  0.7500        1.0000        0.7500
 5      120.5       130     0  0.8000  0.7000        0.9500        0.7000
 8      178.4       193     0  0.8500  0.6500        1.0000        0.6500
10      217.0       235     0  0.9750  0.4750        0.9500        0.4750
11      236.3       256    14  0.9750  0.4750        0.6500        0.4750
12      255.7       277    32  0.9750  0.0750        0.2000        0.0750
13      275.2       298    40  0.9750  0.0000        0.0000        0.0000
```

#### Anma Yükselirken Üretim Düşüyor

Bütçe hesabı **11,3 parça** diyor ve tablo bunu doğruluyor: on parçaya kadar hiçbir istek sınırı
aşmıyor, on birde kırk sorgunun **on dördü**, on ikide **otuz ikisi**, on üçte **hepsi** aşıyor.
Ortalama bağlam on üçüncü parçada 275,2 belirteçtir, en büyüğü 298. Sınır ortalamaya değil **en
büyüğe** çarpar; ortalama 236,3 iken bile on dört istek yanıtsız döner.

Asıl bulgu iki sütunun **zıt yönlere** gitmesidir. k birden ona çıktığında erişim anması
**0,7750'den 0,9750'e** yükseliyor, üretim ise **0,7750'den 0,4750'ye** düşüyor. Erişim ölçüsüne
bakan bir plan k'yı büyütür ve iyileştiğini sanır; üretim ölçüsü tersini söyler. Kursun kuralının
neden iki sütun istediği bu satırlarda görünür.

Son iki sütun hatanın yerini söylüyor. **Alıntı kavram** payı k on olana kadar 0,9500 ile 1,0000
arasında kalıyor: model neredeyse her zaman doğru kavramı anlatan bir parçayı alıntılıyor.
**Alıntı kayıt** payı ise üretimle birlikte 0,4750'ye iniyor. Yani hata kavramda değil, **kayıt
türünde**. Sınır aşıldığında ikisi birden çöküyor, çünkü artık hiç yanıt yok. Bu ayrımı okunur
kılan şey alıntının kendisidir; yanıt yalnız metin olsaydı iki hata türü tek sayının içinde
kalırdı.

#### Sıranın Payı

k süpürmesi iki şeyi birlikte değiştiriyor: bağlamda kaç parça olduğunu ve ilgili parçanın nerede
durduğunu. Aşağıdaki blok ikincisini yalıtır. Her sorguda bağlama **bir ilgili parça** konur,
yanına j ilgisiz parça eklenir ve aynı küme üç ayrı sırada verilir. Son sütun, sıra sabitken
yalnız tohumun değiştiği koşumu taban olarak basar.

```python
def deney(j, tohum=TOHUM):
    """Baglamda hep bir ilgili parca var; yanina j ilgisiz parca uc ayri yerlesimle konuyor."""
    sk, dg, ks = {"bas": 0, "orta": 0, "son": 0}, {"orta": 0, "son": 0}, 0
    for s in SORGU:
        aday = getir(s["metin"], 40)
        iyi = next(p for p in aday if ilgili(s, p))
        kotu = [p for p in aday if not ilgili(s, p)][:j]
        yer = {"bas": [iyi] + kotu, "son": kotu + [iyi],
               "orta": kotu[:j // 2] + [iyi] + kotu[j // 2:]}
        se = {}
        for a in ("bas", "orta", "son"):
            se[a] = yanitla(s["metin"], yer[a], tohum)["parca"]
            sk[a] += se[a] is not None and ilgili(s, se[a])
        for a in ("orta", "son"):
            dg[a] += se[a] is not se["bas"]
        ks += yanitla(s["metin"], yer["bas"], tohum + 1)["parca"] is not se["bas"]
    return [sk[a] / 40 for a in ("bas", "orta", "son")], dg["orta"] / 40, dg["son"] / 40, ks / 40


print("ilgisiz  uretim: basta  ortada  sonda | yanit degisme payi: orta   son   iki kosum")
for j in (0, 2, 4, 8):
    u, do, ds, ks = deney(j)
    print("%7d          %.4f  %.4f  %.4f                      %.4f %.4f %.4f"
          % (j, u[0], u[1], u[2], do, ds, ks))
print("ikinci kosum (tohum 20260219), j=4: basta %.4f ortada %.4f sonda %.4f"
      % tuple(deney(4, TOHUM + 1)[0]))
```

```
ilgisiz  uretim: basta  ortada  sonda | yanit degisme payi: orta   son   iki kosum
      0          1.0000  1.0000  1.0000                      0.0000 0.0000 0.0000
      2          0.9000  0.2000  0.7000                      0.7750 0.3250 0.2000
      4          0.7500  0.1000  0.5250                      0.9250 0.4750 0.3750
      8          0.7250  0.1500  0.4750                      0.8250 0.6500 0.4750
ikinci kosum (tohum 20260219), j=4: basta 0.8750 ortada 0.2250 sonda 0.5750
```

#### İlgisiz Parçanın Bedeli

İlk satır kontrolü kuruyor: bağlamda yalnız ilgili parça varsa üretim **1,0000**'dır ve sıra
hiçbir şey değiştirmez. Bundan sonraki her satırdaki düşüş, eklenen ilgisiz parçaların bedelidir.

İlgili parça **başta** iken sekiz ilgisiz parça üretimi 1,0000'den **0,7250**'ye indiriyor, yani
parça başına ortalama **0,0344**. Aynı parça **ortada** iken 1,0000'den **0,1500**'e iniyor, parça
başına **0,1063**. Düşüşün bir eşiği yok: ilk iki ilgisiz parça bile başta 0,1000, ortada
**0,8000** götürüyor. Bu, `yz-destekli-gelistirme/02`'de ölçülen bulgunun erişim bağlamındaki
karşılığıdır ve buradaki ek bilgi şudur: bedelin büyüklüğü ilgili parçanın **nerede durduğuna**
bağlıdır.

Dört ilgisiz parçalı satır sırayı tek başına okutuyor. Aynı beş parça, aynı tohum, yalnız sıra
farklı: üretim **başta 0,7500**, **sonda 0,5250**, **ortada 0,1000**. Baş ile orta arasındaki fark
**0,6500**'dür. Bu farkın gerçek olup olmadığı son sütunla sınanır: sıra sabitken yalnız tohumun
değiştiği koşumda yanıtların **0,3750**'si değişiyor, sıra değiştiğinde ise **0,9250**'si. İkinci
koşumun aynı satırdaki sayıları da (0,8750 / 0,2250 / 0,5750) aynı sıralamayı veriyor; başta ile
ortada arasındaki fark her iki koşumda da tam 0,6500'dür ve iki koşum farkı en çok 0,1250'dir.

Buradan çıkan kural şudur: **bağlamın sırası bir tasarım kararıdır ve yazılmadan ölçüm
tekrarlanamaz.** Aynı erişim, aynı parçalar ve aynı model, parçaların dizilişi değiştiğinde
üretimde 0,7500 ile 0,1000 arasında salınıyor. Yeniden sıralamanın `erisim-hatti/06`'da 1000
çağrıya satın aldığı kesinlik, parçalar bağlama kötü bir sırada konursa harcanır.

#### Özet

- İki yüz kırk belirteçlik pencereye yönerge ve sorgudan sonra 11,3 parça sığar; on birinci parçada
  kırk sorgunun on dördü, on üçüncüde hepsi sınırı aşar ve yanıtsız döner.
- Sınır ortalama bağlama değil en büyüğüne çarpar: ortalama 236,3 belirteçken bile on dört istek
  pencereyi aşar.
- Parça sayısı birden ona çıktığında erişim anması 0,7750'den 0,9750'e yükselirken üretim
  0,7750'den 0,4750'ye düşer; iki ölçü zıt yönlere gider.
- Alıntı kavram payı 0,9500 ile 1,0000 arasında kalırken alıntı kayıt payı 0,4750'ye iner: hata
  kavramda değil kayıt türündedir ve bu ayrımı okunur kılan şey kaynağa bağlamadır.
- İlgili parça başta iken her ilgisiz parça üretimden ortalama 0,0344, ortada iken 0,1063 götürür
  ve düşüşün eşiği yoktur.
- Aynı beş parça farklı sırada verildiğinde üretim 0,7500 ile 0,1000 arasında oynar ve yanıtların
  0,9250'si değişir; sıra sabitken tohum değiştiğinde değişen pay 0,3750'dir.

#### Sonraki Adım

Yedi derste hat baştan sona kuruldu: dağarcık hazırlandı, parçalandı, dizinlendi, yenilendi, sorgu
dönüştürüldü, adaylar yeniden sıralandı ve bağlam kuruldu. Her ders kendi düzeneğini kendi
sayısıyla savundu, ama bu sayıların hepsi aynı kusuru taşıyor: bir kurulumun **iyi** olması, doğru
parçanın gelmesi ile doğru yanıtın üretilmesinin **aynı sorguda** olması demek değildir. Bu dersin
tablosunda alıntı kavram payı 1,0000 iken üretimin 0,6500 olduğu bir satır var; orada model doğru
kaynağı gösterip yanlış kaydı okudu. Sonraki ders bu dört durumu ayrı ayrı sayar ve tek bir
sayının hangisini gizlediğini gösterir.

### Erişim ve Üretim Kalitesinin Ayrı Ölçülmesi

Source: https://academia.sh/tr/kurslar/rag/degerlendirme

Uçtan uca tek bir doğruluk oranının dört ayrı durumu üst üste yığdığının gösterilmesi: kırk sorguluk kurgu kümede erişimsiz taban 0,3750 çıkıyor ve bu oranın tamamı şans, çünkü doğru parça hiç getirilmiyor. Üç parçalı bağlamda tek sayı 0,9500, beş parçalı bağlamda da 0,9500; ama üçlüde iki başarısızlık erişim kusuru, beşlide aynı iki başarısızlık üretim kusurudur ve tek sayı ikisini ayırt etmez. Erişim anması üçlüde 0,9500, beşlide 1,0000; bedel 120 parça ve 2199 belirteçten 200 parça ve 3505 belirtece çıkıyor. İki koşum farkı erişimsiz tabanda 0,1750, üç parçalı bağlamda 0,0000. Sınıf alt grubu her iki kusurun da aynı sınıfta toplandığını gösteriyor.

Bir önceki derste aynı parçalar farklı sıralarda verildi ve yanıtın değişme payı sayıldı. Hat
artık kurulu: belge hazırlandı, parçalara bölündü, dizinlendi, sorgu tek adımda dönüştürüldü,
adaylar yeniden sıralandı ve bağlam sınıra göre kuruldu. Yedi dersin her biri kendi adımını kendi
sayısıyla savundu.

Bu ders o sayıların birleştiği yerde durur. Bir erişim artırılmış üretim hattı çalıştırıldığında
elde kalan genellikle tek bir orandır: kaç soruya doğru yanıt verildi. Bu dersin iddiası, o tek
oranın **dört ayrı durumu** üst üste yığdığı ve yığının içinden hangi aşamanın bozulduğunun
okunamadığıdır. Değerlendirme yordamının kendisi M27'nin Model Değerlendirme, Yorumlanabilirlik ve
Etik kursunda, model değerlendirme ve alt grup dersleriyle birlikte kuruldu ve burada tekrarlanmaz; oradan devralınan
tek şey **taban çizgisi kuralıdır** ve bu kursta taban **erişimsiz çağrıdır**.

- **EH71.** Dağarcık, kavram ekseni, gömme ve sorgu kümesi **kurgudur** ve ders içinde üretilir.
  Hiçbir gerçek kurum, ürün, belge, vektör deposu ya da gömme ucu yoktur.
- **EH72.** Kavramın **belge dilinde** bir yüzeyi (`kademe esigi`), **sorgu dilinde** başka bir
  yüzeyi (`hangi dilimdeyim`) vardır ve ikisi hiçbir belirteci paylaşmaz.
- **EH73.** **Erişim ölçüsü**: getirilen parçaların içinde hedef yordamın belge yüzeyi geçiyorsa
  erişim doğrudur. Bu ölçü tohumdan bağımsızdır.
- **EH74.** **Üretim ölçüsü**: yanıtta adı geçen yordam hedef yordamsa üretim doğrudur. Yanıt bir
  **dil modeli benzeticisinden** gelir; benzetici gerçek bir uç nokta çağırmaz.
- **EH75.** Benzeticinin **ön bilgisi yalnız sınıf düzeyindedir**. Sorgu dilinden hangi sınıfa ait
  olduğunu çıkarır, o sınıfın dört yordamına eşit ve küçük bir taban puan verir, ama yordam adını
  kendiliğinden bilmez. Bağlamda geçen her yordam adı bir puan ekler.
- **EH76.** **Bedel** üç birimle yazılır: getirilen parça sayısı, isteme giren belirteç ve erişim
  adımı. Süre yazılmaz.

#### Erişim Sütunu: Kanıt Geldi mi

İlk sütun modele hiç bakmaz. Sorulan tek şey, getirilen parçaların hedef yordamı taşıyıp
taşımadığıdır. İki oran yan yana durur: **erişim anması** en az bir doğru parçanın geldiği sorgu
payı, **erişim kesinliği** getirilen parçaların doğru olma payıdır.

```python
# KURGUDUR. Dagarcik, kavram ekseni, gomme ve sorgu kumesi ders icinde uretilir;
# hicbir gercek kurum, urun, belge ya da gomme ucu yoktur.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

PARCA = [{"kod": d["kod"], "sinif": d["sinif"], "metin": p}
         for d in BELGE for p in d["par"]]
PV = [gom(p["metin"]) for p in PARCA]


def getir(q, k):
    v = gom(q)
    s = sorted(range(len(PARCA)), key=lambda i: (-aci(v, PV[i]), i))
    return [PARCA[i] for i in s[:k]]


def erisim_olc(k):
    """Yalniz erisim sutunu: getirilen parcalar hedef yordami tasiyor mu."""
    anma = kesin = 0
    for s in SORGU:
        yuzey = KAVRAM[s["kavram"]][1]
        tasiyan = [p for p in getir(s["metin"], k) if yuzey in p["metin"]]
        anma += 1 if tasiyan else 0
        kesin += len(tasiyan) / k
    return anma / len(SORGU), kesin / len(SORGU)


print(f"dagarcik {len(BELGE)} belge , {len(PARCA)} parca , sorgu {len(SORGU)}")
print("\n  k   erisim anmasi   erisim kesinligi   getirilen parca")
for k in (1, 3, 5):
    a, ke = erisim_olc(k)
    print(f"{k:>3} {a:>15.4f} {ke:>18.4f} {k * len(SORGU):>18}")
```

```
dagarcik 200 belge , 693 parca , sorgu 40

  k   erisim anmasi   erisim kesinligi   getirilen parca
  1          0.9500             0.9500                 40
  3          0.9500             0.9500                120
  5          1.0000             0.9600                200
```

Bir parçadan üçe çıkmak anmayı **oynatmıyor**: 0,9500 aynı kalıyor, getirilen parça sayısı üçe
katlanıyor. Beşe çıkmak anmayı **1,0000** yapıyor, yani kanıt artık her sorguda bağlamın içinde.
Erişim sütunu bu kadarını söyler ve daha fazlasını söyleyemez: parçanın **geldiğini** bilir,
kullanıldığını bilmez.

#### Üretim Sütunu ve Dört Durum

İkinci sütun aynı sorguları bir **dil modeli benzeticisiyle** çalıştırır. Benzetici gerçek bir uç
nokta çağırmaz; bağlamda geçen yordam adlarını puanlar, sorgunun sınıfını tanıyıp o sınıfın dört
yordamına küçük bir taban puan verir ve dağılım sıcaklığıyla örnekler. İki sütun kesiştiğinde her
sorgu dört kutudan birine düşer.

```python
from math import exp


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


def uret(q, parcalar, tohum=TOHUM, sicaklik=0.6):
    """KURGU dil modeli benzeticisi. Baglamda gecen yordam adlarini puanlar;
    on bilgisi yalniz sinif duzeyindedir, yordam adini bilmez."""
    istem = q + " || " + " ".join(p["metin"] for p in parcalar)
    dm, sq = " " + istem.lower() + " ", " " + q.lower() + " "
    sn = next((KAVRAM[k][0] for k in ANAHTAR if KAVRAM[k][2] in sq), None)
    puan = {}
    for k in ANAHTAR:
        p = (0.15 if KAVRAM[k][0] == sn else 0.0) + dm.count(KAVRAM[k][1])
        if p:
            puan[k] = p
    if not puan:
        return None, istem
    ad = list(puan)
    a = [exp(puan[k] / sicaklik) for k in ad]
    t = sum(a)
    return ad[ayrik(uretec(tohum ^ izno(istem))(), [x / t for x in a])], istem


def kosum(k, tohum=TOHUM):
    d = {"dd": 0, "dy": 0, "yd": 0, "yy": 0, "bel": 0}
    for s in SORGU:
        par = getir(s["metin"], k) if k else []
        yanit, istem = uret(s["metin"], par, tohum)
        d["bel"] += len(belirtecle(istem))
        dp = any(KAVRAM[s["kavram"]][1] in p["metin"] for p in par)
        dy = yanit == s["kavram"]
        d["dd" if dp and dy else "dy" if dp else "yd" if dy else "yy"] += 1
    return d


n = len(SORGU)
print("kurulum     dogru+dogru  dogru+yanlis  yanlis+dogru  yanlis+yanlis"
      "   tek sayi  belirtec")
for ad, k in (("erisimsiz", 0), ("k = 1", 1), ("k = 3", 3), ("k = 5", 5)):
    d = kosum(k)
    print(f"{ad:<11} {d['dd']:>11} {d['dy']:>13} {d['yd']:>13} {d['yy']:>14}"
          f" {(d['dd'] + d['yd']) / n:>10.4f} {d['bel']:>9}")

print("\nikinci kosum (tohum 20260219) , tek sayi ve kosum farki")
for ad, k in (("erisimsiz", 0), ("k = 1", 1), ("k = 3", 3), ("k = 5", 5)):
    a = (lambda d: (d["dd"] + d["yd"]) / n)(kosum(k))
    b = (lambda d: (d["dd"] + d["yd"]) / n)(kosum(k, TOHUM + 1))
    print(f"{ad:<11} {a:>7.4f} {b:>9.4f} {b - a:>+10.4f}")

print("\nsinif alt grubu (dogru+dogru / dogru+yanlis / yanlis+dogru / yanlis+yanlis)")
print(f"{'sinif':<9} {'k = 3':>16} {'k = 5':>16}")
for sn in SINIF:
    sat = []
    for k in (3, 5):
        c = [0, 0, 0, 0]
        for s in SORGU:
            if s["sinif"] != sn:
                continue
            par = getir(s["metin"], k)
            y, _ = uret(s["metin"], par)
            dp = any(KAVRAM[s["kavram"]][1] in p["metin"] for p in par)
            c[0 if dp and y == s["kavram"] else 1 if dp else 2 if y == s["kavram"] else 3] += 1
        sat.append(" / ".join(str(x) for x in c))
    print(f"{sn:<9} {sat[0]:>16} {sat[1]:>16}")
```

```
kurulum     dogru+dogru  dogru+yanlis  yanlis+dogru  yanlis+yanlis   tek sayi  belirtec
erisimsiz             0             0            15             25     0.3750       231
k = 1                33             5             0              2     0.8250       887
k = 3                38             0             0              2     0.9500      2199
k = 5                38             2             0              0     0.9500      3505

ikinci kosum (tohum 20260219) , tek sayi ve kosum farki
erisimsiz    0.3750    0.2000    -0.1750
k = 1        0.8250    0.9250    +0.1000
k = 3        0.9500    0.9500    +0.0000
k = 5        0.9500    0.9500    +0.0000

sinif alt grubu (dogru+dogru / dogru+yanlis / yanlis+dogru / yanlis+yanlis)
sinif                k = 3            k = 5
tarife       8 / 0 / 0 / 0    8 / 0 / 0 / 0
ariza        7 / 0 / 0 / 2    7 / 2 / 0 / 0
sayac       10 / 0 / 0 / 0   10 / 0 / 0 / 0
kesinti      6 / 0 / 0 / 0    6 / 0 / 0 / 0
bakim        7 / 0 / 0 / 0    7 / 0 / 0 / 0
```

#### Aynı Sayı, Başka Bileşim

Tablonun ilk satırı tabanı verir. Erişimsiz çağrı **0,3750** yapıyor ve bu oranın **tamamı üçüncü
kutudandır**: doğru parça hiç getirilmedi, on beş yanıt sınıf düzeyindeki tahminden doğru çıktı.
Tek sayıya bakan biri modelin soruların üçte birinden fazlasını bildiğini söyler. Dört durum tablosu
aynı satırda **hiçbir bilgiye dayanılmadığını** söyler. Bu ayrım şansı bir yetenek sanmayı önler.

Asıl gösterim son iki satırdadır. Üç parçalı ve beş parçalı kurulumların tek sayısı **birebir
aynıdır: 0,9500**. Bileşimleri değildir. Üçlüde iki başarısızlık **yanlış parça + yanlış yanıt**
kutusundadır, yani kanıt hiç gelmemiştir; sorun erişimdedir. Beşlide erişim anması 1,0000'e çıkar
ve o iki başarısızlık **doğru parça + yanlış yanıt** kutusuna taşınır: kanıt bağlamdadır ve model
onu kullanmamıştır. Bu ikincisi bir **kaynağa sadakat** kusurudur ve düzeltmesi bambaşkadır. Tek
sayı bu taşınmayı hiç göstermez, ama bedel gösterir: 120 parçadan 200 parçaya, 2199 belirteçten
**3505 belirtece**.

Alt grup dökümü hangi düzeltmenin nereye yapılacağını yazar. Her iki kusur da **tek bir sınıfta**,
`ariza` sınıfında toplanmıştır; öbür dört sınıf iki kurulumda da eksiksizdir. Beşe çıkmak kayıp
sorguları kurtarmadı, yalnız kusurun **adını değiştirdi**.

Son olarak iki koşum farkı, tek sayının ne kadarına güvenilebileceğini söyler. Erişimsiz tabanda
fark **0,1750**; şansa dayanan bir sayı doğal olarak oynaktır. Bir parçada fark **0,1000**. Üç ve
beş parçada fark **0,0000**: bağlamdaki kanıt puan ayrımını yeterince açtığı için örnekleme artık
sonucu döndürmüyor. Sayıyı sabitleyen şey düzeneğin kendisi değil, **bağlama giren kanıttır**.

#### Özet

- Erişim ve üretim iki ayrı sütundur: birincisi kanıtın geldiğini, ikincisi kanıtın kullanıldığını
  ölçer ve biri öbürünü yerine koyamaz.
- Erişimsiz taban bu iş yükünde 0,3750 çıkar ve bu oranın tamamı **yanlış parça + doğru yanıt**
  kutusundadır, yani şanstır.
- Üç parçalı ve beş parçalı kurulumun tek sayısı da 0,9500'dür, ama ilkinde iki başarısızlık
  erişim, ikincisinde aynı iki başarısızlık üretim kusurudur.
- Beş parçaya çıkmak anmayı 0,9500'den 1,0000'e taşır; bedeli 120 parçadan 200 parçaya ve 2199
  belirteçten 3505 belirtece çıkmaktır, uçtan uca sayı ise değişmez.
- Sınıf alt grubu her iki kusuru da `ariza` sınıfında toplar; iki koşum farkı erişimsiz tabanda
  0,1750, üç parçalı bağlamda 0,0000'dır.

#### Sonraki Adım

Bu ders erişimin ne zaman kazandığını değil, kazancın **nereden geldiğini** ayırdı. Cevaplanmayan
bir soru kaldı: erişim hattı, modele bilgi kazandırmanın tek yolu değildir. Aynı görev için modelin
kendisi de değiştirilebilir; M28/K03'ün Model API'leri ile Uygulama Geliştirme kursunda ince ayarın
sayısı ölçüldü ve altmış örnekle istem düzeneğini geçemediği görüldü. Bir sonraki ders bu iki
çözümü aynı masaya koyar ve üç ayrı görevde yan yana ölçer: hangisinin **hangi problemi** çözdüğü
ve hangi görevde **erişimin kazanmadığı** sayılır.

### Erişim ile İnce Ayarın Yan Yana Ölçülmesi

Source: https://academia.sh/tr/kurslar/rag/erisim-ve-ince-ayar-karsilastirmasi

Aynı iş yükünde üç ayrı görevin erişimle ve ince ayarla ayrı ayrı ölçülmesi: kırk sorguluk kurgu kümede bilgi tazeliği erişimsiz 0,0000, yalnız erişimle 0,9500, kırk sekiz örnekle ince ayarda 0,6750 çıkıyor ve örnek eklemek bu tavanı kaldırmıyor, çünkü bayat bilgi bir kapsama sorunu değildir. Biçim uyumu erişimle 0,0000 kalıyor, ince ayarla on iki örnekte 1,0000 oluyor: erişimin kazanmadığı görev budur. Alan dili erişimle 0,9500, tam kapsamlı ince ayarla 1,0000. Bedel erişimde istek başına ek belirteç ve kırk erişim adımı, ince ayarda kırk sekiz etiketli örnek. İki koşum farkı erişimsiz tabanda 0,1750, öbür üç kurulumda 0,0000.

Bir önceki ders erişim hattının tek sayısını dört duruma ayırdı ve tek sayının hangi aşamanın
bozulduğunu gizlediğini gösterdi. Ayrım şunu da açığa çıkardı: erişimin işi **isteme giren
bilgiyi** değiştirmektir. Modelin kendisine hiç dokunmaz.

Modele dokunmanın yolu vardır ve ölçülmüştür. M28/K03'ün Model API'leri ile Uygulama Geliştirme
kursunda ince ayar aynı destek görevinde denendi: taban **0,6000**, altmış örnekle istem düzeneği
**0,9667**, aynı altmış örnekle ince ayar **0,9500**. İstek başına bağlam **28,48** belirteçten
**623,48** belirtece çıkıyordu. O yordam burada tekrarlanmaz; o sayılar bu dersin **girdisidir**.
Bu dersin sorusu başkadır: bir görev verildiğinde hangisinin **hangi problemi** çözdüğü ve hangi
görevde erişimin **hiçbir şey kazandırmadığı**.

- **EH77.** Dağarcık, kavram ekseni, gömme, sorgu kümesi ve yenileme **kurgudur**, ders içinde
  üretilir. Hiçbir gerçek kurum, ürün, belge ya da gömme ucu yoktur.
- **EH78.** **Bilgi tazeliği görevi**: her yordamın bir **yürürlük damgası** vardır. Damga ince ayar
  anlık görüntüsünden sonra bir bölüm yordamda değişti. Doğru yanıt **yürürlükteki** damgadır.
- **EH79.** **Biçim uyumu görevi**: yanıtın iki alanlı sabit kalıba (`yordam | damga`) uyması
  istenir. Bu kalıp kurgudur ve yalnız çıktı kanalını ilgilendirir.
- **EH80.** **Alan dili görevi**: sorgu dilindeki yüzeyin (`hangi dilimdeyim`) hangi yordama
  karşılık geldiğinin bulunması. Bu, bir önceki dersin ölçtüğü işin aynısıdır.
- **EH81.** **İnce ayar burada bir öğrenme benzeticisidir**: eğitim kümesinde **gördüğü** yordamın
  sorgu yüzeyini doğrudan çözer, **gördüğü sınıfta** çıktı kalıbını uygular ve yürürlük damgasını
  **anlık görüntüden** verir. Görmediği yordamda dil modeli benzeticisinin tahminine düşer.
- **EH82.** **Bedel iki ayrı birimdedir ve toplanmaz**: erişimde istek başına ek belirteç ve erişim
  adımı, ince ayarda **etiketli örnek sayısı**. İkisinin ortak bir birimi yoktur.
- **EH83.** Ölçüler kırk sorgu üzerinde alınır; erişim üç parça getirir.

#### Üç Görev, Bir İş Yükü

Kurgu yenileme yordamların bir bölümünün yürürlük damgasını değiştirir. İnce ayar anlık görüntüsü
eskisini taşır, dağarcık yenisini.

```python
# KURGUDUR. Dagarcik, kavram ekseni, gomme, sorgu kumesi ve yenileme ders icinde
# uretilir; hicbir gercek kurum, urun, belge ya da gomme ucu yoktur.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# KURGU yenileme: yordamlarin bir bolumu ince ayar anlik goruntusunden sonra degisti.
DAMGA_EGITIM, DAMGA_GUNCEL = {}, {}
for i, k in enumerate(ANAHTAR):
    DAMGA_EGITIM[k] = f"y{i + 1:02d}a"
    DAMGA_GUNCEL[k] = (f"y{i + 1:02d}b"
                       if uretec(TOHUM + 31 * (i + 1))() < 0.45 else f"y{i + 1:02d}a")
BAYAT = [k for k in ANAHTAR if DAMGA_EGITIM[k] != DAMGA_GUNCEL[k]]

PARCA = [{"kod": d["kod"], "ana": d["ana"],
          "metin": p + " yururluk " + DAMGA_GUNCEL[d["ana"]]}
         for d in BELGE for p in d["par"]]
PV = [gom(p["metin"]) for p in PARCA]
OGRENME = [BELGE[int(uretec(TOHUM + 65537 * (i + 1))() * len(BELGE))]["ana"] for i in range(48)]

print(f"dagarcik {len(BELGE)} belge , {len(PARCA)} parca , sorgu {len(SORGU)}")
print(f"yenilenen yordam {len(BAYAT)} / {len(ANAHTAR)} , bayat yordama soran sorgu "
      f"{sum(1 for s in SORGU if s['kavram'] in BAYAT)} / {len(SORGU)}")
print(f"ogrenme kumesi {len(OGRENME)} etiketli ornek , kapsadigi yordam "
      f"{len(set(OGRENME))} , kapsadigi sinif {len({KAVRAM[x][0] for x in set(OGRENME)})}")
```

```
dagarcik 200 belge , 693 parca , sorgu 40
yenilenen yordam 9 / 20 , bayat yordama soran sorgu 13 / 40
ogrenme kumesi 48 etiketli ornek , kapsadigi yordam 20 , kapsadigi sinif 5
```

Yirmi yordamdan dokuzu yenilendi ve kırk sorgunun **on üçü** artık ince ayarın bildiğinden başka
bir yanıt istiyor. Öğrenme kümesi kırk sekiz etiketli örnektir ve tam kapsamlıdır: yirmi yordamın
yirmisini, beş sınıfın beşini de görür. Bu, ince ayara verilebilecek en iyi koşuldur.

#### Dört Kurulum

Aynı kırk sorgu dört kurulumda çözülür: erişimsiz taban, yalnız erişim, yalnız ince ayar ve ikisi
birlikte. Üç görev üç ayrı sütundur ve **tek bir sayıda toplanmaz**.

```python
from math import exp


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


def getir(q, k=3):
    v = gom(q)
    s = sorted(range(len(PARCA)), key=lambda i: (-aci(v, PV[i]), i))
    return [PARCA[i] for i in s[:k]]


def coz(s, erisim, ince, tohum=TOHUM, sicaklik=0.6):
    """Erisim istemin girdisini, ince ayar modelin kendisini degistirir."""
    par = getir(s["metin"]) if erisim else []
    istem = s["metin"] + " || " + " ".join(p["metin"] for p in par)
    gorulen = set(OGRENME[:ince])
    sq = " " + s["metin"].lower() + " "
    kav = next((x for x in ANAHTAR if KAVRAM[x][2] in sq and x in gorulen), None)
    if kav is None:                      # ince ayar bu yordami gormedi: benzetici tahmin eder
        dm = " " + istem.lower() + " "
        sn = next((KAVRAM[x][0] for x in ANAHTAR if KAVRAM[x][2] in sq), None)
        pu = {x: (0.15 if KAVRAM[x][0] == sn else 0.0) + dm.count(KAVRAM[x][1]) for x in ANAHTAR}
        ad = [x for x in ANAHTAR if pu[x]]
        a = [exp(pu[x] / sicaklik) for x in ad]
        t = sum(a)
        kav = ad[ayrik(uretec(tohum ^ izno(istem))(), [x / t for x in a])]
    if erisim:
        b = par[0]["metin"].split()
        damga = b[b.index("yururluk") + 1]
    else:
        damga = DAMGA_EGITIM[kav] if ince else "yok"
    bicim = ince > 0 and KAVRAM[kav][0] in {KAVRAM[x][0] for x in gorulen}
    return kav, damga, bicim, len(belirtecle(istem))


def olc(erisim, ince, tohum=TOHUM):
    n = len(SORGU)
    t = d = b = bel = 0
    for s in SORGU:
        kav, damga, bic, nb = coz(s, erisim, ince, tohum)
        t += damga == DAMGA_GUNCEL[s["kavram"]]
        d += kav == s["kavram"]
        b += bic
        bel += nb
    return t / n, b / n, d / n, bel


KURULUM = (("erisimsiz taban", 0, 0), ("yalniz erisim", 1, 0),
           ("yalniz ince ayar", 0, 48), ("ikisi birlikte", 1, 48))
print("kurulum            tazelik   bicim  alandili  belirtec  erisim adimi  etiketli ornek")
for ad, e, i in KURULUM:
    t, b, d, bel = olc(e, i)
    print(f"{ad:<18} {t:>7.4f} {b:>7.4f} {d:>9.4f} {bel:>9} {e * len(SORGU):>13} {i:>15}")

print("\nince ayar ornek sayisi supurmesi (erisim yok)")
print("ornek  gorulen kavram  gorulen sinif  tazelik   bicim  alandili")
for i in (0, 6, 12, 24, 48):
    t, b, d, _ = olc(0, i)
    g = set(OGRENME[:i])
    print(f"{i:>5} {len(g):>15} {len({KAVRAM[x][0] for x in g}):>14}"
          f" {t:>9.4f} {b:>7.4f} {d:>9.4f}")

print("\nikinci kosum (tohum 20260219) , alan dili isabeti ve kosum farki")
for ad, e, i in KURULUM:
    a, b = olc(e, i)[2], olc(e, i, TOHUM + 1)[2]
    print(f"{ad:<18} {a:>7.4f} {b:>8.4f} {b - a:>+9.4f}")
```

```
kurulum            tazelik   bicim  alandili  belirtec  erisim adimi  etiketli ornek
erisimsiz taban     0.0000  0.0000    0.3750       231             0               0
yalniz erisim       0.9500  0.0000    0.9500      2559            40               0
yalniz ince ayar    0.6750  1.0000    1.0000       231             0              48
ikisi birlikte      0.9500  1.0000    1.0000      2559            40              48

ince ayar ornek sayisi supurmesi (erisim yok)
ornek  gorulen kavram  gorulen sinif  tazelik   bicim  alandili
    0               0              0    0.0000  0.0000    0.3750
    6               6              4    0.4500  0.7500    0.6250
   12               9              5    0.4500  1.0000    0.7000
   24              15              5    0.4500  1.0000    0.7750
   48              20              5    0.6750  1.0000    1.0000

ikinci kosum (tohum 20260219) , alan dili isabeti ve kosum farki
erisimsiz taban     0.3750   0.2000   -0.1750
yalniz erisim       0.9500   0.9500   +0.0000
yalniz ince ayar    1.0000   1.0000   +0.0000
ikisi birlikte      1.0000   1.0000   +0.0000
```

#### Erişimin Kazanmadığı Görev

Üç sütun üç ayrı yanıt verir ve hiçbiri öbürünü kapsamaz.

**Bilgi tazeliğinde erişim kazanır.** Yalnız erişim **0,9500**, tam kapsamlı ince ayar **0,6750**.
Aradaki fark rastlantı değildir: kaybedilen tam olarak yenilenmiş dokuz yordama soran on üç
sorgudur. Süpürme sütunu bunu doğruluyor. Örnek sayısı altıdan kırk sekize çıkarken alan dili
0,6250'den 1,0000'e tırmanıyor, ama tazelik 0,4500'de duruyor ve ancak kapsam tamamlandığında
**0,6750**'de tavan yapıyor. Daha fazla örnek bunu **düzeltmez**, çünkü bayatlık bir kapsama sorunu
değildir: model doğru öğrendiği şeyi doğru hatırlıyor, öğrendiği şey artık yürürlükte değil.

**Biçim uyumunda erişim hiçbir şey kazandırmaz.** Erişimsiz taban 0,0000, yalnız erişim de
**0,0000**. Getirilen üç parça bağlamı zenginleştirir, çıktı kalıbına dokunmaz. İnce ayar aynı
görevi **on iki örnekte 1,0000** yapar; kalıbı öğrenmek için gereken şey yordam kapsaması değil,
**sınıf kapsamasıdır** ve beş sınıf on iki örnekte tamamlanıyor. Erişim istemin **girdisini**,
ince ayar modelin **çıktı davranışını** değiştirir; biçim ikinci kümededir.

**Alan dilinde ikisi de kazanır, tam kapsamda ince ayar öne geçer.** Erişim 0,9500, ince ayar
1,0000. Ama ince ayarın 1,0000'i yirmi yordamın hepsini gören kırk sekiz örneğe bağlıdır; yirmi
dört örnekte aynı sayı **0,7750**'dir. Erişimin 0,9500'ü ise etiketli örnek istemez.

Bedeller ortak birim taşımadığı için ayrı yazılır. Erişim toplam belirteci **231'den 2559'a**
çıkarır ve kırk **erişim adımı** ekler; istek başına 5,8 belirteçten 64,0 belirtece çıkmak
demektir. İnce ayarın belirteci **231'de kalır** ve erişim adımı yoktur, ama kırk sekiz **etiketli
örnek** ister ve damga her yenilendiğinde bu örneklerin bir bölümü geçersizleşir. İkisi birlikte
üç görevde de en iyi sütunu verir ve **iki bedeli birden** öder.

İki koşum farkı son tabloda. Erişimsiz taban ikinci koşumda 0,3750'den 0,2000'e düşüyor
(**−0,1750**); bilgiye dayanmayan bir sayı oynaktır. Öbür üç kurulumda fark **0,0000**. Hem
bağlamdaki kanıt hem de öğrenilmiş eşleme, örneklemenin sonucu döndürmesini engelliyor.

#### Özet

- Erişim istemin girdisini, ince ayar modelin çıktı davranışını değiştirir; bu ayrım hangi görevin
  hangisiyle çözüleceğini belirler.
- Bilgi tazeliğinde erişim 0,9500, tam kapsamlı ince ayar 0,6750 yapar; kaybedilen tam olarak
  yenilenmiş dokuz yordama soran on üç sorgudur.
- Örnek sayısını artırmak tazeliği düzeltmez: alan dili 0,6250'den 1,0000'e çıkarken tazelik
  0,4500'de durur ve 0,6750'de tavan yapar.
- Biçim uyumunda erişim 0,0000'dan 0,0000'a hiçbir şey katmaz; ince ayar on iki örnekte 1,0000
  yapar, çünkü kalıp için yordam değil sınıf kapsaması gerekir.
- Bedeller toplanmaz: erişim 231 belirteci 2559'a çıkarıp kırk erişim adımı ekler, ince ayar
  belirteci sabit tutup kırk sekiz etiketli örnek ister.

#### Sonraki Adım

İki çözüm de bir varsayımı paylaşıyor: dağarcıktaki her şeyin **düz metin** olduğu. Kurgu
belgelerin tamamı cümlelerden kuruluydu ve parçalama bir cümle dizisini bölmek demekti. Saha
ekibinin gerçek yordam belgeleri böyle değildir; içlerinde satırları ve sütunları anlamı taşıyan
**tablolar** vardır. Bir tablo cümle gibi bölündüğünde satır ile başlık birbirinden ayrılır ve
parça tek başına hiçbir şey söylemez. Bir sonraki ders aynı sorgu kümesinde bunu ölçer: tablonun
satır bazlı ve blok bazlı parçalanması aynı anmayı vermez.

### Tablo ve Görüntü Taşıyan Kaynakların Parçalanması

Source: https://academia.sh/tr/kurslar/rag/cok-kipli-erisim

Aynı kurgu dağarcık tablo biçiminde sunulduğunda parçalama kararının erişim anmasına ne yaptığının sayılması: yordam adı yalnız başlıkta durduğu için satır bazlı parçalama anmayı 0,0000'a düşürüyor, blok bazlı parçalama 0,9500 veriyor ama istek başına 91,6 belirteç götürüyor, satırın başlıkla birlikte saklanması aynı 0,9500 anmayı istek başına 41,4 belirteçle veriyor ve dizinde saklanan belirteci 5926'dan 9432'ye çıkarıyor. Tablo görüntü olarak verildiğinde betimlemesiz kaynak 0,0000, tek satırlık betimlemeli kaynak 0,9500 anma ama 0,0000 cevaplanabilirlik veriyor: kaynak bulunuyor, içindeki değer getirilemiyor. Ders M28/K04 kursunun kapanışıdır.

Bir önceki ders erişim ile ince ayarı üç görevde yan yana ölçtü ve ikisinin de aynı varsayıma
dayandığını gösterdi: dağarcıktaki her şeyin **düz metin** olduğu. Kurgu belgeler cümlelerden
kuruluydu ve her parça tek başına ne hakkında olduğunu söylüyordu.

Saha ekibinin yordam belgeleri böyle değildir. İçlerinde **tablolar** vardır ve tabloda anlam
hücrede değil, hücrenin **başlıkla ilişkisindedir**. Bir tablo cümle gibi bölündüğünde satır ile
başlık ayrılır ve satır tek başına hiçbir şey söylemez. Görüntü taşıyan kaynaklarda kayıp bir adım
daha öteye gider: metin hiç yoktur. Çok kipli girdinin kendisi M27'nin Doğal Dil İşleme ve Bilgisayarla
Görme kursunda, bilgisayarla görü konusunda ölçüldü ve M28/K03'te girdi biçiminin belirteç bedeli sayıldı — ince
ızgara **0,8167** isabet, kırpık ızgara **0,7000**, kullanılabilir kayıt başına **224,1**
belirteçten **60,0** belirtece. Bu yordamlar burada tekrarlanmaz. Bu dersin ölçtüğü tek şey
**parçalama kararıdır**.

- **EH84.** Dağarcık, kavram ekseni, gömme, sorgu kümesi ve tablo kaynağı **kurgudur** ve ders
  içinde üretilir. Hiçbir gerçek kurum, ürün, belge, ayrıştırıcı ya da gömme ucu yoktur.
- **EH85.** Aynı iki yüz belge bu derste **tabloya** çevrilir. **Yordam adı yalnız başlıkta durur**;
  satırlar alan adı, zorunluluk ve kaynak sütunlarını taşır. Tablonun neyi anlattığı hücrelerde
  yazmaz.
- **EH86.** Beş parçalama kipi ölçülür: **satır** (her satır bir parça, başlık atılır), **blok**
  (bütün tablo tek parça), **satır + başlık** (her satır başlıkla birlikte saklanır), **görsel**
  (tablo görüntü olarak gelir, metin yoktur) ve **görsel + betimleme** (görüntüye tek satırlık
  betimleme yazılmıştır).
- **EH87.** İki ölçü ayrı sayılır. **Erişim anması**: getirilen parçalarda hedef yordamın adı
  geçiyor mu. **Cevaplanabilirlik**: getirilen parçalardan birinde hem yordam adı hem de tablonun
  bir **satırı** birlikte duruyor mu. Bir yanıt ancak ikisi birden varsa üretilebilir.
- **EH88.** Bedel üç birimle yazılır: dizindeki parça sayısı, dizinde **saklanan** belirteç ve
  **istek başına** isteme giren belirteç. İlk ikisi depolama, üçüncüsü çağrı bedelidir.
- **EH89.** Ölçünün tamamı **belirlenmiştir**: örnekleme yoktur, dil modeli benzeticisi
  çağrılmaz, sayı koşumdan koşuma değişmez. Bu yüzden iki koşum farkı tanım gereği sıfırdır.
- **EH90.** Erişim her kipte üç parça getirir; anma ve cevaplanabilirlik bu üçlü üzerinde okunur.

#### Tabloyu Parçalamanın Beş Yolu

Parça boyutu ve örtüşme kararı bu kursun parçalama dersinde düz metin üzerinde ölçülmüştü. Tabloda
karar başka bir eksende durur: **başlığın satırla birlikte saklanıp saklanmayacağı**.

```python
# KURGUDUR. Dagarcik, kavram ekseni, gomme, sorgu kumesi ve tablo kaynagi ders
# icinde uretilir; hicbir gercek kurum, urun, belge ya da gomme ucu yoktur.
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# KURGU tablo kaynagi: her yordam belgesi bir tabloya cevriliyor.
# Yordam adi YALNIZ baslikta; satirlar alan adi, zorunluluk ve kaynak tasiyor.
TABLO = []
for i, d in enumerate(BELGE):
    r = uretec(TOHUM + 4093 * (i + 1))
    TABLO.append({"kod": d["kod"], "ana": d["ana"],
                  "bas": f"{KAVRAM[d['ana']][1]} yordami tablosu",
                  "sat": [f"{p.split()[3]} | {'evet' if r() < 0.5 else 'hayir'}"
                          f" | {'saha' if r() < 0.5 else 'merkez'}" for p in d["par"]]})


def dizin(kip):
    ps = []
    for t in TABLO:
        if kip == "satir":
            ps += [{"kod": t["kod"], "m": s} for s in t["sat"]]
        elif kip == "blok":
            ps.append({"kod": t["kod"], "m": t["bas"] + " ; " + " ; ".join(t["sat"])})
        elif kip == "satir + baslik":
            ps += [{"kod": t["kod"], "m": t["bas"] + " ; " + s} for s in t["sat"]]
        elif kip == "gorsel":
            ps.append({"kod": t["kod"], "m": ""})
        else:
            ps.append({"kod": t["kod"], "m": t["bas"]})
    return ps


def olc(kip, k=3):
    ps = dizin(kip)
    pv = [gom(p["m"]) for p in ps]
    anma = cevap = bel = 0
    for s in SORGU:
        v = gom(s["metin"])
        ilk = sorted(range(len(ps)), key=lambda i: (-aci(v, pv[i]), i))[:k]
        y = KAVRAM[s["kavram"]][1]
        anma += any(y in ps[i]["m"] for i in ilk)
        cevap += any(y in ps[i]["m"] and " | " in ps[i]["m"] for i in ilk)
        bel += sum(len(belirtecle(ps[i]["m"])) for i in ilk)
    n = len(SORGU)
    return anma / n, cevap / n, len(ps), sum(len(belirtecle(p["m"])) for p in ps), bel / n


print("kip                 anma   cevaplanabilir  dizin parcasi  saklanan bel  istek basi bel")
for kip in ("satir", "blok", "satir + baslik", "gorsel", "gorsel + betimleme"):
    a, c, np_, sb, ib = olc(kip)
    print(f"{kip:<19} {a:>6.4f} {c:>15.4f} {np_:>14} {sb:>13} {ib:>15.1f}")
```

```
kip                 anma   cevaplanabilir  dizin parcasi  saklanan bel  istek basi bel
satir               0.0000          0.0000            693          3815            17.0
blok                0.9500          0.9500            200          5926            91.6
satir + baslik      0.9500          0.9500            693          9432            41.4
gorsel              0.0000          0.0000            200             0             0.0
gorsel + betimleme  0.9500          0.0000            200          1418            21.6
```

#### Bulunan Kaynak, Getirilemeyen Değer

Satır bazlı parçalama en ucuz kiptir: istek başına **17,0** belirteç, dizinde 3815 belirteç. Ve
anması **0,0000**'dır. Sorgu bir yordam sorar, satırlarda yordam adı geçmez, gömme hiçbir satırı
sorguya yakın bulmaz. Kayıp bir sıralama kusuru değildir; aranan yüzey **dizine hiç girmemiştir**.
Aynı parçalama düz metinde çalışıyordu, çünkü orada her cümle konusunu kendi içinde tekrarlıyordu.

Blok bazlı parçalama anmayı **0,9500** yapar ve cevaplanabilirliği de aynı yere getirir: başlık ile
satırlar aynı parçadadır. Bedeli istek başına **91,6** belirteçtir, satır bazlının beş katından
fazlası. Dizinde saklanan belirteç 3815'ten **5926**'ya çıkar, çünkü başlıklar da saklanır.

Satır + başlık kipi ikisinin arasını açar. Anma ve cevaplanabilirlik blokla **birebir aynıdır**
(0,9500), ama istek başına belirteç **41,4**'e iner: getirilen üç parça artık bütün tablo değil, üç
satırdır. Bunun bedeli depolamadadır. Başlık her satırda tekrarlandığı için dizinde saklanan
belirteç 5926'dan **9432**'ye çıkar, yani blok kipinin 1,59 katına. **İki bedel ters yönde
hareket eder**: istek başına giden belirteç düşerken saklanan belirteç yükselir. Hangisinin
seçileceği istek sayısına bağlıdır ve bu bir sayı sorusudur, bir üslup sorusu değil.

Son iki satır çok kipli kaynağın kendine özgü kaybını verir. Tablo görüntü olarak geldiğinde ve
betimleme yazılmadığında dizinde metin yoktur: anma **0,0000**, saklanan belirteç **0**. Kaynak
dizinde durur ve hiçbir sorguya cevap vermez; erişim uzayında ölü ağırlıktır.

Asıl uyarı beşinci satırdadır. Tek satırlık bir betimleme yazıldığında anma **0,9500**'e fırlar,
cevaplanabilirlik ise **0,0000**'da kalır. Betimleme tablonun **ne hakkında olduğunu** söyler,
**içinde ne yazdığını** söylemez. Değerlendirme dersinin dört durum tablosuyla okunduğunda bu,
doğru parçanın getirildiği ama yanıtın üretilemediği kutudur; tek bir anma sayısına bakan biri bu
kipi **çalışıyor** sanır.

#### Özet

- Tabloda anlam hücrede değil hücrenin başlıkla ilişkisindedir; satır bazlı parçalama başlığı
  attığı için anmayı 0,0000'a düşürür ve kayıp sıralamada değil dizindedir.
- Blok bazlı parçalama 0,9500 anma verir ve istek başına 91,6 belirteç götürür; satır + başlık
  aynı 0,9500'ü istek başına 41,4 belirteçle verir.
- Başlık tekrarının bedeli depolamadadır: saklanan belirteç 5926'dan 9432'ye, blok kipinin 1,59
  katına çıkar; iki bedel ters yönde hareket eder.
- Betimlemesiz görüntü kaynağı dizinde metin taşımaz, anması 0,0000'dır ve erişim uzayında ölü
  ağırlıktır.
- Tek satırlık betimleme anmayı 0,9500 yapar ama cevaplanabilirliği 0,0000'da bırakır: kaynak
  bulunur, içindeki değer getirilemez.
#### Kurs Kapanışı

| Ders | Erişimsiz taban | Erişimli | Bedel |
|---|---|---|---|
| `gommeler/01` — ilk sonucun kavram isabeti | anahtar sözcük araması 0,0500 | gömme benzerliği 0,5000 (**+0,4500**) | 8000 karşılaştırma, 240 gömme çağrısı, 6400 saklanan sayı |
| `gommeler/02` — kavram isabeti, 32 boyut | alan dışı gömme 0,0500, tabanla birebir aynı | alan içi gömme 0,5000 (**+0,4500**) | saklanan sayı iki kurulumda da 6400; iki model bandı 0,0250 |
| `gommeler/03` — ilk sonucun kavram isabeti | iç çarpım 0,4250 | açı benzerliği 0,5000 (**+0,0750**) | kırk sorgunun otuzunda ilk üç ayrışıyor; getirilen kümenin ortalaması 64,3 → 54,6 belirteç |
| `gommeler/04` — tam taramaya karşı anma | tam tarama 1,0000, 200 karşılaştırma | kovalı dizin sonda 2 ile 0,9600 (**−0,0400**) | 47,2 karşılaştırma; sonda 1'de anma 0,7000 ve kavram kesinliği 0,4600 → 0,3600 |
| `gommeler/05` — süzgeçli anma | süzgeçsiz dizin 0,9600 | dizin içinde süzme, genişlik 1: 0,4750 (**−0,4850**) | aday 31,2 → 2,8; süzülmüş kümenin tam taraması 18 karşılaştırmayla 1,0000 |
| `gommeler/06` — belge dili sınıfında ilk sıra | yalnız gömme 0,5000 | sıra temelli birleştirme 0,4000 (**−0,1000**) | kod sınıfında 1,0000 → 0,0500; yirminci sıraya kadar anma 0,7122 → 0,7209 |
| `erisim-hatti/01` — üretim isabeti | erişimsiz taban 0,1750 | erişimli hat 0,9250 (**+0,7500**) | 3174 → 5343 belirteç, 120 parça; yanlış parçalı koşum 0,0500 |
| `erisim-hatti/02` — üretim isabeti | hazırlıksız tek blok 0,0000, anması 1,0000 | yapıya duyarlı hazırlık 0,9250 (**+0,9250**) | saklanan parça 1805 → 693; süzgeç 568 kavram bağının 96'sını siliyor |
| `erisim-hatti/03` — ilişki geçişini bütün taşıyan parça payı | boyut 8 parçalama 0,0000 | boyut 32 parçalama 0,8557 (**+0,8557**) | saklanan parça 1538 → 455; boyut 80'de üretim 0,4750 ve isteklerin 0,25'i bağlam sınırını aşıyor |
| `erisim-hatti/04` — güncel yanıt payı | on iki dönemde bir yenileme 0,6125 | her dönem yenileme 0,9250 (**+0,3125**) | gömülen parça 519 → 881; bayat parça payı 0,2562 → 0,0000, yanlış yanıt payı 0,3875 → 0,0750 |
| `erisim-hatti/05` — kısa yazımda erişim anması | dönüştürmesiz 0,3750 | genişletme 0,7500 (**+0,3750**) | sorgu başına bir çağrı, 990–2360 ek belirteç; uzun yazımda 0,5500 → 0,3500 |
| `erisim-hatti/06` — ilk üçün kesinliği | tek aşamalı getirme 0,4167 (üretim 0,7500) | 24 adayın yeniden sıralanması 0,9000 (**+0,4833**, üretim 1,0000) | çağrı 40 → 1000, belirteç 4003 → 37689; 48 adayda anma 1,0000 → 0,9500 |
| `erisim-hatti/07` — üretim isabeti / anma | tek parça 0,7750 / 0,7750 | on parça 0,4750 (**−0,3000**) / 0,9750 | bağlam penceresine 11,3 parça sığıyor; k=13'te kırk sorgunun kırkı da sınırı deliyor |
| `erisim-hatti/08` — uçtan uca isabet | erişimsiz taban 0,3750, tamamı şans | üç parça 0,9500 (**+0,5750**) | 120 parça, 2199 belirteç; beş parçada aynı 0,9500, kusur üretime taşınıyor |
| `erisim-hatti/09` — bilgi tazeliği | erişimsiz 0,0000 | erişimli 0,9500 (**+0,9500**) | 2559 belirteç, 40 erişim adımı; biçim uyumunda 0,0000 → 0,0000 |
| `erisim-hatti/10` — cevaplanabilirlik | satır bazlı parçalama 0,0000 | satır + başlık 0,9500 (**+0,9500**) | istek başına 17,0 → 41,4 belirteç; dizinde saklanan 3815 → 9432 |

Kursun kuralı tabloda satır satır yazılıdır: **erişim ile üretim ayrı ölçülür.** Erişimsiz taban
sütunundaki sayıların hiçbiri kötü bir modelden gelmiyor; hepsi, cevabın modelin içinde değil
**dağarcıkta** olmasından geliyor. İki sütunu tek orana indirmek en öğretici satırları görünmez
kılar: `erisim-hatti/02`'de
hazırlıksız kaynak **erişim sütununun en iyisi** (anma 1,0000) ve **üretim sütununun en
kötüsüdür** (0,0000).

**İkinci iddia da aynı tablodan okunur: erişim de bozar.** `gommeler/02`'de alan dışı gömme
getirilen kümede anahtar sözcük tabanının **altına** düşer. `gommeler/04`'te sonda 1'de anma 0,7000'e,
ilk beşin kavram kesinliği 0,4600'den 0,3600'e iner. `gommeler/05`'te dar süzgeçte dizin 18,8 karşılaştırmayla 0,4750
verirken süzülmüş kümenin tam taraması 18 karşılaştırmayla 1,0000 verir. `gommeler/06`'da
birleştirme belge dili sınıfında **ikisinden de kötüdür** ve kod sınıfında 1,0000'i 0,0500'e
indirir. `erisim-hatti/01`'de yanlış parçalı koşum üretimi erişimsiz tabanın altına düşürür.
`erisim-hatti/03`'te parça boyutunu 80'e çıkarmak ilişki geçişini 0,9784'e taşırken üretimi
**0,4750**'ye düşürür, çünkü isteklerin dörtte biri bağlam sınırını aşar. `erisim-hatti/04`'te
yenileme aralığını uzatmak erişim sütununu **hiç oynatmaz** ve bozulmanın tamamı üretim
sütununda kalır: güncel yanıt payı 0,9250'den 0,6125'e iner. `erisim-hatti/05`'te uzun yazımda
dönüştürme tabanı 0,5500'den 0,3500'e götürür. `erisim-hatti/06`'da aday sayısını 24'ten 48'e
çıkarmak kesinliğe ölçülemez bir 0,0083 katarken anmayı 1,0000'den 0,9500'e indirir ve belirteci
neredeyse ikiye katlar. `erisim-hatti/07`'de on parça getirmek anmayı 0,9750'ye çıkarırken
üretimi **0,4750**'ye düşürür — getirilen doğru, kullanılan yanlıştır. `erisim-hatti/08`'de
beş parçaya çıkmak anmayı 1,0000 yapar, uçtan uca sayıyı **hiç değiştirmez** ve belirteci 2199'dan
3505'e çıkarır. `erisim-hatti/09`'da biçim uyumunda erişim 0,0000'dan 0,0000'a hiçbir şey katmaz.
Ve bu derste betimlemeli görsel kaynak anmayı 0,9500 yaparken cevaplanabilirliği 0,0000'da bırakır:
iyileşen sayı, iyileşmeyen iş.

On altı derste modele **hangi bilginin** gireceği ölçüldü. Ama bu seçimi hep **biz** yaptık: kaç
parça getirileceği, hangi ölçütle sıralanacağı, sorgunun dönüştürülüp dönüştürülmeyeceği ve
bağlamın nasıl kurulacağı hattın içine elle yazıldı. Hat da **tek geçişliydi**: sorgu girdi, parça geldi,
yanıt çıktı. Modelin hangi aracı çağıracağına kendi karar verdiği, sonucu yetersiz bulup yeniden
denediği ve bu döngünün **nerede duracağı** bir kez bile sorulmadı.
Sonraki kurs bu döngüyü kurar ve durma koşulunu bir ölçüm nesnesine dönüştürür.

