---
title: 'Doğal Dil İşleme ve Bilgisayarla Görme'
source: 'https://academia.sh/tr/kurslar/nlp-ve-goru'
language: tr
updated: '2026-08-17T04:42:08+00:00'
license: 'CC BY-SA 4.0'
lessons: 14
outcomes:
    - 'Metni sayısal temsile dönüştüren yöntemleri alanın tabanına karşı karşılaştırır'
    - 'Görüntü görevlerini sınıflandırma, tespit ve bölütleme olarak ayırır ve her birinin tabanını kurar'
    - 'Alan özel değerlendirme ölçütlerini kullanır ve ölçütün neyi gizlediğini sayıyla gösterir'
---

# Doğal Dil İşleme ve Bilgisayarla Görme

Metnin ve görüntünün sayıya çevrilmesinde her adımın, o alanın en aptal yordamına karşı ne kattığının ölçülmesi: belirteçleme kararının oynattığı sözlük boyu ve sözlük dışı oranı, sözcük torbasının ve terim ağırlıklandırmanın elle sayılmış özniteliklere kattığı, gömmenin komşuluk ve oran benzeşiminde tuttuğu ile tutmadığı, belirteç düzeyi ile varlık düzeyi ölçütünün ayrışması, sınıflandırma boru hattında her adımın payı, vekil görevin etiketli örnek azaldıkça öne geçmesi, girdiyi kopyalayan yordamın örtüşme temelli ölçütte aldığı yüksek sayı, aynı çıktının dört ölçütte dört ayrı sıralaması, normalleştirme ve artırmanın katkısı ile etiketi bozan dönüşüm, aktarımın kaç örnekle kattığı, sabit bir kutunun örtüşme ölçütündeki sayısı ve eşiğin bunu oynatması, her pikseli baskın sınıfa atamanın bölütlemede aldığı sayı, kare kararlarının zaman içindeki tutarsızlığı ve ortak temsilin eşleştirme başarısı.

## Doğal Dil İşleme

Kısa Türkçe saha notlarının sayıya çevrilmesinde her kararın kattığının sayılması: üç belirteçleme kararının üç ayrı sözlük ve sözlük dışı oranı vermesi ile eklemeli yapının gövdelemeyi zorlaştırması, sözcük torbasının elle sayılmış metin özniteliklerine kattığı ve terim ağırlıklandırmanın üstüne koyduğu, gömmenin bağlamdan öğrenilmesi ve oran benzeşiminin çoğu zaman en sık sözcüğe düşmesi, aynı çıktının belirteç düzeyinde yüksek varlık düzeyinde düşük sayı vermesi ve en sık etiketi her belirtece yazan tabanın şaşırtıcı yüksekliği, sınıflandırma boru hattında her adımın payı, maskeli kestirimle önceden eğitilen gömmenin etiketli örnek azaldıkça öne geçmesi, girdiyi kopyalayan yordamın örtüşme temelli ölçütte aldığı yüksek sayı ve aynı çıktının dört ölçütte dört ayrı sıralaması.

### Metin Ön İşleme

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/metin-on-isleme

Kısa Türkçe saha notlarının belirteçlere bölünmesinde kararın oynattığı sayının ölçülmesi: alanın tabanı boşlukla ayırma 748 belirteçlik sözlük ve 0,0565 sözlük dışı oranı verirken noktalama atılıp küçük harfe inildiğinde sözlük 669'a, gövdeleme eklendiğinde 641'e ve oran 0,0557'ye iniyor. Sözlük dışının 0,9467'si sayıdır; sayılar tek belirtece katlandığında sözlük 203, 124 ve 96 oluyor. Kural tabanlı gövdeleyici 85 kökü 103 gövdeye bölüyor, 19 kökü birden çok gövdeye dağıtıyor ve bir gövdede iki kökü birleştiriyor; çizelgeye dayalı kök bulma sözlüğü 82'ye indiriyor ama kapsamı 0,9967 ve tanımadığı biçimde hiçbir şey yapamıyor.

Derin öğrenme kursu yirmi dört derste mimariyi kurdu, ama girdi hep hazır bir sayıydı: bir sütun,
bir ızgara hücresi, bir okuma dizisi, bir olay kodu. Elde bir metin varken durum başkadır. Saha
ekibinin abone kaydına düştüğü birkaç sözcüklük bir notta modelin okuyabileceği tek bir sayı
yoktur; sayıyı üreten şey bir karar dizisidir.

Kursun ölçüsü buradan kurulur. Her derste üç sayı yan yana durur: **alanın tabanı** — o görevin en
aptal yordamının aynı ölçütteki sayısı; **yöntemin sayısı**; ve **fark**, farkın temsilden mi
modelden mi ölçütten mi geldiği yazılarak. Kuralı şudur: bir alan ölçütü, o alanın en aptal
yordamının aynı ölçütteki sayısı yazılmadan okunamaz. **Alanın tabanı yazılmayan sayı ölçülmemiş
sayılır.** Burada taban metni boşluklardan ayırmaktır, model yoktur ve fark ne çıkarsa yalnız
temsilden gelir.

- **NL1.** Notlar **kurgudur**: ders içinde üretilir, tohum 20260218, hiçbir kaynak sistemden
  gelmez. Küme 1.800 nottur ve M27/K02'nin saha notu alanının genişletilmiş hâlidir.
- **NL2.** Sözlük 85 kökten kurulur: 24 çekimli ad, 10 eylem, 11 nitelik ve 40 seyrek ad. Seyrek
  adların ağırlıkları hızla düşer, birkaçı notlarda ancak bir iki kez görünür.
- **NL3.** Etiketler **kurgudur**: olay türü (olağan, arıza, erişilemedi, kaçak şüphesi) ve ikili
  kaçak şüphesi. Şüphe olasılığı yalnız olay türüne bağlıdır.
- **NL4.** **Belirteç** (token) metnin bölündüğü en küçük parçadır. JavaScript ve TypeScript
  kursunda dil çözümleyicisinin ürettiği birim **sözcük birimi** diye anılmıştı; ayrım korunur,
  çünkü orada bölme dilbilgisiyle kesin, burada bir karardır.
- **NL5.** İlk 1.200 not eğitim payı, kalan 600 not ayrılmış paydır. Sözlük **yalnız eğitim
  payından** kurulur; ayrılmış payda görülüp sözlükte bulunmayan belirteç **sözlük dışıdır**.
- **NL6.** Metin normalleştirme ve dizgi yordamları M26/K03'ün veri temizleme kursunda ölçüldü;
  yordam tekrarlanmaz, yalnız kararın oynattığı sayı ölçülür.
- **NL7.** Ölçüt sözlük boyu ile sözlük dışı oranıdır (küçük iyi) ve her satırda aynıdır.
- **NL8.** Gövdeleyicinin doğruluğu kurgunun kök eşlemesine karşı ölçülür; kök bulma çizelgesi aynı
  eşlemenin **yalnız eğitim payında görülen** kısmıdır.

#### Notların Kurgusu

Bir not bir ya da birkaç kısa öbekten oluşur: ilk öbek olay türünü taşır, ek öbek ile seyrek ad
öbeği türden bağımsızdır ve gürültüdür.

```python
# ORTAK — KURGUDUR. Saha notlari ders icinde uretilir, tohum 20260218; kaynak
# sistemden gelmez. Sozluk 45 cekimli kok ve 40 seyrek addan olusur.
TOHUM, NOT_SAYISI, M32 = 20260218, 1800, 0xFFFFFFFF

AD = {  # 0 yalin, 1 ilgi, 2 bulunma, 3 iyelik, 4 cogul
    "sayac": "sayac sayacin sayacta sayaci sayaclar",
    "kapak": "kapak kapagin kapakta kapagi kapaklar",
    "muhur": "muhur muhurun muhurde muhuru muhurler",
    "vana": "vana vananin vanada vanasi vanalar",
    "kelepce": "kelepce kelepcenin kelepcede kelepcesi kelepceler",
    "boru": "boru borunun boruda borusu borular",
    "pano": "pano panonun panoda panosu panolar",
    "kapi": "kapi kapinin kapida kapisi kapilar",
    "zil": "zil zilin zilde zili ziller",
    "bahce": "bahce bahcenin bahcede bahcesi bahceler",
    "apartman": "apartman apartmanin apartmanda apartmani apartmanlar",
    "bodrum": "bodrum bodrumun bodrumda bodrumu bodrumlar",
    "giris": "giris girisin giriste girisi girisler",
    "adres": "adres adresin adreste adresi adresler",
    "okuma": "okuma okumanin okumada okumasi okumalar",
    "olcum": "olcum olcumun olcumde olcumu olcumler",
    "erisim": "erisim erisimin erisimde erisimi erisimler",
    "ziyaret": "ziyaret ziyaretin ziyarette ziyareti ziyaretler",
    "abone": "abone abonenin abonede abonesi aboneler",
    "arac": "arac aracin aracta araci araclar",
    "kir": "kir kirin kirde kiri kirler",
    "iz": "iz izin izde izi izler",
    "sokak": "sokak sokagin sokakta sokagi sokaklar",
    "ev": "ev evin evde evi evler",
}
NITELIK = "kirik gevsek kirli normal bozuk acik kapali eksik temiz yeni yok".split()
EYLEM = {  # 0 edilgen gecmis, 1 olumsuz
    "calis": "calisiyor calismiyor", "don": "donuyor donmuyor", "oku": "okundu okunmadi",
    "ac": "acildi acilmadi", "gir": "girildi girilemedi", "ulas": "ulasildi ulasilamadi",
    "tekrarla": "tekrarlandi tekrarlanmadi", "bul": "bulundu bulunmadi",
    "sagla": "saglandi saglanamadi", "degil": "degil degildi",
}
NADIR = """kablo kablosu kabloda|cam cami camda|tel teli telde|mandal mandali mandalda
merdiven merdiveni merdivende|tahta tahtasi tahtada|cukur cukuru cukurda|kar kari karda
buz buzu buzda|cop copu copta|duvar duvari duvarda|kutu kutusu kutuda|vida vidasi vidada
conta contasi contada|filtre filtresi filtrede|bant banti bantta|etiket etiketi etikette
kilit kiliti kilitte|asansor asansoru asansorde|zemin zemini zeminde|tavan tavani tavanda
kuyu kuyusu kuyuda|depo deposu depoda|ocak ocagi ocakta|direk diregi direkte
kanal kanali kanalda|numara numarasi numarada|cati catisi catida|baca bacasi bacada
kova kovasi kovada|levha levhasi levhada|somun somunu somunda|tapa tapasi tapada
izolasyon izolasyonu izolasyonda|supap supabi supapta|menfez menfezi menfezde
kayit kaydi kayitta|temel temeli temelde|kose kosesi kosede|koruma korumasi korumada"""
OBEK = {
    "olagan": ["{sayac.0} {calis.0}", "{okuma.0} normal", "{olcum.0} {tekrarla.0}",
               "{sayac.1} {erisim.3} {sagla.0}", "{kapak.0} temiz", "{vana.0} acik",
               "{sayac.2} {iz.0} {bul.1}", "{olcum.0} icin {erisim.0} {sagla.0}",
               "{sayac.1} {kapak.3} yeni", "{muhur.0} ile {kapak.0} temiz"],
    "ariza": ["{sayac.0} {don.1}", "{kapak.0} kirik", "{pano.0} bozuk",
              "{sayac.1} {kapak.3} kirik", "{olcum.0} {oku.1}", "{vana.0} bozuk",
              "{sayac.2} {kir.0} {bul.0}", "{sayac.4} {calis.1}",
              "{sayac.0} {calis.0} ama {okuma.0} yok",
              "{pano.1} {kapak.3} eksik"],
    "erisilemedi": ["{kapi.0} {ac.1}", "{zil.0} {calis.1}", "{abone.0} {ev.2} {degil.1}",
                    "{erisim.0} {sagla.1}", "{bodrum.0} {kapi.3} kapali",
                    "{apartman.1} {giris.3} kapali", "{adres.2} {ulas.1}",
                    "{bahce.1} {kapi.3} kapali", "{apartman.2} {zil.0} {calis.1}",
                    "{sayac.2} {erisim.0} yok"],
    "kacak": ["{muhur.0} kirik", "{kelepce.0} gevsek", "{muhur.2} {iz.0} {bul.0}",
              "{sayac.1} {muhur.3} kirik", "{kelepce.2} {iz.0} {bul.0}",
              "{muhur.0} eksik", "{vana.1} {kelepce.3} gevsek",
              "{muhur.1} {iz.3} {bul.0}", "{boru.2} {kelepce.0} eksik",
              "{kapak.2} bir {iz.0} {bul.0}"],
}
EK_OBEK = ["{ziyaret.0} {tekrarla.0}", "{sokak.2} {arac.0} {bul.0}", "{adres.0} yeni",
           "{bahce.1} {kapi.3} acik", "{apartman.2} {gir.0}", "{ev.1} {kapi.3} acik",
           "{kapak.0} kirli", "{olcum.0} {tekrarla.1}", "{arac.0} {sokak.2}",
           "bu {ziyaret.2} {olcum.0} {tekrarla.0}"]
TUR = [("olagan", 0.36, 0.04), ("ariza", 0.26, 0.28),
       ("erisilemedi", 0.16, 0.15), ("kacak", 0.22, 0.82)]
BICIM = {k: v.split() for d in (AD, EYLEM) for k, v in d.items()}
SEYREK = [s.split() for s in NADIR.replace("\n", "|").split("|")]
AGIRLIK = [1 / (i + 1) ** 1.6 for i in range(len(SEYREK))]
AGIRLIK = [w / sum(AGIRLIK) for w in AGIRLIK]
KOKU = {f: k for k, fs in BICIM.items() for f in fs}
KOKU.update({f: fs[0] for fs in SEYREK for f in fs})
KOKU.update({w: w for w in NITELIK})
TASIYICI = ["ve", "ile", "bir", "bu", "ama", "icin"]
KOKU.update({w: w for w in TASIYICI})


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 obek_yaz(sablon):
    p = []
    for s in sablon.split():
        if s.startswith("{"):
            kok, _, i = s[1:-1].partition(".")
            p.append(BICIM[kok][int(i)])
        else:
            p.append(s)
    return " ".join(p)


VERI = []
for i in range(NOT_SAYISI):
    r = uretec(TOHUM + i)
    t = TUR[ayrik(r(), [x[1] for x in TUR])]
    c = [obek_yaz(OBEK[t[0]][int(r() * 10)])]
    if r() < 0.55:
        c.append(obek_yaz(EK_OBEK[int(r() * 10)]))
    if r() < 0.30:
        c.append(obek_yaz(OBEK[t[0]][int(r() * 10)]))
    if r() < 0.22:
        f, nit = SEYREK[ayrik(r(), AGIRLIK)], NITELIK[int(r() * len(NITELIK))]
        c.append(f[2] + " kir bulundu" if r() < 0.34 else f[int(r() * 2)] + " " + nit)
    n = c[0]
    for x in c[1:]:
        n += (" ve " if r() < 0.22 else ", ") + x
    if r() < 0.52:
        n += ", okuma " + str(240 + int(r() * 1760))
    VERI.append({"no": 10001 + i, "not": n[0].upper() + n[1:] + ".",
                 "tur": t[0], "supheli": int(r() < t[2])})

EGT, AYR = VERI[:1200], VERI[1200:]
for i in (0, 3, 41):
    print(f"{VERI[i]['tur']:<12} {VERI[i]['supheli']}  {VERI[i]['not']}")
print(f"\n{len(VERI)} not, {len(KOKU)} sozluk bicimi, {len(BICIM) + len(SEYREK) + len(NITELIK)} kok")
for ad, _, _ in TUR:
    n = [x for x in VERI if x["tur"] == ad]
    print(f"{ad:<12} {len(n):>5} not   supheli orani {sum(x['supheli'] for x in n) / len(n):.4f}")
print(f"{'toplam':<12} {len(VERI):>5} not   supheli orani "
      f"{sum(x['supheli'] for x in VERI) / len(VERI):.4f}")
```

```
kacak        1  Vananin kelepcesi gevsek.
olagan       0  Olcum icin erisim saglandi, sayacin kapagi yeni, mandalda kir bulundu.
kacak        1  Boruda kelepce eksik, okuma 1505.

1800 not, 277 sozluk bicimi, 85 kok
olagan         638 not   supheli orani 0.0486
ariza          446 not   supheli orani 0.3072
erisilemedi    305 not   supheli orani 0.1377
kacak          411 not   supheli orani 0.7835
toplam        1800 not   supheli orani 0.2956
```

Şüphe oranı türe göre 0,0486 ile 0,7835 arasında değişiyor: metin etiketle ilişkilidir ama onu
belirlemez, kaçak öbeği taşıyan 411 notun 89'unda şüphe yoktur. Sonraki derslerin tavanı budur ve
en sık sınıf 0,7044 pay tutar.

#### Üç Belirteçleme Kararı

En aptal yordam boşluklardan ayırmaktır: noktalama sözcüğe yapışık kalır, cümle başındaki büyük
harf ayrı tür sayılır. İkinci karar noktalamayı atıp küçük harfe iner. Üçüncü karar üstüne kural
tabanlı **gövdelemeyi** ekler: sonda eşleşen en uzun ek atılır, geriye en az üç karakter kalmak
koşuluyla.

```python
EKLER = ["lari", "leri", "lar", "ler", "nin", "nun", "dan", "den", "tan", "ten",
         "dir", "tir", "dur", "da", "de", "ta", "te", "in", "un", "yi", "yu",
         "si", "su", "li", "lu", "di", "du", "ti", "tu", "i", "u", "a", "e"]


def k1(n):  # bosluk
    return n.split()


def k2(n):  # noktalama atilir, kucuk harfe inilir
    return [b for b in (s.strip(",.").lower() for s in n.split()) if b]


def govdele(b):
    for e in EKLER:
        if b.endswith(e) and len(b) - len(e) >= 3:
            return b[:-len(e)]
    return b


def k3(n):  # + govdeleme
    return [govdele(b) for b in k2(n)]


def sayi_mi(b):
    return b.strip(",.").isdigit()


def olc(f, ad, sayi_payi=True):
    egt = [b for x in EGT for b in f(x["not"])]
    ayr = [b for x in AYR for b in f(x["not"])]
    s = set(egt)
    dis = [b for b in ayr if b not in s]
    ek = f"   sayi payi {sum(map(sayi_mi, dis)) / len(dis):.4f}" if sayi_payi else ""
    print(f"{ad:<28} {len(egt) + len(ayr):>8} {len(s):>7} {len(dis):>5}"
          f" {len(dis) / len(ayr):>8.4f}{ek}")


print(f"{'belirtecleme karari':<28} {'belirtec':>8} {'sozluk':>7} {'disi':>5} {'oran':>8}")
olc(k1, "bosluk")
olc(k2, "noktalama atma, kucuk harf")
olc(k3, "+ govdeleme")


def katla(f):
    return lambda n: ["<sayi>" if sayi_mi(b) else b for b in f(n)]


print()
olc(katla(k1), "bosluk", False)
olc(katla(k2), "noktalama atma, kucuk harf", False)
olc(katla(k3), "+ govdeleme", False)
```

```
belirtecleme karari          belirtec  sozluk  disi     oran
bosluk                          12044     748   225   0.0565   sayi payi 0.9467
noktalama atma, kucuk harf      12044     669   225   0.0565   sayi payi 0.9467
+ govdeleme                     12044     641   222   0.0557   sayi payi 0.9595

bosluk                          12044     203    12   0.0030
noktalama atma, kucuk harf      12044     124    12   0.0030
+ govdeleme                     12044      96     9   0.0023
```

Üç karar aynı 12.044 belirteci üretir ama üç ayrı sözlük verir: 748, 669, 641. Taban sözlüğü 107
belirteç şişiriyor, çünkü `kapali` ile `kapali,` ve `Kapi` ile `kapi` ayrı türler sayılıyor. Sözlük
dışı oranı ise ilk iki kararda aynı: 0,0565. **Sözlük boyu ile sözlük dışı oranı aynı yönde hareket
etmiyor** ve nedeni son sütunda yazılı: sözlük dışının 0,9467'si sayıdır. Okuma değeri her notta
başkadır ve eğitimde görülmemiş bir sayı ayrılmış payda sözlük dışına düşer.

Sayılar tek belirtece katlandığında tablo başka okunur: sözlük 203, 124 ve 96, oran 0,0030 ve
0,0023. Katlamanın boşluk kararında sözlüğü ancak 203'e indirmesi bir karar bağımlılığıdır —
noktalama yapışık kaldığı için `1107.` sayı sayılmaz.

Üçlü böylece yazılabilir: taban 748 ve 0,0565, üç kararın tamamı 641 ve 0,0557. Fark sözlükte 107
belirteç, sözlük dışında 0,0008'dir ve **tamamı temsilden gelir**. Sayı katlanmış tabloda
gövdeleme sözlük dışı belirteci 12'den 9'a indirir; 3.985 belirteç üzerinden okunan üç belirteçlik
bir fark tek başına bir şey söylemez.

#### Aynı Kökün Kaç Gövdesi Var

Türkçe eklemeli bir dildir: bir kök, ardışık eklerle onlarca yüzey biçimi verir. Gövdeleyicinin
hedefi bunları tek gövdede toplamaktır; kök eşlemesi elde olduğu için hedefe ne kadar yaklaştığı
sayılabilir.

```python
bicimler = sorted({b for x in VERI for b in k2(x["not"]) if b in KOKU})
kok_gov, gov_kok = {}, {}
for b in bicimler:
    kok_gov.setdefault(KOKU[b], set()).add(govdele(b))
    gov_kok.setdefault(govdele(b), set()).add(KOKU[b])
dagilan = sorted(k for k, v in kok_gov.items() if len(v) > 1)
toplayan = sorted(g for g, v in gov_kok.items() if len(v) > 1)
print(f"notlarda gecen yuzey bicimi {len(bicimler)}, gercek kok {len(kok_gov)},"
      f" govdeleyicinin verdigi govde {len(gov_kok)}")
print(f"birden cok govdeye dagilan kok {len(dagilan)}, birden cok kok toplayan govde"
      f" {len(toplayan)}")
for k in dagilan[:8]:
    print(f"  {k:<10} -> {' '.join(sorted(kok_gov[k]))}")
for g in toplayan:
    print(f"  {g:<10} <- {' '.join(sorted(gov_kok[g]))}")

# Kok bulma cizelgesi yalniz egitim payinda gorulen bicimleri tanir.
CIZELGE = {b: KOKU[b] for x in EGT for b in k2(x["not"]) if b in KOKU}
ayr_bel = [b for x in AYR for b in k2(x["not"]) if not sayi_mi(b)]
print(f"\ncizelge {len(CIZELGE)} bicim tanir; sayi disi ayrilmis belirtecte kapsami"
      f" {sum(b in CIZELGE for b in ayr_bel) / len(ayr_bel):.4f}")
olc(katla(lambda n: [CIZELGE.get(b, b) for b in k2(n)]), "kok bulma (cizelge)", False)
olc(katla(k3), "govdeleme (kural)", False)
```

```
notlarda gecen yuzey bicimi 134, gercek kok 85, govdeleyicinin verdigi govde 103
birden cok govdeye dagilan kok 19, birden cok kok toplayan govde 1
  apartman   -> apartma apartman
  baca       -> bac baca
  bant       -> ban bant
  bul        -> bulun bulunma
  calis      -> calisiyor calismiyor
  ev         -> evd evin
  iz         -> iz izi
  kapak      -> kapag kapak
  kir        <- kir kirli

cizelge 123 bicim tanir; sayi disi ayrilmis belirtecte kapsami 0.9967
kok bulma (cizelge)             12044      82    11   0.0028
govdeleme (kural)               12044      96     9   0.0023
```

Notlarda 134 yüzey biçimi geçiyor, bunlar 85 köke ait ve gövdeleyici 103 gövde üretiyor: hedefin 18
gövde uzağında. Kusur iki yönlüdür. **Eksik gövdeleme** 85 kökün 19'unda görülür ve dört nedenden
çıkar: ünsüz yumuşaması (`kapak` ile `kapagi`), en uzun eşleşmenin yanlış eki seçmesi
(`apartmanin` içindeki `nin` atılınca `apartma` kalır), kökün son harfinin ek sanılması (`baca` ile
`bacada`) ve en az üç karakter koşulu (`izi`). Eylemler hiç çözülmez, çünkü ek listesi ad çekimine
göre yazılmıştır. **Aşırı gövdeleme** bir kez olur: `kirli` biçiminden `li` atılınca ayrı bir kök
olan `kir` ile birleşilir; `kapak kirli` ile `sayacta kir bulundu` aynı gövdeyi paylaşır.

Kök bulma başka bir denge sunar. Çizelge eğitimde görülen 123 biçimi tanır ve sözlüğü 82 belirtece
indirir; kuralın 96'sından küçüktür, gerçek kök sayısına daha yakındır. Bedeli son iki satırdadır:
kapsam 0,9967, tanınmayan biçim olduğu gibi geçiyor ve sözlük dışı belirteç 11'de kalıyor, kural
ise 9'a iniyor. Biri tanıdığı yerde daha doğru, öteki tanımadığı yerde bile işler.

Bir ayrıntı ölçümün altında durur: `sayaci` biçimi hem belirtme hem iyelik ekiyle üretilebilir.
Hiçbir belirteçleme kararı bunu ayıramaz, çünkü karar yalnız karakterlere bakar.

#### Özet

- Notlar kurgudur ve ders içinde üretilir: 1.800 not, 85 kök, tohum 20260218; şüphe oranı türe göre
  0,0486 ile 0,7835 arasındadır, en sık sınıf 0,7044 pay tutar.
- Üç belirteçleme kararı aynı 12.044 belirteçten üç ayrı sözlük çıkarır: 748, 669, 641. Alanın
  tabanı boşlukla ayırmadır ve sözlüğü 107 belirteç şişirir.
- Sözlük dışı oranı ilk iki kararda aynıdır (0,0565), çünkü sözlük dışının 0,9467'si sayıdır;
  sayılar katlandığında sözlük 203, 124, 96 olur ve oran 0,0030 ile 0,0023'e iner. Fark tamamen
  temsilden gelir: model yoktur, ölçüt her satırda aynıdır.
- Gövdeleyici 85 kökü 103 gövdeye böler; 19 kök birden çok gövdeye dağılır, bir gövde iki kökü
  toplar. Çizelgeye dayalı kök bulma sözlüğü 82'ye indirir ama kapsamı 0,9967'dir ve sözlük dışı
  belirteci 11'de bırakır.

#### Sonraki Adım

Metin belirteçlere bölündü, biçimler gövdelere ve köklere indirildi, iki ölçüt sayıldı. Ortaya
çıkan şey hâlâ bir sözcük listesidir; modelin göreceği tek bir sayı üretilmedi. M27/K02 aynı not
alanından elle beş sayı çıkarmış ve ayrılmış kümede 0,0317 katkı ölçmüştü; o beş sayı bu kursun
taban çizgisidir. Sonraki ders sözlüğün tamamını sayıya çevirir: her belirteç bir sütun olur ve
terim ağırlıklandırma üstüne konur. Ölçü, o çizginin ne kadar üstüne çıkıldığıdır.

### Sayısal Temsil

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/sayisal-temsil

Kısa saha notlarının sütuna çevrilmesinde her kararın kattığının aynı model ve aynı ayrılmış payla sayılması: alanın tabanı olan elle sayılmış beş sayı 0,7383 verirken en sık sınıf 0,7017'de kalıyor, 96 gövdelik sözcük torbası 0,8217'ye çıkıyor ve çizgiyi 0,0833 geçiyor. Sözlük boyu 8'den 64'e katkı ekliyor, 64'ten 96'ya tam sıfır ekliyor. Ham sayım ile ters belge sıklığı ağırlığı doğruluğu hiç oynatmıyor (0,0833), taşıyıcı sözcük atmak 0,0067 kaybettiriyor ve olay türünü bilen tavan 0,8250 — torba tavanın 0,0033 altındadır.

Önceki ders metni belirteçlere böldü ve sözlüğü 96 gövdeye indirdi. Ortaya çıkan şey hâlâ bir
sözcük listesiydi; bir modelin göreceği tek bir sayı üretilmemişti. Bu ders sözlüğü sütuna
çevirir: her gövde bir sütun olur, notta geçip geçmediği o sütunun değeri olur. Yordamın adı
**sözcük torbasıdır**, çünkü sıra atılır — `muhur kirik` ile `kirik muhur` aynı satırı verir.

Ölçünün çizgisi hazırdır. M27/K02 aynı not alanından elle beş sayı çıkarmış ve o beş sayı bir
karar ağacına ayrılmış kümede 0,0317 katmıştı. **Alanın tabanı** o beş sayıdır: bir metinden sayı
çıkarmanın en ucuz yolu. Sözcük torbası bu çizginin ne kadar üstüne çıkıyor, sözlük boyu büyüdükçe
katkı ne yapıyor ve terim ağırlıklandırma üstüne ne koyuyor.

- **NL9.** Kurgu, küme ve tohum `nlp/01`'deki gibidir. Belirteçleme kararı 01'in üçüncü kararıdır
  — noktalama atma, küçük harfe inme, gövdeleme, sayı katlama — ve bu derste **sabittir**.
- **NL10.** Görev ikili kaçak şüphesi kestirimidir. Ölçüt ayrılmış paydaki doğruluktur (büyük iyi)
  ve yanına şüpheli sınıfın duyarlılığı yazılır. Ölçüt tanımları M27/K03'te kuruldu, tekrarlanmaz.
- **NL11.** Bütün temsiller **aynı modeli** kullanır: tek katmanlı doğrusal model, tam toplu eğim
  inişi, 120 tur, adım 1,5, eşik sıfır. Model ve ölçüt sabit olduğu için fark yalnız temsilden
  gelebilir.
- **NL12.** Boru hattının her adımı **yalnız eğitim payından** öğrenilir: sözlük, belge sıklığı,
  ortalama ve standart sapma. M27/K02'nin kuralı sürer.
- **NL13.** Alanın tabanı **elle sayılmış beş sayıdır**: not uzunluğu, sözcük sayısı ve üç anahtar
  sözcük göstergesi (mühür, erişim, araç). İlk ikisi eğitim payının ortalaması ve standart
  sapmasıyla ölçeklenir. En sık sınıf mutlak tabandır ve duyarlılığı sıfırdır.
- **NL14.** Sözlük boyu süpürmesi altı adaydır: 8, 16, 32, 48, 64, 96. Sözlük, eğitim payının en
  sık gövdelerinden sırayla alınır.
- **NL15.** Terim ağırlıklandırma **biçimiyle** anılır: ham sayım ve sayımın ters belge
  sıklığıyla çarpımı — ikincisi belge başına birim uzunluğa getirilir.
- **NL16.** Tavan, olay türünü bilen bir yordamın aynı ölçütteki sayısıdır; etiket yalnız türden
  üretildiği için metinden okunabilecek en yüksek sayı budur.

#### Kurulum

Notlar `nlp/01`'in kurgusuyla aynı tohumdan yeniden üretilir.

```python
# ORTAK — KURGUDUR. Saha notlari ders icinde uretilir, tohum 20260218; kaynak
# sistemden gelmez. Sozluk 45 cekimli kok ve 40 seyrek addan olusur.
TOHUM, NOT_SAYISI, M32 = 20260218, 1800, 0xFFFFFFFF

AD = {  # 0 yalin, 1 ilgi, 2 bulunma, 3 iyelik, 4 cogul
    "sayac": "sayac sayacin sayacta sayaci sayaclar",
    "kapak": "kapak kapagin kapakta kapagi kapaklar",
    "muhur": "muhur muhurun muhurde muhuru muhurler",
    "vana": "vana vananin vanada vanasi vanalar",
    "kelepce": "kelepce kelepcenin kelepcede kelepcesi kelepceler",
    "boru": "boru borunun boruda borusu borular",
    "pano": "pano panonun panoda panosu panolar",
    "kapi": "kapi kapinin kapida kapisi kapilar",
    "zil": "zil zilin zilde zili ziller",
    "bahce": "bahce bahcenin bahcede bahcesi bahceler",
    "apartman": "apartman apartmanin apartmanda apartmani apartmanlar",
    "bodrum": "bodrum bodrumun bodrumda bodrumu bodrumlar",
    "giris": "giris girisin giriste girisi girisler",
    "adres": "adres adresin adreste adresi adresler",
    "okuma": "okuma okumanin okumada okumasi okumalar",
    "olcum": "olcum olcumun olcumde olcumu olcumler",
    "erisim": "erisim erisimin erisimde erisimi erisimler",
    "ziyaret": "ziyaret ziyaretin ziyarette ziyareti ziyaretler",
    "abone": "abone abonenin abonede abonesi aboneler",
    "arac": "arac aracin aracta araci araclar",
    "kir": "kir kirin kirde kiri kirler",
    "iz": "iz izin izde izi izler",
    "sokak": "sokak sokagin sokakta sokagi sokaklar",
    "ev": "ev evin evde evi evler",
}
NITELIK = "kirik gevsek kirli normal bozuk acik kapali eksik temiz yeni yok".split()
EYLEM = {  # 0 edilgen gecmis, 1 olumsuz
    "calis": "calisiyor calismiyor", "don": "donuyor donmuyor", "oku": "okundu okunmadi",
    "ac": "acildi acilmadi", "gir": "girildi girilemedi", "ulas": "ulasildi ulasilamadi",
    "tekrarla": "tekrarlandi tekrarlanmadi", "bul": "bulundu bulunmadi",
    "sagla": "saglandi saglanamadi", "degil": "degil degildi",
}
NADIR = """kablo kablosu kabloda|cam cami camda|tel teli telde|mandal mandali mandalda
merdiven merdiveni merdivende|tahta tahtasi tahtada|cukur cukuru cukurda|kar kari karda
buz buzu buzda|cop copu copta|duvar duvari duvarda|kutu kutusu kutuda|vida vidasi vidada
conta contasi contada|filtre filtresi filtrede|bant banti bantta|etiket etiketi etikette
kilit kiliti kilitte|asansor asansoru asansorde|zemin zemini zeminde|tavan tavani tavanda
kuyu kuyusu kuyuda|depo deposu depoda|ocak ocagi ocakta|direk diregi direkte
kanal kanali kanalda|numara numarasi numarada|cati catisi catida|baca bacasi bacada
kova kovasi kovada|levha levhasi levhada|somun somunu somunda|tapa tapasi tapada
izolasyon izolasyonu izolasyonda|supap supabi supapta|menfez menfezi menfezde
kayit kaydi kayitta|temel temeli temelde|kose kosesi kosede|koruma korumasi korumada"""
OBEK = {
    "olagan": ["{sayac.0} {calis.0}", "{okuma.0} normal", "{olcum.0} {tekrarla.0}",
               "{sayac.1} {erisim.3} {sagla.0}", "{kapak.0} temiz", "{vana.0} acik",
               "{sayac.2} {iz.0} {bul.1}", "{olcum.0} icin {erisim.0} {sagla.0}",
               "{sayac.1} {kapak.3} yeni", "{muhur.0} ile {kapak.0} temiz"],
    "ariza": ["{sayac.0} {don.1}", "{kapak.0} kirik", "{pano.0} bozuk",
              "{sayac.1} {kapak.3} kirik", "{olcum.0} {oku.1}", "{vana.0} bozuk",
              "{sayac.2} {kir.0} {bul.0}", "{sayac.4} {calis.1}",
              "{sayac.0} {calis.0} ama {okuma.0} yok",
              "{pano.1} {kapak.3} eksik"],
    "erisilemedi": ["{kapi.0} {ac.1}", "{zil.0} {calis.1}", "{abone.0} {ev.2} {degil.1}",
                    "{erisim.0} {sagla.1}", "{bodrum.0} {kapi.3} kapali",
                    "{apartman.1} {giris.3} kapali", "{adres.2} {ulas.1}",
                    "{bahce.1} {kapi.3} kapali", "{apartman.2} {zil.0} {calis.1}",
                    "{sayac.2} {erisim.0} yok"],
    "kacak": ["{muhur.0} kirik", "{kelepce.0} gevsek", "{muhur.2} {iz.0} {bul.0}",
              "{sayac.1} {muhur.3} kirik", "{kelepce.2} {iz.0} {bul.0}",
              "{muhur.0} eksik", "{vana.1} {kelepce.3} gevsek",
              "{muhur.1} {iz.3} {bul.0}", "{boru.2} {kelepce.0} eksik",
              "{kapak.2} bir {iz.0} {bul.0}"],
}
EK_OBEK = ["{ziyaret.0} {tekrarla.0}", "{sokak.2} {arac.0} {bul.0}", "{adres.0} yeni",
           "{bahce.1} {kapi.3} acik", "{apartman.2} {gir.0}", "{ev.1} {kapi.3} acik",
           "{kapak.0} kirli", "{olcum.0} {tekrarla.1}", "{arac.0} {sokak.2}",
           "bu {ziyaret.2} {olcum.0} {tekrarla.0}"]
TUR = [("olagan", 0.36, 0.04), ("ariza", 0.26, 0.28),
       ("erisilemedi", 0.16, 0.15), ("kacak", 0.22, 0.82)]
BICIM = {k: v.split() for d in (AD, EYLEM) for k, v in d.items()}
SEYREK = [s.split() for s in NADIR.replace("\n", "|").split("|")]
AGIRLIK = [1 / (i + 1) ** 1.6 for i in range(len(SEYREK))]
AGIRLIK = [w / sum(AGIRLIK) for w in AGIRLIK]
KOKU = {f: k for k, fs in BICIM.items() for f in fs}
KOKU.update({f: fs[0] for fs in SEYREK for f in fs})
KOKU.update({w: w for w in NITELIK})
TASIYICI = ["ve", "ile", "bir", "bu", "ama", "icin"]
KOKU.update({w: w for w in TASIYICI})


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 obek_yaz(sablon):
    p = []
    for s in sablon.split():
        if s.startswith("{"):
            kok, _, i = s[1:-1].partition(".")
            p.append(BICIM[kok][int(i)])
        else:
            p.append(s)
    return " ".join(p)


VERI = []
for i in range(NOT_SAYISI):
    r = uretec(TOHUM + i)
    t = TUR[ayrik(r(), [x[1] for x in TUR])]
    c = [obek_yaz(OBEK[t[0]][int(r() * 10)])]
    if r() < 0.55:
        c.append(obek_yaz(EK_OBEK[int(r() * 10)]))
    if r() < 0.30:
        c.append(obek_yaz(OBEK[t[0]][int(r() * 10)]))
    if r() < 0.22:
        f, nit = SEYREK[ayrik(r(), AGIRLIK)], NITELIK[int(r() * len(NITELIK))]
        c.append(f[2] + " kir bulundu" if r() < 0.34 else f[int(r() * 2)] + " " + nit)
    n = c[0]
    for x in c[1:]:
        n += (" ve " if r() < 0.22 else ", ") + x
    if r() < 0.52:
        n += ", okuma " + str(240 + int(r() * 1760))
    VERI.append({"no": 10001 + i, "not": n[0].upper() + n[1:] + ".",
                 "tur": t[0], "supheli": int(r() < t[2])})

EGT, AYR = VERI[:1200], VERI[1200:]
print(f"{len(VERI)} kurgu not, {len(BICIM) + len(SEYREK) + len(NITELIK)} kok, "
      f"supheli orani {sum(x['supheli'] for x in VERI) / len(VERI):.4f}")
print(VERI[3]["not"])
```

```
1800 kurgu not, 85 kok, supheli orani 0.2956
Olcum icin erisim saglandi, sayacin kapagi yeni, mandalda kir bulundu.
```

#### Sözcük Torbası ve Sözlük Boyu

Model bir kez yazılır ve bütün satırlarda aynı kalır. Öznitelikler seyrek verilir: bir notta on
birkaç gövde bulunduğu için, sütun 96'ya çıksa da satır başına birkaç çarpma yapılır.

```python
import math
from collections import Counter

EKLER = ["lari", "leri", "lar", "ler", "nin", "nun", "dan", "den", "tan", "ten",
         "dir", "tir", "dur", "da", "de", "ta", "te", "in", "un", "yi", "yu",
         "si", "su", "li", "lu", "di", "du", "ti", "tu", "i", "u", "a", "e"]


def govdele(b):
    for e in EKLER:
        if b.endswith(e) and len(b) - len(e) >= 3:
            return b[:-len(e)]
    return b


for x in VERI:  # nlp/01'in ucuncu karari: noktalama atma, kucuk harf, govdeleme, sayi katlama
    x["bel"] = [("<sayi>" if b.isdigit() else govdele(b))
                for b in (s.strip(",.").lower() for s in x["not"].split()) if b]


def egit(ozn, y, boyut, tur=120, adim=1.5):
    w = [0.0] * (boyut + 1)
    for _ in range(tur):
        g = [0.0] * (boyut + 1)
        for x, t in zip(ozn, y):
            z = w[boyut] + sum(w[i] * v for i, v in x)
            d = 1 / (1 + math.exp(-max(-30.0, min(30.0, z)))) - t
            for i, v in x:
                g[i] += d * v
            g[boyut] += d
        for i in range(boyut + 1):
            w[i] -= adim * g[i] / len(y)
    return w


def olc(w, ozn, y, boyut):
    d = p = 0
    for x, e in zip(ozn, y):
        k = int(w[boyut] + sum(w[i] * v for i, v in x) > 0)
        d, p = d + (k == e), p + (k == 1 and e == 1)
    return d / len(y), p / sum(y)


def kur(ad, yap, boyut):  # ilk cagri cizgiyi kurar
    ye, ya = [x["supheli"] for x in EGT], [x["supheli"] for x in AYR]
    w = egit([yap(x) for x in EGT], ye, boyut)
    de, _ = olc(w, [yap(x) for x in EGT], ye, boyut)
    da, dy = olc(w, [yap(x) for x in AYR], ya, boyut)
    if not CIZGI:
        CIZGI.append(da)
    print(f"{ad:<24} {boyut:>6} {de:>9.4f} {da:>9.4f} {dy:>10.4f} {da - CIZGI[0]:>+8.4f}")
    return da


ANAHTAR, CIZGI = ["muhur", "erisim", "arac"], []
ham = [[len(x["not"]), len(x["bel"])] for x in EGT]
ORT = [sum(h[i] for h in ham) / len(ham) for i in (0, 1)]
SAP = [math.sqrt(sum((h[i] - ORT[i]) ** 2 for h in ham) / len(ham)) for i in (0, 1)]


def elle(x):  # M27/K02'nin bes sayisi: iki bicim olcusu, uc anahtar sozcuk gostergesi
    o = [(0, (len(x["not"]) - ORT[0]) / SAP[0]), (1, (len(x["bel"]) - ORT[1]) / SAP[1])]
    for i, a in enumerate(ANAHTAR):
        o.append((2 + i, float(any(b.startswith(a) for b in x["bel"]))))
    return o


TABAN = sum(x["supheli"] == 0 for x in AYR) / len(AYR)
print(f"{'temsil':<24} {'sutun':>6} {'egitimde':>9} {'ayrilmis':>9} {'duyarlilik':>10}"
      f" {'cizgiden':>8}")
kur("elle sayilmis bes sayi", elle, 5)
print(f"{'en sik sinif':<24} {0:>6} {'':>9} {TABAN:>9.4f} {0.0:>10.4f}"
      f" {TABAN - CIZGI[0]:>+8.4f}")

SIK = Counter(b for x in EGT for b in x["bel"])
SIRA = sorted(SIK, key=lambda b: (-SIK[b], b))
BELGE = Counter(b for x in EGT for b in set(x["bel"]))
TASIYICI_G = {govdele(w) for w in TASIYICI}


def torba(terim, kip="gosterge"):
    d = {b: i for i, b in enumerate(terim)}
    ters = {b: math.log(len(EGT) / BELGE.get(b, 1)) for b in d}

    def yap(x):
        c = Counter(b for b in x["bel"] if b in d)
        if kip == "gosterge":
            return [(d[b], 1.0) for b in c]
        if kip == "sayim":
            return [(d[b], float(v)) for b, v in c.items()]
        u = math.sqrt(sum((v * ters[b]) ** 2 for b, v in c.items())) or 1.0
        return [(d[b], v * ters[b] / u) for b, v in c.items()]
    return yap


print()
for n in (8, 16, 32, 48, 64, 96):
    kur(f"sozcuk torbasi {n}", torba(SIRA[:n]), n)
```

```
temsil                    sutun  egitimde  ayrilmis duyarlilik cizgiden
elle sayilmis bes sayi        5    0.7608    0.7383     0.3408  +0.0000
en sik sinif                  0              0.7017     0.0000  -0.0367

sozcuk torbasi 8              8    0.7783    0.7667     0.3296  +0.0283
sozcuk torbasi 16            16    0.7908    0.7700     0.3911  +0.0317
sozcuk torbasi 32            32    0.8208    0.8067     0.5140  +0.0683
sozcuk torbasi 48            48    0.8300    0.8133     0.5363  +0.0750
sozcuk torbasi 64            64    0.8333    0.8217     0.5698  +0.0833
sozcuk torbasi 96            96    0.8350    0.8217     0.5698  +0.0833
```

Çizgi 0,7383'tür ve en sık sınıfı 0,0367 geçiyor. M27/K02'de aynı beş sayı bir karar ağacına
0,0317 katmıştı; iki sayının yakınlığı tesadüf değildir, çünkü katkının kaynağı her iki kurulumda
da aynı üç anahtar göstergedir. Duyarlılık sütunu tabanın niçin okunması gerektiğini gösteriyor:
en sık sınıf 0,7017 doğruluk verirken şüphelilerin **hiçbirini** bulmuyor.

Sözcük torbası çizgiyi 0,0833 geçiyor — elle sayılan beş sayının kattığının iki katından fazla.
Sekiz sütun bile 0,0283 katıyor, yani en sık sekiz gövde elle seçilmiş beş göstergeye yakın iş
görüyor. Katkı 64 sütunda doyuyor: 64 ile 96 arasında ayrılmış küme sayısı **tam olarak aynı**
kalırken eğitim sayısı 0,8333'ten 0,8350'ye çıkıyor. Sütun eklemek eğitim sayısını her zaman
artırır; bu bir ölçüm değil, tanımın gereğidir.

#### Ağırlıklandırma ve Tavan

Torbanın hücresine ne yazıldığı ayrı bir karardır: varlık göstergesi, ham sayım ya da sıklığın
belgeler arası seyrekliğiyle ağırlıklandırılmış hâli.

```python
kur("sayim agirligi", torba(SIRA, "sayim"), len(SIRA))
kur("ters belge sikligi", torba(SIRA, "agirlik"), len(SIRA))
SUZ = [b for b in SIRA if b not in TASIYICI_G]
kur("tasiyici sozcuk atilmis", torba(SUZ), len(SUZ))

TUR_ET = {}
for a, _, _ in TUR:
    p = [x["supheli"] for x in EGT if x["tur"] == a]
    TUR_ET[a] = int(sum(p) * 2 > len(p))
tavan = sum(TUR_ET[x["tur"]] == x["supheli"] for x in AYR) / len(AYR)
print(f"\n{'olay turunu bilen tavan':<24} {'':>6} {'':>9} {tavan:>9.4f} {'':>10}"
      f" {tavan - CIZGI[0]:>+8.4f}")
```

```
sayim agirligi               96    0.8333    0.8217     0.5698  +0.0833
ters belge sikligi           96    0.8150    0.8217     0.5363  +0.0833
tasiyici sozcuk atilmis      90    0.8292    0.8150     0.5419  +0.0767

olay turunu bilen tavan                      0.8250             +0.0867
```

Terim ağırlıklandırma bu derlemde **hiçbir şey katmıyor**: üç satır da 0,8217 veriyor. Nedeni
metnin kendisindedir. Notlar kısadır ve bir gövde bir notta neredeyse hep bir kez geçer, bu yüzden
ham sayım gösterge sütunundan ayrışmaz. Ters belge sıklığı ağırlığı sütunları yeniden ölçeklendirir
ama sıralamayı bozmaz; doğruluk aynı kalırken duyarlılık 0,5698'den 0,5363'e düşüyor. Kattığı fark
0,0000'dır.

Taşıyıcı sözcük atmak 0,0067 **kaybettiriyor**. Altı taşıyıcı sözcüğün üçü bu kurguda belirli
kalıpların işaretidir: `ile` yalnız olağan öbekte, `ama` yalnız arıza öbeğinde geçer. Taşıyıcı
sözcük listesi dilden değil görevden okunur; genel bir liste burada bilgi atıyor.

Son satır kalan boşluğu kapatıyor. Olay türünü bilen bir yordam 0,8250 veriyor ve sözcük torbası
0,8217 ile bunun 0,0033 altında. Etiket yalnız türden üretildiği için metinden okunabilecek en
yüksek sayı budur: daha iyi bir temsil bu kurguda 0,0033'ten fazlasını kazanamaz. Farkın kaynağı
da böylece yazılabilir — model bütün satırlarda aynı, ölçüt ve ayrılmış pay aynı, **fark
temsilden** gelir.

#### Özet

- Alanın tabanı elle sayılmış beş sayıdır ve 0,7383 verir; en sık sınıf 0,7017'de kalır ve
  şüphelilerin hiçbirini bulmaz.
- 96 gövdelik sözcük torbası 0,8217 verir ve çizgiyi 0,0833 geçer — elle sayılan beş sayının
  kattığının iki katından fazla. Model ile ölçüt sabit olduğu için farkın tamamı temsilden gelir.
- Sözlük boyu 8'den 64'e katkı ekler ve orada doyar: 64 ile 96 arasındaki fark tam sıfırken eğitim
  sayısı 0,8333'ten 0,8350'ye çıkar.
- Terim ağırlıklandırma 0,0000 katar; notlar kısa olduğu için sayım göstergeden ayrışmaz, ters
  belge sıklığı ağırlığı doğruluğu değil duyarlılığı oynatır (0,5698'den 0,5363'e). Taşıyıcı sözcük
  atmak 0,0067 kaybettirir, çünkü listedeki üç sözcük bu kurguda kalıp işaretidir.
- Olay türünü bilen tavan 0,8250'dir; torba tavanın 0,0033 altındadır ve kalan boşluk metinde
  değildir.

#### Sonraki Adım

Sözcük torbası bir notu 96 sütuna çevirdi, ama sütunlar birbirine tümüyle yabancıdır: `muhur` ile
`kelepce` sütunları, `muhur` ile `<sayi>` sütunları kadar uzaktır. Modelin öğrendiği tek şey her
sütunun etiketle ilişkisidir ve bu ilişki her sütun için sıfırdan öğrenilir. Oysa notlarda `muhur`
ile `kelepce` benzer sözcüklerin yanında geçiyor. Sonraki ders bunu kullanır: her gövde bir sayı
yerine bir vektörle temsil edilir ve vektör **bağlamdan** öğrenilir. Ölçü, öğrenilen komşuluğun
anlamlı çıkıp çıkmadığı ve vektör aritmetiğinin kaç durumda tuttuğudur.

### Kelime Gömmeleri

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/kelime-gommeleri

Sözlüğün her öğesine bağlamdan öğrenilen bir vektör verilmesi ve komşuluğun kurgunun kendi öbek havuzlarına karşı sayılması: rastgele komşunun beklenen oranı 0,2543 iken ham birlikte geçme vektörü 0,4938, sekiz boyutlu öğrenilen gömme 0,6049 veriyor. Toplam sayı yanıltıyor — 81 biçimin 49'u tek bir kalıpta geçen seyrek adlardır ve orada ham sayım bile 0,7755 veriyor, sık biçimlerde ise rastgele 0,0462, ham sayım 0,0625, öğrenilen gömme 0,2500. Oran benzeşimi 72 sınamanın 0,0972'sinde tutuyor ve tutmayanlar en sık sözcüğe değil, bağlamı en dar biçimlere düşüyor.

Sözcük torbası bir notu 96 sütuna çevirdi, ama sütunlar birbirine yabancıydı: `muhur` sütunu ile
`kelepce` sütunu, `muhur` ile `<sayi>` sütunu kadar uzaktı. Oysa notlarda bu ikisi aynı öbeklerde,
aynı sözcüklerin yanında geçiyor. Bu derste her sözlük öğesine bir vektör verilir ve vektör
etiketten değil **bağlamdan** öğrenilir. İddia dağılımsal anlamdır: benzer bağlamda geçen
sözcükler benzer vektör alır.

Gömme tablosunun kendisi M27/K05'te ölçüldü ve yordamı tekrarlanmaz. Buradaki ekleme ölçünün
yerini değiştirmektir: sayı bir sınıflandırıcının doğruluğu değil, **vektörlerin kendi düzenidir**.
İki sınama yapılır ve ikisi de kendi tabanına karşı okunur.

- **NL17.** Belirteçleme burada `nlp/01`'in **ikinci** kararıdır: noktalama atma, küçük harfe
  inme, sayı katlama. Gövdeleme uygulanmaz, çünkü ölçülecek şeylerden biri çekim eklerinin
  vektörlerde iz bırakıp bırakmadığıdır. Sözlük 124 öğedir.
- **NL18.** Gömme tablosu M27/K05 `mimariler/08`'de ölçüldü; katman yordamı tekrarlanmaz.
- **NL19.** Model ders içinde yazılır ve **modeldir**: her öğe için bir merkez ve bir bağlam
  vektörü, sekiz boyut, toplam 1.984 parametre.
- **NL20.** Eğitim: bağlam penceresi iki, her ayrı çift için iki karşıt örnek, çift sayısına
  $\log(1+n)$ ağırlığı, 40 tur, adım 0,08. Karşıt örnek sözlükten kendi sıklığıyla çekilir.
- **NL21.** Vektörler yalnız **eğitim payından** öğrenilir; çiftler 1.200 nottan çıkarılır.
- **NL22.** Ölçüt **açı benzerliğidir**: vektörler birim uzunluğa getirilir, iç çarpım okunur.
- **NL23.** Komşuluk sınamasının doğrusu kurgudan gelir: bir biçim, kökü tek bir öbek havuzunda
  geçiyorsa o havuzun grubuna aittir. 124 öğenin 81'i böyledir.
- **NL24.** Alanın tabanı **ham birlikte geçme vektörüdür**: hiçbir şey öğrenmez, yalnız sayar.
  Mutlak taban rastgele komşudur ve beklenen oranı grup büyüklüklerinden hesaplanır.

#### Bağlamdan Öğrenilen Vektörler

Notlar `nlp/01`'in kurgusuyla aynı tohumdan yeniden üretilir.

```python
# ORTAK — KURGUDUR. Saha notlari ders icinde uretilir, tohum 20260218; kaynak
# sistemden gelmez. Sozluk 45 cekimli kok ve 40 seyrek addan olusur.
TOHUM, NOT_SAYISI, M32 = 20260218, 1800, 0xFFFFFFFF

AD = {  # 0 yalin, 1 ilgi, 2 bulunma, 3 iyelik, 4 cogul
    "sayac": "sayac sayacin sayacta sayaci sayaclar",
    "kapak": "kapak kapagin kapakta kapagi kapaklar",
    "muhur": "muhur muhurun muhurde muhuru muhurler",
    "vana": "vana vananin vanada vanasi vanalar",
    "kelepce": "kelepce kelepcenin kelepcede kelepcesi kelepceler",
    "boru": "boru borunun boruda borusu borular",
    "pano": "pano panonun panoda panosu panolar",
    "kapi": "kapi kapinin kapida kapisi kapilar",
    "zil": "zil zilin zilde zili ziller",
    "bahce": "bahce bahcenin bahcede bahcesi bahceler",
    "apartman": "apartman apartmanin apartmanda apartmani apartmanlar",
    "bodrum": "bodrum bodrumun bodrumda bodrumu bodrumlar",
    "giris": "giris girisin giriste girisi girisler",
    "adres": "adres adresin adreste adresi adresler",
    "okuma": "okuma okumanin okumada okumasi okumalar",
    "olcum": "olcum olcumun olcumde olcumu olcumler",
    "erisim": "erisim erisimin erisimde erisimi erisimler",
    "ziyaret": "ziyaret ziyaretin ziyarette ziyareti ziyaretler",
    "abone": "abone abonenin abonede abonesi aboneler",
    "arac": "arac aracin aracta araci araclar",
    "kir": "kir kirin kirde kiri kirler",
    "iz": "iz izin izde izi izler",
    "sokak": "sokak sokagin sokakta sokagi sokaklar",
    "ev": "ev evin evde evi evler",
}
NITELIK = "kirik gevsek kirli normal bozuk acik kapali eksik temiz yeni yok".split()
EYLEM = {  # 0 edilgen gecmis, 1 olumsuz
    "calis": "calisiyor calismiyor", "don": "donuyor donmuyor", "oku": "okundu okunmadi",
    "ac": "acildi acilmadi", "gir": "girildi girilemedi", "ulas": "ulasildi ulasilamadi",
    "tekrarla": "tekrarlandi tekrarlanmadi", "bul": "bulundu bulunmadi",
    "sagla": "saglandi saglanamadi", "degil": "degil degildi",
}
NADIR = """kablo kablosu kabloda|cam cami camda|tel teli telde|mandal mandali mandalda
merdiven merdiveni merdivende|tahta tahtasi tahtada|cukur cukuru cukurda|kar kari karda
buz buzu buzda|cop copu copta|duvar duvari duvarda|kutu kutusu kutuda|vida vidasi vidada
conta contasi contada|filtre filtresi filtrede|bant banti bantta|etiket etiketi etikette
kilit kiliti kilitte|asansor asansoru asansorde|zemin zemini zeminde|tavan tavani tavanda
kuyu kuyusu kuyuda|depo deposu depoda|ocak ocagi ocakta|direk diregi direkte
kanal kanali kanalda|numara numarasi numarada|cati catisi catida|baca bacasi bacada
kova kovasi kovada|levha levhasi levhada|somun somunu somunda|tapa tapasi tapada
izolasyon izolasyonu izolasyonda|supap supabi supapta|menfez menfezi menfezde
kayit kaydi kayitta|temel temeli temelde|kose kosesi kosede|koruma korumasi korumada"""
OBEK = {
    "olagan": ["{sayac.0} {calis.0}", "{okuma.0} normal", "{olcum.0} {tekrarla.0}",
               "{sayac.1} {erisim.3} {sagla.0}", "{kapak.0} temiz", "{vana.0} acik",
               "{sayac.2} {iz.0} {bul.1}", "{olcum.0} icin {erisim.0} {sagla.0}",
               "{sayac.1} {kapak.3} yeni", "{muhur.0} ile {kapak.0} temiz"],
    "ariza": ["{sayac.0} {don.1}", "{kapak.0} kirik", "{pano.0} bozuk",
              "{sayac.1} {kapak.3} kirik", "{olcum.0} {oku.1}", "{vana.0} bozuk",
              "{sayac.2} {kir.0} {bul.0}", "{sayac.4} {calis.1}",
              "{sayac.0} {calis.0} ama {okuma.0} yok",
              "{pano.1} {kapak.3} eksik"],
    "erisilemedi": ["{kapi.0} {ac.1}", "{zil.0} {calis.1}", "{abone.0} {ev.2} {degil.1}",
                    "{erisim.0} {sagla.1}", "{bodrum.0} {kapi.3} kapali",
                    "{apartman.1} {giris.3} kapali", "{adres.2} {ulas.1}",
                    "{bahce.1} {kapi.3} kapali", "{apartman.2} {zil.0} {calis.1}",
                    "{sayac.2} {erisim.0} yok"],
    "kacak": ["{muhur.0} kirik", "{kelepce.0} gevsek", "{muhur.2} {iz.0} {bul.0}",
              "{sayac.1} {muhur.3} kirik", "{kelepce.2} {iz.0} {bul.0}",
              "{muhur.0} eksik", "{vana.1} {kelepce.3} gevsek",
              "{muhur.1} {iz.3} {bul.0}", "{boru.2} {kelepce.0} eksik",
              "{kapak.2} bir {iz.0} {bul.0}"],
}
EK_OBEK = ["{ziyaret.0} {tekrarla.0}", "{sokak.2} {arac.0} {bul.0}", "{adres.0} yeni",
           "{bahce.1} {kapi.3} acik", "{apartman.2} {gir.0}", "{ev.1} {kapi.3} acik",
           "{kapak.0} kirli", "{olcum.0} {tekrarla.1}", "{arac.0} {sokak.2}",
           "bu {ziyaret.2} {olcum.0} {tekrarla.0}"]
TUR = [("olagan", 0.36, 0.04), ("ariza", 0.26, 0.28),
       ("erisilemedi", 0.16, 0.15), ("kacak", 0.22, 0.82)]
BICIM = {k: v.split() for d in (AD, EYLEM) for k, v in d.items()}
SEYREK = [s.split() for s in NADIR.replace("\n", "|").split("|")]
AGIRLIK = [1 / (i + 1) ** 1.6 for i in range(len(SEYREK))]
AGIRLIK = [w / sum(AGIRLIK) for w in AGIRLIK]
KOKU = {f: k for k, fs in BICIM.items() for f in fs}
KOKU.update({f: fs[0] for fs in SEYREK for f in fs})
KOKU.update({w: w for w in NITELIK})
TASIYICI = ["ve", "ile", "bir", "bu", "ama", "icin"]
KOKU.update({w: w for w in TASIYICI})


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 obek_yaz(sablon):
    p = []
    for s in sablon.split():
        if s.startswith("{"):
            kok, _, i = s[1:-1].partition(".")
            p.append(BICIM[kok][int(i)])
        else:
            p.append(s)
    return " ".join(p)


VERI = []
for i in range(NOT_SAYISI):
    r = uretec(TOHUM + i)
    t = TUR[ayrik(r(), [x[1] for x in TUR])]
    c = [obek_yaz(OBEK[t[0]][int(r() * 10)])]
    if r() < 0.55:
        c.append(obek_yaz(EK_OBEK[int(r() * 10)]))
    if r() < 0.30:
        c.append(obek_yaz(OBEK[t[0]][int(r() * 10)]))
    if r() < 0.22:
        f, nit = SEYREK[ayrik(r(), AGIRLIK)], NITELIK[int(r() * len(NITELIK))]
        c.append(f[2] + " kir bulundu" if r() < 0.34 else f[int(r() * 2)] + " " + nit)
    n = c[0]
    for x in c[1:]:
        n += (" ve " if r() < 0.22 else ", ") + x
    if r() < 0.52:
        n += ", okuma " + str(240 + int(r() * 1760))
    VERI.append({"no": 10001 + i, "not": n[0].upper() + n[1:] + ".",
                 "tur": t[0], "supheli": int(r() < t[2])})

EGT, AYR = VERI[:1200], VERI[1200:]
print(f"{len(VERI)} kurgu not, {len(BICIM) + len(SEYREK) + len(NITELIK)} kok, "
      f"supheli orani {sum(x['supheli'] for x in VERI) / len(VERI):.4f}")
print(VERI[3]["not"])
```

```
1800 kurgu not, 85 kok, supheli orani 0.2956
Olcum icin erisim saglandi, sayacin kapagi yeni, mandalda kir bulundu.
```

Eğitim her ayrı bağlam çiftini bir kez görür: merkez sözcüğün vektörü ile gerçek komşunun bağlam
vektörü birbirine yaklaştırılır, sözlükten çekilen iki karşıt örneğinki uzaklaştırılır.

```python
import math
from collections import Counter

BOYUT, PENCERE, KARSIT, TUR_SAYI, ADIM = 8, 2, 2, 40, 0.08

for x in VERI:  # nlp/01'in ikinci karari: noktalama atma, kucuk harf, sayi katlama
    x["bel"] = [("<sayi>" if b.isdigit() else b)
                for b in (s.strip(",.").lower() for s in x["not"].split()) if b]

SIK = Counter(b for x in EGT for b in x["bel"])
SOZ = sorted(SIK, key=lambda b: (-SIK[b], b))
YER = {b: i for i, b in enumerate(SOZ)}
CIFT = Counter()
for x in EGT:
    d = [YER[b] for b in x["bel"]]
    for i, a in enumerate(d):
        for j in range(max(0, i - PENCERE), min(len(d), i + PENCERE + 1)):
            if j != i:
                CIFT[(a, d[j])] += 1

T = sum(SIK.values())
GURULTU = [SIK[b] / T for b in SOZ]  # karsit ornek sozcugun kendi sikligiyla cekilir
r = uretec(TOHUM + 31000)
U = [[(r() - 0.5) * 0.6 for _ in range(BOYUT)] for _ in SOZ]
C = [[0.0] * BOYUT for _ in SOZ]
for _ in range(TUR_SAYI):
    for (a, b), n in CIFT.items():
        w = math.log(1 + n)
        for k, hedef in [(b, 1.0)] + [(ayrik(r(), GURULTU), 0.0) for _ in range(KARSIT)]:
            z = sum(U[a][i] * C[k][i] for i in range(BOYUT))
            d = ADIM * w * (1 / (1 + math.exp(-max(-30.0, min(30.0, z)))) - hedef)
            for i in range(BOYUT):
                U[a][i], C[k][i] = U[a][i] - d * C[k][i], C[k][i] - d * U[a][i]

print(f"{len(SOZ)} sozluk ogesi, {len(CIFT)} ayri baglam cifti, "
      f"{2 * len(SOZ) * BOYUT} parametre, {TUR_SAYI} tur")


def birim(v):
    u = math.sqrt(sum(x * x for x in v)) or 1.0
    return [x / u for x in v]


BIRIM = [birim(v) for v in U]


def aci(i, j):
    return sum(BIRIM[i][k] * BIRIM[j][k] for k in range(BOYUT))


GRUP = {}
for tur, kalip in OBEK.items():
    for k in kalip:
        for s in k.split():
            a = s[1:-1].partition(".")[0] if s.startswith("{") else s
            GRUP.setdefault(a, set()).add(tur)
for k in EK_OBEK:
    for s in k.split():
        a = s[1:-1].partition(".")[0] if s.startswith("{") else s
        GRUP.setdefault(a, set()).add("ek")
for f in SEYREK:
    GRUP[f[0]] = {"seyrek"}
TEK = {a for a, v in GRUP.items() if len(v) == 1}
BICIM_GRUP = {b: list(GRUP[KOKU[b]])[0] for b in SOZ
              if b in KOKU and KOKU[b] in TEK}
SAY = Counter(BICIM_GRUP.values())
print(f"{len(BICIM_GRUP)} bicim tek bir obek havuzuna ait: "
      + ", ".join(f"{g} {n}" for g, n in sorted(SAY.items())))
```

```
124 sozluk ogesi, 3216 ayri baglam cifti, 1984 parametre, 40 tur
81 bicim tek bir obek havuzuna ait: ariza 7, ek 7, erisilemedi 8, kacak 6, olagan 4, seyrek 49
```

#### Komşuluk Kime Düşüyor

Her biçim için en yakın komşu bulunur ve komşunun grubu biçimin grubuyla karşılaştırılır. Aynı
sınama üç temsile uygulanır: rastgele komşunun beklenen oranı, ham birlikte geçme vektörü ve
öğrenilen gömme.

```python
SAYIM_V = [[0.0] * len(SOZ) for _ in SOZ]
for (a, b), n in CIFT.items():
    SAYIM_V[a][b] = float(n)
SAYIM_B = [birim(v) for v in SAYIM_V]


def komsu(vek, i):
    en, ey = -2.0, i
    for j in range(len(SOZ)):
        if j != i:
            d = sum(vek[i][k] * vek[j][k] for k in range(len(vek[i])))
            if d > en:
                en, ey = d, j
    return SOZ[ey]


def oran(vek, bicim):
    return sum(BICIM_GRUP.get(komsu(vek, YER[b])) == BICIM_GRUP[b] for b in bicim) / len(bicim)


def satir(ad, bicim):
    bek = sum(SAY[BICIM_GRUP[b]] - 1 for b in bicim) / (len(bicim) * (len(SOZ) - 1))
    print(f"{ad:<24} {len(bicim):>5} {bek:>9.4f} {oran(SAYIM_B, bicim):>10.4f}"
          f" {oran(BIRIM, bicim):>10.4f}")


TUMU = list(BICIM_GRUP)
print(f"\n{'komsuluk sinamasi':<24} {'bicim':>5} {'rastgele':>9} {'ham sayim':>10}"
      f" {'ogrenilen':>10}")
satir("tumu", TUMU)
satir("yalniz sik bicimler", [b for b in TUMU if BICIM_GRUP[b] != "seyrek"])
satir("yalniz seyrek adlar", [b for b in TUMU if BICIM_GRUP[b] == "seyrek"])
```

```
komsuluk sinamasi        bicim  rastgele  ham sayim  ogrenilen
tumu                        81    0.2543     0.4938     0.6049
yalniz sik bicimler         32    0.0462     0.0625     0.2500
yalniz seyrek adlar         49    0.3902     0.7755     0.8367
```

Toplam satır beklenen sırayı veriyor: rastgele 0,2543, ham sayım 0,4938, öğrenilen gömme 0,6049.
Öğrenilen temsil, hiçbir şey öğrenmeyen sayıma 0,1111 katıyor. Alt satırlar okunmadan bu sayı
yanıltıcıdır: sınanan 81 biçimin 49'u seyrek addır ve hepsi **tek bir öbek kalıbında** geçer, yani
birbirinin bağlamıdır. Orada rastgele beklenti 0,3902, ham sayım 0,7755 verir.

Sık biçimlerde tablo tersine döner. Otuz iki sık biçimde rastgele beklenti 0,0462'dir, ham sayım
0,0625 ile bunun ancak 0,0163 üstündedir — hiçbir şey öğrenmeyen taban burada gerçekten hiçbir şey
bilmiyor. Öğrenilen gömme 0,2500 veriyor, yani rastgelenin beş katı ve ham sayımın dört katı.
Öğrenmenin kattığı yer burasıdır ve toplam satırda görünmez. Kursun ikinci iddiası tam olarak
budur: bir alan ölçütü tek bir sayıya indirildiğinde, sayının hangi alt gruptan geldiği kaybolur.

#### Vektör Aritmetiği Tutuyor Mu

İkinci sınama daha serttir. Aynı çekim ekini alan iki kök seçilir ve şu soru vektörlerle sorulur:
`sayac` biçiminden `sayacin` biçimine giden fark `muhur` biçimine eklenirse hangi biçim çıkar.
İkinci vektörden birincisi çıkarılır, üçüncü eklenir, sonuca en yakın biçim aranır ve doğru cevap
`muhurun`'dur.

```python
BENZESIM = []
for k in range(1, 5):
    ks = [AD[a].split() for a in AD if AD[a].split()[0] in SOZ and AD[a].split()[k] in SOZ]
    for a in ks:
        for b in ks:
            if a[0] != b[0]:
                BENZESIM.append((a[0], a[k], b[0], b[k]))


def coz(vek, a, b, c):
    v = [vek[YER[b]][i] - vek[YER[a]][i] + vek[YER[c]][i] for i in range(len(vek[0]))]
    en, ey = -2.0, 0
    for j in range(len(SOZ)):
        if SOZ[j] not in (a, b, c):
            d = sum(v[i] * vek[j][i] for i in range(len(v)))
            if d > en:
                en, ey = d, j
    return SOZ[ey]


print(f"\n{'oran benzesimi':<18} {'sinama':>6} {'tutan':>7} {'ayni kok':>9}"
      f"  en cok verilen cevap")
for ad, vek in (("ham sayim", SAYIM_B), ("ogrenilen gomme", BIRIM)):
    d = k = 0
    c = Counter()
    for a, b, y3, y in BENZESIM:
        t = coz(vek, a, b, y3)
        d, k = d + (t == y), k + (t != y and KOKU.get(t) == KOKU.get(y3))
        c[t] += 1
    n, (ec, en) = len(BENZESIM), c.most_common(1)[0]
    print(f"{ad:<18} {n:>6} {d / n:>7.4f} {k / n:>9.4f}  {ec} {en / n:.4f}")
```

```
oran benzesimi     sinama   tutan  ayni kok  en cok verilen cevap
ham sayim              72  0.1250    0.0000  kelepcede 0.1111
ogrenilen gomme        72  0.0972    0.0556  kelepcesi 0.0694
```

Yetmiş iki sınamanın ham sayımda 0,1250'si, öğrenilen gömmede 0,0972'si tutuyor. İkisi de
düşüktür ve bu sonuç saklanmaz: bu ölçekte oran benzeşimi **tutmuyor**. Bir ekin vektörlerde
ortak bir kaydırma bırakması için aynı ekin çok sayıda kök üstünde ve birbirinden ayrı
bağlamlarda görülmesi gerekir. Bu kurguda her kök ile ek çifti bir ya da iki kalıpta geçer;
vektör kökün bağlamını taşır, ekin bağlamını taşımaz. Yetmiş iki sınamanın 0,0556'sı aynı kökün
başka bir biçimine düşüyor, yani kök yakalanıyor, ek yakalanamıyor.

Beklenen kusur görünmüyor. En sık üç biçim `okuma`, `<sayi>` ve `olcum`'dur ve hiçbiri cevap
olmuyor; cevaplar bağlamı en dar biçimlerde toplanıyor — ham sayımda `kelepcede` 0,1111, gömmede
`kelepcesi` 0,0694 payla. Aynı temsil komşuluk sınamasında tabanı geçerken benzeşimde geçemiyor;
iki ölçüt aynı vektörleri iki ayrı sırayla okuyor.

#### Özet

- Sekiz boyutlu, 1.984 parametreli bir gömme 1.200 nottan çıkan 3.216 ayrı bağlam çiftiyle 40 tur
  eğitildi; vektörler etiketten değil bağlamdan öğrenildi.
- Komşuluk sınamasında rastgele beklenti 0,2543, ham birlikte geçme 0,4938, öğrenilen gömme
  0,6049 verdi; öğrenilen temsilin sayıma kattığı 0,1111'dir.
- Toplam sayı yanıltır: 81 biçimin 49'u tek bir kalıpta geçen seyrek addır ve orada ham sayım bile
  0,7755 verir. Otuz iki sık biçimde rastgele 0,0462, ham sayım 0,0625, öğrenilen gömme 0,2500'dür
  — öğrenmenin kattığı yer budur ve toplam satırda görünmez.
- Oran benzeşimi tutmuyor: 72 sınamanın ham sayımda 0,1250'si, gömmede 0,0972'si doğru. Ekin
  vektörde iz bırakması için aynı ekin çok sayıda ayrı bağlamda görülmesi gerekir.
- Yetmiş iki sınamanın 0,0556'sı aynı kökün başka bir biçimine düşüyor; cevaplar en sık sözcüğe
  değil, bağlamı en dar biçimlere toplanıyor (`kelepcesi` 0,0694).

#### Sonraki Adım

Üç derste bir not tek bir satıra indirgendi: önce belirteç listesi, sonra 96 sütunluk torba, sonra
sözcük başına bir vektör. Verilen karar her seferinde **belgenin tamamına** aitti — bu not şüpheli
mi. Oysa notun içinde hangi belirtecin neyi bildirdiği hiç sorulmadı: `sayacin kapagi kirik`
notunda hangi belirteç donanımı, hangisi konumu, hangisi durumu adlandırıyor. Sonraki ders etiketi
belgeden alıp **her belirtece ayrı ayrı** verir. O zaman doğruluğun neyi saydığı da değişir:
belirteç başına mı, yoksa birden çok belirteci kaplayan varlık başına mı.

### Dizi Etiketleme

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/dizi-etiketleme

Etiketin belgeden alınıp her belirtece ayrı ayrı verilmesi ve doğruluğun neyi saydığının ölçülmesi: alanın tabanı olan en sık etiketi her belirtece yazmak 0,5061 belirteç doğruluğu veriyor ama varlık düzeyinde F1 0,0000 — hiçbir varlık bulunmuyor. Son üç karaktere bakan yordam iki etiketleme düzeninde de aynı 0,9824 belirteç doğruluğunu verirken varlık düzeyinde 0,9267 ve 0,9600 veriyor; belirteci ezberleyen yordam 1,0000 belirteç doğruluğuyla tür düzeninde 0,9665'te kalıyor. Sözcük türünde aynı biçimdeki taban 0,5473 verir ve orada yanıltmaz.

Üç derste bir not tek bir satıra indirgendi ve verilen karar her seferinde belgenin bütününe
aitti. Notun içinde hangi belirtecin neyi adlandırdığı hiç sorulmadı. `sayacin kapagi kirik`
notunda ilk iki belirteç bir donanımı adlandırır ve üçüncüsü onun durumunu bildirir; oysa
`boruda kelepce eksik` notunda ilk iki belirteç **iki ayrı** donanımdır. Bu ders etiketi
belirteçlere dağıtır.

Etiket yer değiştirince ölçüt de değişir: belirteç düzeyinde doğruluk her belirteci ayrı sayar,
varlık düzeyinde bir varlık ancak başlangıcı, bitişi ve türü birlikte tuttuğunda sayılır. Alanın
tabanı burada **en sık etiketi her belirtece yazmaktır** ve belirteç düzeyinde şaşırtıcı biçimde
yüksek çıkar.

- **NL25.** Belirteçleme `nlp/03`'ün kararıdır: noktalama atma, küçük harfe inme, sayı katlama.
  Gövdeleme uygulanmaz, çünkü sınır kararının bir kısmı ekten okunur.
- **NL26.** Varlık türleri **kurgudur** ve kurgunun kendi sözlüğünden türetilir: donanım yedi kök,
  konum dokuz kök, ölçüm iki kök ile sayı belirteci. Öteki belirteçler varlık dışıdır.
- **NL27.** Sınır kuralı: yalın ya da ilgi durumundaki bir adın ardından iyelik durumunda bir ad
  gelirse ikisi **tek varlıktır**; sayı belirteci önceki ölçüm belirtecine bağlanır. Öbür
  durumlarda her belirteç kendi varlığıdır.
- **NL28.** Sözcük türü etiketi de sözlükten okunur: ad, nitelik, eylem, taşıyıcı, sayı.
- **NL29.** Alanın tabanı **en sık etiketi her belirtece yazmaktır**, iki görevde de.
- **NL30.** Model ezber çizelgesidir: eğitim payında her anahtar için en sık etiket. İki anahtar
  denenir — belirtecin kendisi ve son üç karakteri.
- **NL31.** İki etiketleme düzeni vardır: yalnız tür ve başlangıç ile iç ayrımı. Belirteç düzeyi
  doğruluk ikisinde de **tür üzerinden** sayılır, böylece iki düzen aynı ölçütle karşılaştırılır.
- **NL32.** Varlık düzeyi ölçüt tam eşleşmedir. Kesinlik, duyarlılık ve F1 tanımları M27/K03'te
  kuruldu ve tekrarlanmaz; buraya eklenen tek şey **neyin sayıldığıdır**.

#### Varlıklar ve İki Etiketleme Düzeni

Notlar `nlp/01`'in kurgusuyla aynı tohumdan üretilir.

```python
# ORTAK — KURGUDUR. Saha notlari ders icinde uretilir, tohum 20260218; kaynak
# sistemden gelmez. Sozluk 45 cekimli kok ve 40 seyrek addan olusur.
TOHUM, NOT_SAYISI, M32 = 20260218, 1800, 0xFFFFFFFF

AD = {  # 0 yalin, 1 ilgi, 2 bulunma, 3 iyelik, 4 cogul
    "sayac": "sayac sayacin sayacta sayaci sayaclar",
    "kapak": "kapak kapagin kapakta kapagi kapaklar",
    "muhur": "muhur muhurun muhurde muhuru muhurler",
    "vana": "vana vananin vanada vanasi vanalar",
    "kelepce": "kelepce kelepcenin kelepcede kelepcesi kelepceler",
    "boru": "boru borunun boruda borusu borular",
    "pano": "pano panonun panoda panosu panolar",
    "kapi": "kapi kapinin kapida kapisi kapilar",
    "zil": "zil zilin zilde zili ziller",
    "bahce": "bahce bahcenin bahcede bahcesi bahceler",
    "apartman": "apartman apartmanin apartmanda apartmani apartmanlar",
    "bodrum": "bodrum bodrumun bodrumda bodrumu bodrumlar",
    "giris": "giris girisin giriste girisi girisler",
    "adres": "adres adresin adreste adresi adresler",
    "okuma": "okuma okumanin okumada okumasi okumalar",
    "olcum": "olcum olcumun olcumde olcumu olcumler",
    "erisim": "erisim erisimin erisimde erisimi erisimler",
    "ziyaret": "ziyaret ziyaretin ziyarette ziyareti ziyaretler",
    "abone": "abone abonenin abonede abonesi aboneler",
    "arac": "arac aracin aracta araci araclar",
    "kir": "kir kirin kirde kiri kirler",
    "iz": "iz izin izde izi izler",
    "sokak": "sokak sokagin sokakta sokagi sokaklar",
    "ev": "ev evin evde evi evler",
}
NITELIK = "kirik gevsek kirli normal bozuk acik kapali eksik temiz yeni yok".split()
EYLEM = {  # 0 edilgen gecmis, 1 olumsuz
    "calis": "calisiyor calismiyor", "don": "donuyor donmuyor", "oku": "okundu okunmadi",
    "ac": "acildi acilmadi", "gir": "girildi girilemedi", "ulas": "ulasildi ulasilamadi",
    "tekrarla": "tekrarlandi tekrarlanmadi", "bul": "bulundu bulunmadi",
    "sagla": "saglandi saglanamadi", "degil": "degil degildi",
}
NADIR = """kablo kablosu kabloda|cam cami camda|tel teli telde|mandal mandali mandalda
merdiven merdiveni merdivende|tahta tahtasi tahtada|cukur cukuru cukurda|kar kari karda
buz buzu buzda|cop copu copta|duvar duvari duvarda|kutu kutusu kutuda|vida vidasi vidada
conta contasi contada|filtre filtresi filtrede|bant banti bantta|etiket etiketi etikette
kilit kiliti kilitte|asansor asansoru asansorde|zemin zemini zeminde|tavan tavani tavanda
kuyu kuyusu kuyuda|depo deposu depoda|ocak ocagi ocakta|direk diregi direkte
kanal kanali kanalda|numara numarasi numarada|cati catisi catida|baca bacasi bacada
kova kovasi kovada|levha levhasi levhada|somun somunu somunda|tapa tapasi tapada
izolasyon izolasyonu izolasyonda|supap supabi supapta|menfez menfezi menfezde
kayit kaydi kayitta|temel temeli temelde|kose kosesi kosede|koruma korumasi korumada"""
OBEK = {
    "olagan": ["{sayac.0} {calis.0}", "{okuma.0} normal", "{olcum.0} {tekrarla.0}",
               "{sayac.1} {erisim.3} {sagla.0}", "{kapak.0} temiz", "{vana.0} acik",
               "{sayac.2} {iz.0} {bul.1}", "{olcum.0} icin {erisim.0} {sagla.0}",
               "{sayac.1} {kapak.3} yeni", "{muhur.0} ile {kapak.0} temiz"],
    "ariza": ["{sayac.0} {don.1}", "{kapak.0} kirik", "{pano.0} bozuk",
              "{sayac.1} {kapak.3} kirik", "{olcum.0} {oku.1}", "{vana.0} bozuk",
              "{sayac.2} {kir.0} {bul.0}", "{sayac.4} {calis.1}",
              "{sayac.0} {calis.0} ama {okuma.0} yok",
              "{pano.1} {kapak.3} eksik"],
    "erisilemedi": ["{kapi.0} {ac.1}", "{zil.0} {calis.1}", "{abone.0} {ev.2} {degil.1}",
                    "{erisim.0} {sagla.1}", "{bodrum.0} {kapi.3} kapali",
                    "{apartman.1} {giris.3} kapali", "{adres.2} {ulas.1}",
                    "{bahce.1} {kapi.3} kapali", "{apartman.2} {zil.0} {calis.1}",
                    "{sayac.2} {erisim.0} yok"],
    "kacak": ["{muhur.0} kirik", "{kelepce.0} gevsek", "{muhur.2} {iz.0} {bul.0}",
              "{sayac.1} {muhur.3} kirik", "{kelepce.2} {iz.0} {bul.0}",
              "{muhur.0} eksik", "{vana.1} {kelepce.3} gevsek",
              "{muhur.1} {iz.3} {bul.0}", "{boru.2} {kelepce.0} eksik",
              "{kapak.2} bir {iz.0} {bul.0}"],
}
EK_OBEK = ["{ziyaret.0} {tekrarla.0}", "{sokak.2} {arac.0} {bul.0}", "{adres.0} yeni",
           "{bahce.1} {kapi.3} acik", "{apartman.2} {gir.0}", "{ev.1} {kapi.3} acik",
           "{kapak.0} kirli", "{olcum.0} {tekrarla.1}", "{arac.0} {sokak.2}",
           "bu {ziyaret.2} {olcum.0} {tekrarla.0}"]
TUR = [("olagan", 0.36, 0.04), ("ariza", 0.26, 0.28),
       ("erisilemedi", 0.16, 0.15), ("kacak", 0.22, 0.82)]
BICIM = {k: v.split() for d in (AD, EYLEM) for k, v in d.items()}
SEYREK = [s.split() for s in NADIR.replace("\n", "|").split("|")]
AGIRLIK = [1 / (i + 1) ** 1.6 for i in range(len(SEYREK))]
AGIRLIK = [w / sum(AGIRLIK) for w in AGIRLIK]
KOKU = {f: k for k, fs in BICIM.items() for f in fs}
KOKU.update({f: fs[0] for fs in SEYREK for f in fs})
KOKU.update({w: w for w in NITELIK})
TASIYICI = ["ve", "ile", "bir", "bu", "ama", "icin"]
KOKU.update({w: w for w in TASIYICI})


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 obek_yaz(sablon):
    p = []
    for s in sablon.split():
        if s.startswith("{"):
            kok, _, i = s[1:-1].partition(".")
            p.append(BICIM[kok][int(i)])
        else:
            p.append(s)
    return " ".join(p)


VERI = []
for i in range(NOT_SAYISI):
    r = uretec(TOHUM + i)
    t = TUR[ayrik(r(), [x[1] for x in TUR])]
    c = [obek_yaz(OBEK[t[0]][int(r() * 10)])]
    if r() < 0.55:
        c.append(obek_yaz(EK_OBEK[int(r() * 10)]))
    if r() < 0.30:
        c.append(obek_yaz(OBEK[t[0]][int(r() * 10)]))
    if r() < 0.22:
        f, nit = SEYREK[ayrik(r(), AGIRLIK)], NITELIK[int(r() * len(NITELIK))]
        c.append(f[2] + " kir bulundu" if r() < 0.34 else f[int(r() * 2)] + " " + nit)
    n = c[0]
    for x in c[1:]:
        n += (" ve " if r() < 0.22 else ", ") + x
    if r() < 0.52:
        n += ", okuma " + str(240 + int(r() * 1760))
    VERI.append({"no": 10001 + i, "not": n[0].upper() + n[1:] + ".",
                 "tur": t[0], "supheli": int(r() < t[2])})

EGT, AYR = VERI[:1200], VERI[1200:]
print(f"{len(VERI)} kurgu not, {len(BICIM) + len(SEYREK) + len(NITELIK)} kok, "
      f"supheli orani {sum(x['supheli'] for x in VERI) / len(VERI):.4f}")
print(VERI[3]["not"])
```

```
1800 kurgu not, 85 kok, supheli orani 0.2956
Olcum icin erisim saglandi, sayacin kapagi yeni, mandalda kir bulundu.
```

Varlıklar ve belirteç etiketleri kurgu sözlüğünden türetilir, iki düzende de aynı sınır kuralıyla.
Kestirim yordamı ikisinde de aynıdır: anahtar başına en sık etiket.

```python
from collections import Counter

TIP = {"donanim": "sayac kapak muhur vana kelepce boru pano",
       "konum": "kapi zil bahce apartman bodrum giris adres ev sokak",
       "olcum": "okuma olcum"}
KOK_TIP = {k: t for t, v in TIP.items() for k in v.split()}
DURUM = {f: i for v in AD.values() for i, f in enumerate(v.split())}
STUR = {f: "ad" for v in list(AD.values()) + [" ".join(s) for s in SEYREK] for f in v.split()}
STUR.update({f: "nitelik" for f in NITELIK})
STUR.update({f: "eylem" for v in EYLEM.values() for f in v.split()})
STUR.update({f: "tasiyici" for f in TASIYICI}, **{"<sayi>": "sayi"})

for x in VERI:
    x["bel"] = [("<sayi>" if b.isdigit() else b)
                for b in (s.strip(",.").lower() for s in x["not"].split()) if b]


def tipi(b):
    return "olcum" if b == "<sayi>" else KOK_TIP.get(KOKU.get(b))


def baglanir(a, b):  # ilgi ya da yalin + iyelik tek varliktir; sayi okumaya baglanir
    return b == "<sayi>" or (DURUM.get(a) in (0, 1) and DURUM.get(b) == 3)


def varliklar(bel):
    v, i = [], 0
    while i < len(bel):
        if tipi(bel[i]) is None:
            i += 1
            continue
        j = i + 1
        while j < len(bel) and tipi(bel[j]) and baglanir(bel[j - 1], bel[j]):
            j += 1
        v.append((i, j, tipi(bel[j - 1])))
        i = j
    return v


def etiketle(bel, ayrim):
    e = ["dis"] * len(bel)
    for i, j, t in varliklar(bel):
        for k in range(i, j):
            e[k] = (("B-" if k == i else "I-") + t) if ayrim else t
    return e


def coz(bel, tah, ayrim):
    v, i = [], 0
    while i < len(bel):
        t = tah[i]
        if t == "dis":
            i += 1
            continue
        tip = t[2:] if ayrim else t
        j = i + 1
        while j < len(bel) and tah[j] == ("I-" + tip if ayrim else tip):
            j += 1
        v.append((i, j, tip))
        i = j
    return v


def cizelge(ayrim, anahtar):
    s = {}
    for x in EGT:
        for b, e in zip(x["bel"], etiketle(x["bel"], ayrim)):
            s.setdefault(anahtar(b), Counter())[e] += 1
    g = Counter(e for x in EGT for e in etiketle(x["bel"], ayrim)).most_common(1)[0][0]
    return {b: c.most_common(1)[0][0] for b, c in s.items()}, g


def degerlendir(ad, ayrim, anahtar=lambda b: b, sabit=None):
    c, g = cizelge(ayrim, anahtar)
    d = t = dv = tv = gv = 0
    for x in AYR:
        bel = x["bel"]
        tah = [sabit] * len(bel) if sabit else [c.get(anahtar(b), g) for b in bel]
        tur = [e[2:] if ayrim and e != "dis" else e for e in tah]
        d += sum(a == b for a, b in zip(etiketle(bel, False), tur))
        t += len(bel)
        p, y = coz(bel, tah, ayrim), varliklar(bel)
        dv += sum(v in y for v in p)
        tv += len(p)
        gv += len(y)
    k, u = dv / tv if tv else 0.0, dv / gv
    f = 2 * k * u / (k + u) if k + u else 0.0
    print(f"{ad:<28} {d / t:>9.4f} {k:>9.4f} {u:>11.4f} {f:>7.4f}")


ES = Counter(e for x in EGT for e in etiketle(x["bel"], False)).most_common(1)[0][0]
print(f"{len(VERI)} notta {sum(len(varliklar(x['bel'])) for x in VERI)} varlik, "
      f"{sum(j - i > 1 for x in VERI for i, j, _ in varliklar(x['bel']))} tanesi cok belirtecli; "
      f"en sik belirtec etiketi '{ES}'")
print(f"\n{'adlandirilmis varlik':<28} {'belirtec':>9} {'kesinlik':>9} {'duyarlilik':>11}"
      f" {'F1':>7}")
EK = (lambda b: b[-3:])
degerlendir("en sik etiket", False, sabit=ES)
degerlendir("son uc karakter, tur", False, EK)
degerlendir("son uc karakter, ayrimli", True, EK)
degerlendir("belirtec kimligi, tur", False)
degerlendir("belirtec kimligi, ayrimli", True)
```

```
1800 notta 4378 varlik, 1583 tanesi cok belirtecli; en sik belirtec etiketi 'dis'

adlandirilmis varlik          belirtec  kesinlik  duyarlilik      F1
en sik etiket                   0.5061    0.0000      0.0000  0.0000
son uc karakter, tur            0.9824    0.9191      0.9343  0.9267
son uc karakter, ayrimli        0.9824    0.9421      0.9786  0.9600
belirtec kimligi, tur           1.0000    0.9774      0.9558  0.9665
belirtec kimligi, ayrimli       1.0000    1.0000      1.0000  1.0000
```

Kümede 4.378 varlık var ve 1.583'ü birden çok belirteç kaplıyor. En sık belirteç etiketi varlık
dışıdır ve her belirtece onu yazmak ayrılmış payda 0,5061 doğruluk veriyor: belirteçlerin yarıdan
fazlası doğru etiketleniyor. Aynı çıktının varlık düzeyi sayısı 0,0000'dır, çünkü tek bir varlık
bile bulunmuyor. Kursun kuralı bundan daha keskin bir örnek vermez — 0,5061 tek başına okunursa
yordamın yolun yarısını gittiği sanılır, oysa hiçbir şey bulmamıştır.

Ortadaki iki satır asıl ayrışmayı gösteriyor. Son üç karaktere bakan yordam iki düzende de **aynı**
belirteç doğruluğunu veriyor: 0,9824. Varlık düzeyinde ise 0,9267 ve 0,9600 veriyor. İki düzen aynı
belirteç kararlarını verir; ayrıldıkları tek yer sınırı nasıl okuduklarıdır ve belirteç düzeyi
ölçüt bu farkı **göremez**. Aynı çıktının iki sayısı vardır ve hangisinin yazılacağı ölçütün
tanımına bağlıdır.

Belirteç hatasının varlık hatasına dönüşme oranı da tabloda okunuyor: belirteç düzeyinde 0,0176
hata, tür düzeninde 0,0733 F1 kaybı veriyor. Bir varlık ancak bütün belirteçleri doğruysa sayılır,
yani hata varlık boyunca çarpılır. Son satır çifti bunu uçtan gösteriyor: ezber 1,0000 belirteç
doğruluğu verirken tür düzeninde 0,9665'te kalıyor. Kusursuz belirteç kararıyla bile kayıp vardır,
çünkü tür düzeni bitişik iki aynı türlü varlığı tek varlık sayar — `boruda kelepce eksik` notunda
iki ayrı donanım tek aralığa iniyor. Başlangıç ile iç ayrımı bunu etikete taşır ve 1,0000 verir.

#### Aynı Taban, Başka Bir Görev

İkinci görev sözcük türüdür ve varlık düzeyi yoktur: etiket belirteçle birebirdir.

```python
SAY_TUR = Counter(STUR[b] for x in AYR for b in x["bel"])
EST = Counter(STUR[b] for x in EGT for b in x["bel"]).most_common(1)[0][0]


def tur_olc(ad, anahtar=None):
    c = {}
    if anahtar:
        s = {}
        for x in EGT:
            for b in x["bel"]:
                s.setdefault(anahtar(b), Counter())[STUR[b]] += 1
        c = {k: v.most_common(1)[0][0] for k, v in s.items()}
    d = t = 0
    for x in AYR:
        for b in x["bel"]:
            d += (c.get(anahtar(b), EST) if anahtar else EST) == STUR[b]
            t += 1
    print(f"{ad:<28} {d / t:>9.4f}")


print("ayrilmis payda belirtec turu: " + ", ".join(f"{k} {v}" for k, v in SAY_TUR.most_common()))
print(f"\n{'sozcuk turu':<28} {'belirtec':>9}")
tur_olc(f"en sik etiket ({EST})")
tur_olc("son uc karakter", EK)
tur_olc("belirtec kimligi", lambda b: b)
```

```
ayrilmis payda belirtec turu: ad 2181, nitelik 622, eylem 603, sayi 312, tasiyici 267

sozcuk turu                   belirtec
en sik etiket (ad)              0.5473
son uc karakter                 0.9905
belirtec kimligi                1.0000
```

En sık etiketi her belirtece yazmak burada 0,5473 veriyor, yani adlandırılmış varlıktakinden de
yüksek. Ayrılmış payın 3.985 belirtecinin 2.181'i addır ve tek başına bu oran tabanı belirliyor.
Son üç karakter 0,9905, belirteç kimliği 1,0000 veriyor. Sayılar yüksektir çünkü görev bu kurguda
kolaydır: bir yüzey biçiminin türü değişmez.

Asıl okuma iki görevin karşılaştırılmasındadır. Aynı biçimdeki taban iki görevde iki ayrı anlam
taşıyor: sözcük türünde 0,5473 görevin zorluğunu dürüstçe bildiriyor, adlandırılmış varlıkta 0,5061
hiçbir şey bulmayan bir yordamı yarı yolda gösteriyor. Fark yordamda değil ölçüttedir — birinde
etiketlenen birim ile sayılan birim aynı, ötekinde değil.

#### Özet

- Etiket belgeden alınıp belirteçlere dağıtıldı; 1.800 notta 4.378 varlık var ve 1.583'ü birden çok
  belirteç kaplıyor.
- Alanın tabanı en sık etiketi her belirtece yazmaktır: belirteç düzeyinde 0,5061, varlık düzeyinde
  F1 0,0000. Belirteç düzeyi sayı tek başına okunursa yordamın yarı yolu gittiği sanılır.
- Son üç karaktere bakan yordam iki etiketleme düzeninde de aynı belirteç doğruluğunu (0,9824)
  verirken varlık düzeyinde 0,9267 ve 0,9600 veriyor; fark yalnız sınırın okunmasındadır ve
  belirteç düzeyi ölçüt onu göremez.
- Belirteç düzeyinde 0,0176 hata tür düzeninde 0,0733 F1 kaybı verir; ezber 1,0000 belirteç
  doğruluğuyla tür düzeninde 0,9665'te kalır, çünkü bitişik iki aynı türlü varlık tek aralığa iner.
- Sözcük türünde aynı biçimdeki taban 0,5473 verir ve yanıltmaz: orada etiketlenen birim ile
  sayılan birim aynıdır.

#### Sonraki Adım

Dört derste metin sayıya çevrildi: belirteçlere bölündü, sütunlara açıldı, vektörlere gömüldü ve
son derste etiket belirteçlere dağıtıldı. Belgenin bütününe verilen karar bu dizide yalnız bir kez,
tek bir ikili soruyla soruldu ve orada ölçülen şey kararın kendisi değil **temsildi**: hangi
temsilin ne kattığı. Notun bildirdiği olay türü ise dört sınıflıdır ve o karar hiç verilmedi. Boru
hattının kendisi de hiç sökülmedi — belirteçleme, ağırlıklandırma ve sınıflandırıcı bir arada
ölçüldü, her adımın kaç puan kattığı ayrı ayrı sorulmadı. Sonraki ders belgeyi bir bütün olarak
sınıflandırır ve boru hattının her adımının payını tek tek sayar.

### Metin Sınıflandırma

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/metin-siniflandirma

Bir saha notunun bütününe tek bir olay türü kararı verilmesi ve boru hattının üç adımının her birinin kaç puan kattığının ayrı ayrı sayılması: en sık sınıf tabanı 0,4420, elle sayılmış yedi ölçü 0,5500, sözcük torbası ve doğrusal model 0,9620. On iki kurulum üzerinde ölçüldüğünde temsil adımı ortalama 0,3787, sınıflandırıcı adımı 0,0500, terim ağırlıklandırma 0,0140 katıyor; belirteçleme kararlarının ikisi de eksi katkı veriyor ve ek kırpma sözlüğü 109'dan 89'a indirirken ortalama 0,0165 kaybettiriyor. Bir adımın katkısı tek bir sayı değildir: ağırlıklandırma sınıf ortalamasıyla 0,0340'a çıkarken doğrusal modelle 0,0060 eksiye iniyor.

Dört derste metin sayıya çevrildi. Belirteçleme kararının sözlük boyunu nasıl oynattığı, sözcük
torbasının ve terim ağırlıklandırmanın elle sayılmış özniteliklere ne kattığı, gömmenin bağlamdan
nasıl öğrenildiği ve etiketlerin **belirteçlere** nasıl dağıtıldığı ölçüldü. Bütün bu ölçümlerde
karar biriminin altı belirteçti: her belirteç kendi etiketini aldı, ölçüt belirteç ya da varlık
düzeyinde okundu.

Belgenin **bütününe** tek bir karar vermek hiç denenmedi. Bir saha notu okunur ve dört olay
türünden biri yazılır: sayaç arızası, kaçak şüphesi, erişilemedi, olağan. Bu kurulumda çıktı tek
bir etikettir ve girdinin uzunluğu değişkendir. Bu dersin sorusu şudur: bu kararı üreten boru
hattının **hangi adımı kaç puan katıyor**. Adımlar üçtür — belirteçleme, terim ağırlıklandırma,
sınıflandırıcı — ve her birinin katkısı ötekilerinden bağımsız değildir.

- **NL41.** Saha notları **kurgudur**. M27/K02 `oznitelik-secimi/02`'nin ürettiği not alanının
  genişletilmiş hâlidir: her not bir olay öbeğinden, kimi zaman başka bir türden ödünç alınmış bir
  yan kayıttan, bir gürültü ifadesinden ve bir hat işaretinden kurulur. Tohum 20260218.
- **NL42.** Olay türü etiketi notun **üretildiği türdür**, notun içindeki sözcüklerden türetilmez.
  Ödünç alınan yan kayıt yüzünden metin kimi zaman başka bir türü işaret eder; bu ölçünün tavanını
  aşağı çeker ve kurgunun kasıtlı bir parçasıdır.
- **NL43.** Küme 1.600 nottur; ilk 1.100'ü eğitim, son 500'ü ayrılmış kümedir.
- **NL44.** **Alanın tabanı en sık sınıftır.** Dört sınıflı bir görevde rastgele atama 0,25
  dolayında kalır; en sık sınıf bundan yüksektir ve sınıflar dengesiz olduğu için
  asıl karşılaştırma odur.
- **NL45.** Boru hattının **her adımı yalnız eğitim kümesinden öğrenilir**: sözlük,
  belge sıklıkları ve model ağırlıkları. Bu kural M27/K02 `oznitelik-secimi/05`'te kuruldu
  ve burada sürer.
- **NL46.** Sözlüğe eğitim kümesinde **en az iki notta** geçen sözcükler alınır.
- **NL47.** İki sınıflandırıcı da ders içinde yazılır ve **modeldir**: sınıf ortalaması
  (her sınıfın ortalama vektörüne açı benzerliği) ve dört sınıflı doğrusal model.

#### Belgenin Bütününe Tek Karar

Sınıflandırmanın girdisi bir belgedir, çıktısı bir etikettir. Dizi etiketlemeden farkı bir ölçek
farkı değil, bir karar birimi farkıdır: orada her belirteç için bir çıktı vardı, burada bütün not
için bir çıktı vardır ve notun kaç belirteçten oluştuğu çıktının biçimini değiştirmez.

```python
# KURGU saha notlari — M27/K02'nin not alaninin genisletilmis hali. Tohum 20260218.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
TUR = ("olagan", "erisilemedi", "sayac arizasi", "kacak suphesi")
PAY = (0.46, 0.22, 0.19, 0.13)
OBEK = {t: s.split("|") for t, s in zip(TUR, (
    "okuma normal|okuma normaldi|sayac erisimi saglandi|sayaca erisildi|olcum tekrarlandi|"
    "olcumu yineledik|vana kontrol edildi|vanada sorun yok|kapak temiz|kapakta iz yok|"
    "gosterge okunakli|gostergede rakam net",
    "abone evde degildi|abone bulunamadi|erisim saglanamadi|erisim yok|kapi zili calismiyor|"
    "zil calismadi|bahce kapisi kilitli|bahce kapisi kapali|bodrum katina inilemedi|"
    "bodrum kilitli|adres bulunamadi|adres eksik",
    "gosterge donmuyor|gostergede hareket yok|sayac cami kirik|sayacin cami catlak|"
    "rakam okunmuyor|rakamlar silik|ibre sabit kalmis|ibre kilitli|mekanizma takilmis|"
    "mekanizmada takilma|sayac durmus|sayac calismiyor",
    "muhur izi var|muhurde iz goruldu|muhur kopmus|muhurler kopuk|baglanti degistirilmis|"
    "baglantida degisiklik|kelepce gevsek|kelepcede gevseme|boru ek yeri yeni|boruda yeni ek|"
    "sayac ters takilmis|sayaci ters takmislar"))}
GURULTU = ("arac park halinde|kapak kirli|hava yagisli|adres teyit edildi|not kisa tutuldu|"
           "ikinci ziyaret|bahce icinde|kaldirim uzerinde").split("|")
BOLGE = "kuzey hatti|guney hatti|dogu hatti|bati hatti|merkez hatti".split("|")
SUP_P = {"kacak suphesi": 0.86, "sayac arizasi": 0.21, "erisilemedi": 0.07, "olagan": 0.03}


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 not_kur(no):
    r = uretec(TOHUM + 41000 + no)
    u, k = r(), 0.0
    for i, p in enumerate(PAY):
        k += p
        if u < k:
            t = TUR[i]
            break
    p = [OBEK[t][int(r() * 12)]]
    if r() < 0.55:
        p.append(OBEK[t][int(r() * 12)])
    if r() < 0.34:                          # baska turden odunc alinan yan kayit
        p.append(OBEK[TUR[int(r() * 4)]][int(r() * 12)])
    if r() < 0.62:
        p.append(GURULTU[int(r() * 8)])
    if r() < 0.30:
        p.append(BOLGE[int(r() * 5)])
    return {"metin": ", ".join(p), "tur": t, "supheli": 1 if r() < SUP_P[t] else 0}


NOT = [not_kur(i) for i in range(1600)]
EGT, SIN = NOT[:1100], NOT[1100:]
TUR_I = {t: i for i, t in enumerate(TUR)}
say = {}
for x in EGT:
    say[x["tur"]] = say.get(x["tur"], 0) + 1
EN_SIK = max(say, key=say.get)
TABAN = sum(x["tur"] == EN_SIK for x in SIN) / len(SIN)
for i in (3, 25, 40):
    print(f"not: {NOT[i]['metin']}  ->  {NOT[i]['tur']}")
print(f"egitim {len(EGT)}, ayrilmis {len(SIN)}, ortalama belirtec "
      f"{sum(len(x['metin'].split()) for x in NOT) / len(NOT):.2f}")
print("ayrilmis kumede " + ", ".join(
    f"{t} {sum(x['tur'] == t for x in SIN) / len(SIN):.4f}" for t in TUR))
print(f"en sik sinif '{EN_SIK}', alanin tabani {TABAN:.4f}")
```

```
not: baglanti degistirilmis, kelepce gevsek, dogu hatti  ->  kacak suphesi
not: bodrum katina inilemedi, abone evde degildi, sayac cami kirik, bahce icinde  ->  erisilemedi
not: vanada sorun yok, gostergede rakam net, sayac durmus, kuzey hatti  ->  olagan
egitim 1100, ayrilmis 500, ortalama belirtec 6.68
ayrilmis kumede olagan 0.4420, erisilemedi 0.2340, sayac arizasi 0.1920, kacak suphesi 0.1320
en sik sinif 'olagan', alanin tabani 0.4420
```

İkinci ve üçüncü örnek notlar kurgunun neyi zorlaştırdığını gösteriyor. İkincisi "erisilemedi"
türünden üretilmiş ama içinde bir arıza kaydı taşıyor; üçüncüsü "olagan" türünden üretilmiş ama
"sayac durmus" ifadesi arıza öbeğinden geliyor. Metin etiketi tam belirlemez, yalnız işaret eder.

Alanın tabanı 0,4420. Bu sayı hiçbir sözcüğe bakmadan her nota "olağan" yazan bir yordamın
ayrılmış kümedeki oranıdır ve bundan sonraki her sayı ona karşı okunur.

#### Üç Adım, On İki Kurulum

Boru hattı üç kararın çarpımıdır. Belirteçleme üç seçenektir: **kaba** (yalnız boşluktan bölme,
noktalama sözcüğe yapışık kalır), **özenli** (virgül kırpılır, küçük harfe indirgenir), **kırpık**
(özenlinin üstüne her sözcük ilk beş karaktere indirgenir — eklemeli bir dilde gövdelemenin en kaba
yaklaşımı). Ağırlıklandırma iki seçenektir: ham **sıklık**, ya da sıklığın **ters belge
sıklığıyla** çarpımı. Sınıflandırıcı iki seçenektir. Üç kararın on iki bileşimi vardır
ve on ikisi de aynı ayrılmış kümede ölçülür.

```python
# Boru hattinin uc adimi. Her adim YALNIZ egitim kumesinden ogrenilir.
BOL = {"kaba": lambda m: m.split(),
       "ozenli": lambda m: [w.strip(",").lower() for w in m.split() if w.strip(",")],
       "kirpik": lambda m: [w.strip(",").lower()[:5] for w in m.split() if w.strip(",")]}


def sozluk_kur(D, bol):
    d = {}
    for x in D:
        for w in set(bol(x["metin"])):
            d[w] = d.get(w, 0) + 1
    kelime = sorted(w for w, c in d.items() if c >= 2)
    return ({w: i for i, w in enumerate(kelime)},
            {i: math.log(len(D) / d[w]) for i, w in enumerate(kelime)})


def vektor(m, bol, S, TBS=None):
    v = {}
    for w in bol(m):
        if w in S:
            v[S[w]] = v.get(S[w], 0.0) + 1.0
    if TBS:
        for i in v:
            v[i] *= TBS[i]
    n = math.sqrt(sum(u * u for u in v.values())) or 1.0
    return {i: u / n for i, u in v.items()}


def sinif_ortalamasi(D, V):                 # MODELDIR: her sinifin ortalama vektoru
    C = [{} for _ in TUR]
    for x, v in zip(D, V):
        c = C[TUR_I[x["tur"]]]
        for i, u in v.items():
            c[i] = c.get(i, 0.0) + u
    for c in C:
        n = math.sqrt(sum(u * u for u in c.values())) or 1.0
        for i in c:
            c[i] /= n
    return lambda v: max(range(4), key=lambda j: sum(u * C[j].get(i, 0.0)
                                                     for i, u in v.items()))


def dogrusal_model(D, V, boy, tur=150, adim=3.0):   # MODELDIR: dort sinifli dogrusal
    W, b = [[0.0] * boy for _ in TUR], [0.0] * 4
    y, n = [TUR_I[x["tur"]] for x in D], len(D)
    for _ in range(tur):
        gW, gb = [{} for _ in TUR], [0.0] * 4
        for v, t in zip(V, y):
            o = [sum(W[j][i] * u for i, u in v.items()) + b[j] for j in range(4)]
            e = [math.exp(z - max(o)) for z in o]
            s = sum(e)
            for j in range(4):
                d = e[j] / s - (1.0 if j == t else 0.0)
                gb[j] += d
                for i, u in v.items():
                    gW[j][i] = gW[j].get(i, 0.0) + d * u
        for j in range(4):
            b[j] -= adim * gb[j] / n
            for i, g in gW[j].items():
                W[j][i] -= adim * g / n
    return lambda v: max(range(4), key=lambda j: sum(W[j][i] * u
                                                     for i, u in v.items()) + b[j])


def olc(kes, D, V):
    return sum(kes(v) == TUR_I[x["tur"]] for x, v in zip(D, V)) / len(D)


ANAHTAR = ("muhur", "erisim", "sayac", "gosterge", "kelepce")


def elle(m):                                # M27/K02'nin elle sayilmis metin olculeri
    w = BOL["ozenli"](m)
    v = {0: len(m) / 60.0, 1: len(w) / 10.0}
    for j, a in enumerate(ANAHTAR):
        v[2 + j] = 1.0 if any(a in u for u in w) else 0.0
    n = math.sqrt(sum(u * u for u in v.values())) or 1.0
    return {i: u / n for i, u in v.items()}


VE, VS = [elle(x["metin"]) for x in EGT], [elle(x["metin"]) for x in SIN]
ELLE = olc(dogrusal_model(EGT, VE, 7), SIN, VS)
IZGARA = {}
print(f"{'belirtecleme':<13}{'sozluk':>7}{'agirlik':>11}{'sinif ort.':>12}{'dogrusal':>10}")
for ad, bol in BOL.items():
    S, TBS = sozluk_kur(EGT, bol)
    for ag, t in (("sayim", None), ("agirlikli", TBS)):
        VE = [vektor(x["metin"], bol, S, t) for x in EGT]
        VS = [vektor(x["metin"], bol, S, t) for x in SIN]
        a = olc(sinif_ortalamasi(EGT, VE), SIN, VS)
        d = olc(dogrusal_model(EGT, VE, len(S)), SIN, VS)
        IZGARA[(ad, ag)] = (a, d)
        print(f"{ad if ag == 'sayim' else '':<13}{len(S) if ag == 'sayim' else '':>7}"
              f"{ag:>11}{a:>12.4f}{d:>10.4f}")
print(f"taban {TABAN:.4f}; elle sayilmis yedi olcu + dogrusal model {ELLE:.4f}")
```

```
belirtecleme  sozluk    agirlik  sinif ort.  dogrusal
kaba             156      sayim      0.9040    0.9500
                      agirlikli      0.9300    0.9580
ozenli           109      sayim      0.8940    0.9620
                      agirlikli      0.9200    0.9580
kirpik            89      sayim      0.8700    0.9500
                      agirlikli      0.9040    0.9440
taban 0.4420; elle sayilmis yedi olcu + dogrusal model 0.5500
```

Son satır bu kursun taban okumasının ikinci basamağıdır. M27/K02 `oznitelik-secimi/02` bir saha
notundan elle beş sayı çıkarmış ve bunların ayrılmış kümeye 0,0317 kattığını ölçmüştü; orada görev
ikili şüphe kestirimiydi. Aynı yaklaşım burada dört sınıflı olay türü görevine uygulandığında
0,5500 veriyor — tabanın 0,1080 üstünde. Sözcük torbasının aynı ayrılmış kümede verdiği en düşük
sayı 0,8700, en yükseği 0,9620.

#### Bir Adımın Katkısı Tek Sayı Değildir

On iki kurulum, "hangi adım kaç puan katıyor" sorusunu tek bir çıkarma işlemiyle cevaplamayı
imkânsız kılar. Her adımın katkısı, ötekilerin hangi değerde durduğuna bağlıdır ve bu bağımlılık
sayılabilir: bir adım değiştirilirken geri kalan bütün kurulumlar sabit tutulur ve fark her birinde
ayrı ayrı okunur.

```python
# Bir adimin katkisi tek sayi degildir: oteki adimlarin her kurulumunda ayri olculur.
ADIM = [("belirtecleme kaba -> ozenli",
         [IZGARA[("ozenli", g)][k] - IZGARA[("kaba", g)][k]
          for g in ("sayim", "agirlikli") for k in (0, 1)]),
        ("belirtecleme ozenli -> kirpik",
         [IZGARA[("kirpik", g)][k] - IZGARA[("ozenli", g)][k]
          for g in ("sayim", "agirlikli") for k in (0, 1)]),
        ("agirliklandirma sayim -> agirlikli",
         [IZGARA[(b, "agirlikli")][k] - IZGARA[(b, "sayim")][k]
          for b in BOL for k in (0, 1)]),
        ("siniflandirici ortalama -> dogrusal",
         [IZGARA[(b, g)][1] - IZGARA[(b, g)][0]
          for b in BOL for g in ("sayim", "agirlikli")]),
        ("temsil elle sayim -> sozcuk torbasi",
         [IZGARA[(b, g)][k] - ELLE for b in BOL
          for g in ("sayim", "agirlikli") for k in (0, 1)])]
print(f"{'adim':<38}{'olcum':>6}{'en dusuk':>10}{'en yuksek':>11}{'ortalama':>10}")
for ad, f in ADIM:
    print(f"{ad:<38}{len(f):>6}{min(f):>+10.4f}{max(f):>+11.4f}"
          f"{sum(f) / len(f):>+10.4f}")

S, _ = sozluk_kur(EGT, BOL["ozenli"])
disi = [sum(w not in S for w in BOL["ozenli"](x["metin"])) for x in SIN]
toplam = sum(len(BOL["ozenli"](x["metin"])) for x in SIN)
print(f"sozluk yalniz egitimden kuruldu: {len(S)} sozcuk; ayrilmis kumede "
      f"sozluk disi belirtec {sum(disi)}/{toplam}")
en_iyi = max(IZGARA.items(), key=lambda kv: kv[1][1])
print(f"en yuksek kurulum {en_iyi[0][0]} + {en_iyi[0][1]} + dogrusal "
      f"{en_iyi[1][1]:.4f}; tabanin {en_iyi[1][1] - TABAN:+.4f} uzerinde")
```

```
adim                                   olcum  en dusuk  en yuksek  ortalama
belirtecleme kaba -> ozenli                4   -0.0100    +0.0120   -0.0020
belirtecleme ozenli -> kirpik              4   -0.0240    -0.0120   -0.0165
agirliklandirma sayim -> agirlikli         6   -0.0060    +0.0340   +0.0140
siniflandirici ortalama -> dogrusal        6   +0.0280    +0.0800   +0.0500
temsil elle sayim -> sozcuk torbasi       12   +0.3200    +0.4120   +0.3787
sozluk yalniz egitimden kuruldu: 109 sozcuk; ayrilmis kumede sozluk disi belirtec 0/3305
en yuksek kurulum ozenli + sayim + dogrusal 0.9620; tabanin +0.5200 uzerinde
```

Tablonun en büyük satırı en alttadır ve bu dersin asıl cevabıdır: farkın neredeyse tamamı
**temsilden** gelir. Elle sayılmış yedi ölçüyü sözcük torbasıyla değiştirmek on iki kurulumun
hepsinde en az 0,3200 katıyor. Sınıflandırıcıyı değiştirmek ortalama 0,0500, ağırlıklandırma 0,0140
katıyor. Yedi sayı ile yüz dokuz sayı arasındaki fark, sınıf ortalaması ile doğrusal model
arasındaki farkın yedi buçuk katıdır.

Ağırlıklandırma satırı işaret değiştiriyor ve bu dersin ikinci bulgusudur. Sınıf ortalamasıyla
çalışıldığında ters belge sıklığı üç belirteçlemede de artı katkı veriyor, en yükseği 0,0340;
doğrusal modelle çalışıldığında iki kurulumda eksiye iniyor. Nedeni yordamların yapısındadır:
sınıf ortalaması bütün sözcüklere eşit güvenir, bu yüzden yüksek sıklıklı taşıyıcı sözcüklerin
bastırılması ona yarar. Doğrusal model o bastırmayı ağırlıklarıyla zaten öğrenmektedir ve dışarıdan
gelen ikinci bir bastırma bilgi eklemez. "Terim ağırlıklandırma kaç puan katar" sorusunun tek bir
cevabı yoktur; sınıflandırıcı yazılmadan sorulmuş bir sorudur.

Belirteçleme satırlarının ikisi de eksidedir. Kaba bölmeden özenliye geçiş sözlüğü 156'dan 109'a
indiriyor ve ortalamada 0,0020 kaybettiriyor; ek kırpma sözlüğü 89'a indirirken 0,0165
kaybettiriyor. Kırpma "sayac", "sayaci", "sayacin" biçimlerini tek bir belirteçte topluyor — ama
"kapak temiz" ile "kapakta iz yok" ayrımını da siliyor, çünkü ikisinin ayırt edici sözcükleri beş
karakterde kesişiyor. Sözlüğü küçültmek bir maliyet ölçüsüdür, başarım ölçüsü değildir; ikisinin
aynı yöne gitmesi gerekmez.

Son iki satır boru hattı kuralının bu kümedeki bedelini gösterir. Sözlük yalnız eğitim kümesinden
kurulduğu için ayrılmış kümedeki bazı sözcüklerin dışarıda kalması beklenirdi; burada sözlük dışı
belirteç sayısı 3.305'te sıfırdır, çünkü kurgunun sözlüğü kapalıdır ve 1.100 not bütün ifadeleri
görmeye yeter. Kuralın burada bedeli yoktur, ama kural yine de uygulanmıştır: bedelin sıfır olduğu
ancak ölçüldükten sonra bilinir.

#### Özet

- Belge düzeyinde sınıflandırmada karar birimi belgedir; girdinin belirteç sayısı değişkendir,
  çıktı tek bir etikettir.
- Alanın tabanı en sık sınıftır ve 0,4420 verir; elle sayılmış yedi metin ölçüsü 0,5500, sözcük
  torbası ile doğrusal model 0,9620 veriyor.
- Farkın neredeyse tamamı temsilden gelir: elle sayımdan sözcük torbasına geçiş on iki kurulumun
  hepsinde en az 0,3200 katıyor, sınıflandırıcı adımı ortalama 0,0500 katıyor.
- Bir adımın katkısı tek sayı değildir: terim ağırlıklandırma sınıf ortalamasıyla 0,0340'a çıkar,
  doğrusal modelle 0,0060 eksiye iner.
- Sözlüğü küçültmek başarımı artırmaz: ek kırpma sözlüğü 109'dan 89'a indirirken ortalama 0,0165
  kaybettirir.

#### Sonraki Adım

Bu derste sözcük torbası tabanı 0,5200 geçti, ama bunun için 1.100 etiketli not harcandı. Her not
bir saha ziyaretinin karşılığıdır ve elde yüz tane olabilir. Etiketsiz not ise boldur: ölçüm ağı
her dönem binlerce not üretir ve hiçbirine olay türü yazılmamıştır. Bu notlardan bir
**vekil görev** kurulabilir — bir sözcük gizlenip komşularından kestirilir — ve orada
öğrenilen temsil etiketli göreve taşınabilir. Sonraki ders bu döngüyü ölçer: maskeli
kestirimle önceden eğitilen bir gömme, etiketli örnek sayısı azaldıkça sıfırdan eğitilen
kurulumu ne kadar geçiyor ve fark hangi örnek sayısında kapanıyor.

### Önceden Eğitim ve İnce Ayar

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/donusturucu-tabanli-dil-modelleri

Maskeli kestirimle etiketsiz notlardan öğrenilen bir gömme tablosunun etiketli göreve taşınması ve kattığı farkın etiket sayısıyla birlikte okunması: vekil görev kendi ölçüsünde 0,0419 tabanını 0,3450'ye çıkarıyor ve bunun için sıfır etiket harcanıyor. Alanın tabanı 0,4420 iken yirmi etiketle sıfırdan eğitim 0,5850, önceden eğitim ve ince ayar 0,7480 veriyor; sıfırdan eğitim bu sayıya ancak kırk etiketle ulaşıyor. Fark yüz altmış etikette 0,0090 eksiye döner. Öğrenmeyen denetim kurulumu — rastgele tablonun dondurulması — beş ölçümde de 0,51'in altında kalıyor ve iki koşumu 0,1320 ayrılıyor; önceden eğitilmiş tablonun iki koşumu 0,0020 ayrılıyor.

Önceki derste sözcük torbası alanın tabanını 0,5200 geçti, ama bunun için 1.100 etiketli not
harcandı. Her etiket bir denetçinin sahada geçirdiği zamanın karşılığıdır ve elde yirmi tane
olabilir. Etiketsiz not ise boldur: ölçüm ağı her dönem binlerce not üretir ve hiçbirine olay türü
yazılmamıştır.

Bu derste sorulan şey şudur: bu etiketsiz yığından bir **vekil görev** kurulabilir mi ve orada
öğrenilen temsil etiketli göreve taşındığında **kaç etiketle** ne kadar fark katar. Vekil görev
maskeli kestirimdir: bir notun bir sözcüğü gizlenir ve kalan sözcüklerden kestirilir. Doğru cevap
metnin kendisindedir, dışarıdan hiçbir etiket gerekmez. Dikkat katmanı, çok başlı dikkat ve
konum kodlaması M27/K05 `mimariler/06`–`07`'de kuruldu ve ölçüldü; burada ölçülen şey mimari
değildir. Ölçülen şey **döngüdür**: önceden eğitim, sonra ince ayar.

- **NL48.** Metin kurgusu önceki dersinkiyle aynıdır ve **kurgudur**; tohum 20260218.
- **NL49.** Küme üçe ayrılır: ilk 700 not **etiketsiz havuzdur** (yalnız metni kullanılır, olay
  türü hiç okunmaz), sonraki 400 not **etiketli havuzdur**, son 500 not **ayrılmış kümedir**.
  Ayrılmış küme önceki dersinkiyle aynı 500 nottur.
- **NL50.** Sözlük **yalnız etiketsiz havuzdan** kurulur; en az iki notta geçen sözcükler alınır.
- **NL51.** **Model ders içinde yazılır**: sözcük başına altı sayılık bir gömme tablosu, notun
  gömmelerinin ortalaması ve dört sınıflı bir doğrusal gövde. Tablo 654, gövde 28 parametredir.
- **NL52.** **Vekil görevin tabanı en sık sözcüktür**: her maskeli konuma sözlüğün en sık
  sözcüğünü yazan yordam.
- **NL53.** Dört kurulum karşılaştırılır: sıfırdan (tablo rastgele ilklendirilir ve öğrenilir),
  **rastgele tablo donduruk** (öğrenilmez — denetim kurulumu), önceden eğitim donduruk, önceden
  eğitim ince ayarlı.
- **NL54.** Etiketli örnek sayısı beş değerde ölçülür: 10, 20, 40, 80, 160. Ayrılmış küme beşinde
  de aynıdır.
- **NL55.** Her sayı **iki koşumla** basılır; koşumlar gövdenin ilklendirme tohumunda ayrılır.

#### Etiketsiz Yığın ve Üç Ayrım

Önceden eğitimin gerektirdiği tek şey metnin kendisidir. Bu yüzden ayrım burada üçlüdür: etiketin
hiç okunmadığı bir havuz, etiketin sayılarak harcandığı bir havuz ve hiçbirinin dokunmadığı bir
ayrılmış küme.

```python
# KURGU saha notlari — M27/K02'nin not alaninin genisletilmis hali. Tohum 20260218.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
TUR = ("olagan", "erisilemedi", "sayac arizasi", "kacak suphesi")
PAY = (0.46, 0.22, 0.19, 0.13)
OBEK = {t: s.split("|") for t, s in zip(TUR, (
    "okuma normal|okuma normaldi|sayac erisimi saglandi|sayaca erisildi|olcum tekrarlandi|"
    "olcumu yineledik|vana kontrol edildi|vanada sorun yok|kapak temiz|kapakta iz yok|"
    "gosterge okunakli|gostergede rakam net",
    "abone evde degildi|abone bulunamadi|erisim saglanamadi|erisim yok|kapi zili calismiyor|"
    "zil calismadi|bahce kapisi kilitli|bahce kapisi kapali|bodrum katina inilemedi|"
    "bodrum kilitli|adres bulunamadi|adres eksik",
    "gosterge donmuyor|gostergede hareket yok|sayac cami kirik|sayacin cami catlak|"
    "rakam okunmuyor|rakamlar silik|ibre sabit kalmis|ibre kilitli|mekanizma takilmis|"
    "mekanizmada takilma|sayac durmus|sayac calismiyor",
    "muhur izi var|muhurde iz goruldu|muhur kopmus|muhurler kopuk|baglanti degistirilmis|"
    "baglantida degisiklik|kelepce gevsek|kelepcede gevseme|boru ek yeri yeni|boruda yeni ek|"
    "sayac ters takilmis|sayaci ters takmislar"))}
GURULTU = ("arac park halinde|kapak kirli|hava yagisli|adres teyit edildi|not kisa tutuldu|"
           "ikinci ziyaret|bahce icinde|kaldirim uzerinde").split("|")
BOLGE = "kuzey hatti|guney hatti|dogu hatti|bati hatti|merkez hatti".split("|")
SUP_P = {"kacak suphesi": 0.86, "sayac arizasi": 0.21, "erisilemedi": 0.07, "olagan": 0.03}


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 not_kur(no):
    r = uretec(TOHUM + 41000 + no)
    u, k = r(), 0.0
    for i, p in enumerate(PAY):
        k += p
        if u < k:
            t = TUR[i]
            break
    p = [OBEK[t][int(r() * 12)]]
    if r() < 0.55:
        p.append(OBEK[t][int(r() * 12)])
    if r() < 0.34:                          # baska turden odunc alinan yan kayit
        p.append(OBEK[TUR[int(r() * 4)]][int(r() * 12)])
    if r() < 0.62:
        p.append(GURULTU[int(r() * 8)])
    if r() < 0.30:
        p.append(BOLGE[int(r() * 5)])
    return {"metin": ", ".join(p), "tur": t, "supheli": 1 if r() < SUP_P[t] else 0}


NOT = [not_kur(i) for i in range(1600)]
TUR_I = {t: i for i, t in enumerate(TUR)}
HAVUZ, ETIKETLI, SINAMA = NOT[:700], NOT[700:1100], NOT[1100:]


def bol(m):
    return [w.strip(",").lower() for w in m.split() if w.strip(",")]


d = {}
for x in HAVUZ:
    for w in set(bol(x["metin"])):
        d[w] = d.get(w, 0) + 1
S = {w: i for i, w in enumerate(sorted(w for w, c in d.items() if c >= 2))}
V, GOM = len(S), 6
DIZI = [z for z in ([S[w] for w in bol(x["metin"]) if w in S] for x in HAVUZ)
        if len(z) >= 3]
say = [0] * V
for z in DIZI:
    for i in z:
        say[i] += 1
EN_SIK_S = max(range(V), key=lambda i: say[i])
say2 = {}
for x in ETIKETLI[:160]:
    say2[x["tur"]] = say2.get(x["tur"], 0) + 1
ES = max(say2, key=say2.get)
TABAN = sum(x["tur"] == ES for x in SINAMA) / len(SINAMA)
print(f"etiketsiz havuz {len(DIZI)} not, etiketli havuz {len(ETIKETLI)}, "
      f"ayrilmis {len(SINAMA)}")
print(f"sozluk {V}, gomme boyutu {GOM}, tablo parametresi {V * GOM}, "
      f"govde parametresi {4 * GOM + 4}")
print(f"alanin tabani (en sik sinif '{ES}') {TABAN:.4f}")
```

```
etiketsiz havuz 664 not, etiketli havuz 400, ayrilmis 500
sozluk 109, gomme boyutu 6, tablo parametresi 654, govde parametresi 28
alanin tabani (en sik sinif 'olagan') 0.4420
```

Parametre sayıları bu dersin gerilimini gösteriyor: tablo 654, gövde 28. On etiketli örnekle 682
parametrenin hepsini öğrenmek, kapasitenin veriyi kat kat geçtiği durumdur ve M27/K01
`genelleme/02` bunu ölçmüştü. Önceden eğitimin iddiası şudur: 654 parametre etiketsiz metinden
öğrenilebilir, geriye öğrenilecek 28 parametre kalır.

#### Vekil Görev: Maskeli Kestirim

Maskeli kestirimde her notun her konumu sırayla gizlenir ve gizlenen sözcük kalan sözcüklerin gömme
ortalamasından kestirilir. Öğrenilen şey iki tablodur: girdi gömmesi ve çıktı gömmesi. Asıl göreve
yalnız birincisi taşınır.

```python
def tablo(tohum, olcek=0.5):
    r = uretec(tohum)
    return [[(r() + r() + r() - 1.5) * olcek for _ in range(GOM)] for _ in range(V)]


def maskeli_egit(tohum, tur=4, adim=0.1):     # MODELDIR: vekil gorev
    T, U, c = tablo(tohum), tablo(tohum + 7, 0.3), [0.0] * V
    for _ in range(tur):
        for z in DIZI:
            for k in range(len(z)):
                hedef, cev = z[k], z[:k] + z[k + 1:]
                h = [sum(T[i][j] for i in cev) / len(cev) for j in range(GOM)]
                o = [sum(U[i][j] * h[j] for j in range(GOM)) + c[i] for i in range(V)]
                e = [math.exp(p - max(o)) for p in o]
                s = sum(e)
                dh = [0.0] * GOM
                for i in range(V):
                    f = (e[i] / s - (1.0 if i == hedef else 0.0)) * adim
                    c[i] -= f
                    for j in range(GOM):
                        dh[j] += f * U[i][j]
                        U[i][j] -= f * h[j]
                for i in cev:
                    for j in range(GOM):
                        T[i][j] -= dh[j] / len(cev)
    return T, U, c


def maskeli_olc(T, U, c):
    dog = taban = t = 0
    for z in DIZI[:300]:
        for k in range(len(z)):
            hedef, cev = z[k], z[:k] + z[k + 1:]
            h = [sum(T[i][j] for i in cev) / len(cev) for j in range(GOM)]
            o = [sum(U[i][j] * h[j] for j in range(GOM)) + c[i] for i in range(V)]
            dog += max(range(V), key=lambda i: o[i]) == hedef
            taban += EN_SIK_S == hedef
            t += 1
    return dog / t, taban / t


T0, U0, c0 = maskeli_egit(TOHUM)
mk, mt = maskeli_olc(T0, U0, c0)
print(f"maskeli kestirim: taban (en sik sozcuk) {mt:.4f}, vekil gorev {mk:.4f}, "
      f"fark {mk - mt:+.4f}")
print(f"harcanan etiket 0; on egitim {4} tur, {len(DIZI)} not")
```

```
maskeli kestirim: taban (en sik sozcuk) 0.0419, vekil gorev 0.3450, fark +0.3032
harcanan etiket 0; on egitim 4 tur, 664 not
```

Vekil görev kendi ölçüsünde tabanını 0,3032 geçiyor ve harcanan etiket sıfır. M27/K01
`ml-kavramlari/03` aynı yapıyı sayısal bir vekil görevle kurmuş, orada da vekil görev kendi
tabanını geçmişti — ama taşınan gösterimin katkısı ölçüldüğünde öğrenilmiş kısmın payı 0,0027
**eksi** çıkmıştı. O dersin sonucu şuydu: vekil görevde tabanı geçmek asıl görevde tabanı geçmeyi
getirmez. Aynı soru burada yeniden sorulur ve cevabı yeniden ölçülür.

#### Kattığı Fark ve Kaç Etiketle

Asıl görev önceki dersin görevidir: notun olay türü. Değişen tek şey elde kaç etiket olduğudur.
Dördüncü satırdaki denetim kurulumu bu bölümün asıl aracıdır: rastgele ilklendirilmiş ve **hiç
eğitilmemiş** bir tablo dondurulup aynı gövdeyle kullanılırsa, sayının ne kadarı ortalama almanın
kendisinden gelir.

```python
def kodla(x):
    return [S[w] for w in bol(x["metin"]) if w in S] or [EN_SIK_S]


ETI = [(kodla(x), TUR_I[x["tur"]]) for x in ETIKETLI]
SNV = [(kodla(x), TUR_I[x["tur"]]) for x in SINAMA]


def egit(T, D, tohum, ogren, tur=150, adim=3.0):    # MODELDIR
    T = [u[:] for u in T]
    r = uretec(tohum)
    W = [[(r() - 0.5) * 0.2 for _ in range(GOM)] for _ in range(4)]
    b, n = [0.0] * 4, len(D)
    for _ in range(tur):
        gW = [[0.0] * GOM for _ in range(4)]
        gb = [0.0] * 4
        gT = {} if ogren else None
        for z, y in D:
            h = [sum(T[i][j] for i in z) / len(z) for j in range(GOM)]
            o = [sum(W[q][j] * h[j] for j in range(GOM)) + b[q] for q in range(4)]
            e = [math.exp(p - max(o)) for p in o]
            s = sum(e)
            dh = [0.0] * GOM
            for q in range(4):
                f = e[q] / s - (1.0 if q == y else 0.0)
                gb[q] += f
                for j in range(GOM):
                    gW[q][j] += f * h[j]
                    dh[j] += f * W[q][j]
            if ogren:
                for i in z:
                    g = gT.setdefault(i, [0.0] * GOM)
                    for j in range(GOM):
                        g[j] += dh[j] / len(z)
        for q in range(4):
            b[q] -= adim * gb[q] / n
            for j in range(GOM):
                W[q][j] -= adim * gW[q][j] / n
        if ogren:
            for i, g in gT.items():
                for j in range(GOM):
                    T[i][j] -= adim * g[j] / n
    return T, W, b


def dogruluk(P, D):
    T, W, b = P
    return sum(max(range(4), key=lambda q: sum(
        W[q][j] * sum(T[i][j] for i in z) / len(z) for j in range(GOM)) + b[q]) == y
        for z, y in D) / len(D)


ORNEK = (10, 20, 40, 80, 160)
KURULUM = (("sifirdan", False, True), ("rastgele tablo, donduruk", False, False),
           ("on egitim, donduruk", True, False), ("on egitim, ince ayar", True, True))
SONUC = {}
print(f"{'kurulum':<25}{'ogrenen':>9}" + "".join(f"{'n=' + str(n):>9}" for n in ORNEK)
      + f"{'kosum':>8}")
for ad, onceden, ogren in KURULUM:
    SONUC[ad] = {}
    for n in ORNEK:
        SONUC[ad][n] = [dogruluk(egit(T0 if onceden else tablo(TOHUM + 900 + k),
                                      ETI[:n], TOHUM + 30 + k, ogren), SNV)
                        for k in (1, 2)]
    print(f"{ad:<25}{4 * GOM + 4 + (V * GOM if ogren else 0):>9}"
          + "".join(f"{sum(SONUC[ad][n]) / 2:>9.4f}" for n in ORNEK)
          + f"{max(abs(v[0] - v[1]) for v in SONUC[ad].values()):>8.4f}")
print(f"alanin tabani {TABAN:.4f} (son sutun: iki kosumun en buyuk farki)")
for ad, n in (("on egitim, donduruk", 10), ("on egitim, ince ayar", 20)):
    h = sum(SONUC[ad][n]) / 2
    y = [m for m in ORNEK if sum(SONUC["sifirdan"][m]) / 2 >= h]
    print(f"{ad} n={n} -> {h:.4f}; sifirdan ayni sayiya "
          f"{y[0] if y else '>160'} ornekle ulasiyor")
```

```
kurulum                    ogrenen     n=10     n=20     n=40     n=80    n=160   kosum
sifirdan                       682   0.5050   0.5850   0.7770   0.8740   0.9160  0.0460
rastgele tablo, donduruk        28   0.4510   0.4630   0.5000   0.5050   0.5000  0.1320
on egitim, donduruk             28   0.6050   0.6610   0.7470   0.7470   0.7550  0.0020
on egitim, ince ayar           682   0.5880   0.7480   0.8180   0.8780   0.9070  0.0080
alanin tabani 0.4420 (son sutun: iki kosumun en buyuk farki)
on egitim, donduruk n=10 -> 0.6050; sifirdan ayni sayiya 40 ornekle ulasiyor
on egitim, ince ayar n=20 -> 0.7480; sifirdan ayni sayiya 40 ornekle ulasiyor
```

İkinci satır bu tablonun en önemli satırıdır ve okumadan önce yazılması gerekir. Rastgele
ilklendirilmiş, hiçbir şey öğrenmemiş bir tablo dondurulduğunda beş ölçümün beşinde de 0,51'in
altında kalıyor — tabanın 0,06 kadar üstünde. Ortalama almanın kendisi, sözcüklerin hangi vektöre
oturduğu öğrenilmeden, neredeyse hiçbir şey vermiyor. Üçüncü satırın 0,7550'si bu yüzden **maskeli
kestirimin öğrendiğinin** karşılığıdır: aynı 28 parametre, aynı ortalama, tek fark tablonun
etiketsiz metinden gelmiş olması ve fark 0,2550.

Bu, M27/K01 `ml-kavramlari/03`'ün sonucunun tersidir. Orada vekil görevin öğrenilmiş kısmı asıl
göreve 0,0027 eksi katmış, katkının tamamı taşınan ham gözlemden gelmişti. Burada taşınan ham
gözlem yoktur — taşınan yalnız öğrenilmiş tablodur ve katkı 0,2550'dir. İki dersin farkı vekil
görevin **ne kadar** ilişkili olduğundadır: bir dönemin okumasını kestirmek ile kaçak şüphesi
arasındaki bağ zayıftır, gizli sözcüğü kestirmek ile olay türü arasındaki bağ ise doğrudandır,
çünkü ikisi de aynı sözcük birlikteliklerinden çıkar.

Etiket sayısı sütunları ikinci cevabı verir. Yirmi etikette ince ayarlı kurulum 0,7480,
sıfırdan eğitim 0,5850 veriyor: fark 0,1630 ve bu farkın koşum değişkenliği 0,0460'ın üç katından
büyük olduğu için ölçülmüş sayılır. Sıfırdan eğitim aynı sayıya ancak kırk etiketle ulaşıyor. Yüz
altmışta ise sıfırdan 0,9160, ince ayarlı 0,9070 veriyor — fark 0,0090 eksiye dönmüş, yani
kapanmıştır. Önceden eğitimin kazandırdığı şey son sayı değil, o sayıya varmak için toplanmayan
yirmi etikettir.

Son sütun tabloda ayrıca durur. Rastgele donduruk kurulumun iki koşumu 0,1320 ayrılıyor: o satırda
basılan her sayı, hangi rastgele tablonun düştüğüne bağlı bir kazadır. Önceden eğitilmiş tabloyla
aynı gövde 0,0020 ayrılıyor. Önceden eğitim yalnız ortalamayı yükseltmiyor, **koşumlar arasındaki
saçılmayı da düşürüyor**; bu ikincisi tek bir sayı basan bir tabloda hiç görünmez.

#### Özet

- Vekil görev maskeli kestirimdir ve etiket harcamaz: kendi ölçüsünde taban 0,0419 iken 0,3450
  veriyor, fark 0,3032.
- Alanın tabanı 0,4420; yirmi etikette sıfırdan eğitim 0,5850, önceden eğitim ve ince ayar 0,7480
  veriyor ve sıfırdan eğitim bu sayıya ancak kırk etiketle ulaşıyor.
- Fark etiket sayısıyla kapanır: yüz altmış etikette ince ayarlı kurulum sıfırdan eğitimin 0,0090
  altına iner.
- Denetim kurulumu farkın kaynağını ayırır: hiç eğitilmemiş rastgele bir tablo dondurulduğunda beş
  ölçümde de 0,51'in altında kalır; önceden eğitilmiş tablo aynı 28 parametreyle 0,7550 verir.
- Önceden eğitim koşum saçılmasını da düşürür: rastgele tablonun iki koşumu 0,1320, önceden
  eğitilmiş tablonun iki koşumu 0,0020 ayrılır.

#### Sonraki Adım

Altı derste modelin çıktısı hep bir **etiket** oldu: bir sınıf numarası ya da belirteç başına bir
sınıf numarası. Doğru cevap elde vardı ve ölçü tek bir karşılaştırmaydı. Bir modelin çıktısı
**metnin kendisi** olduğunda bu ölçü kurulamaz: bir notun özeti için tek bir doğru dizi yoktur,
aynı içeriği taşıyan başka diziler de doğrudur. Bu durumda ölçüt aday metin ile kaynak metin
arasındaki **örtüşmeye** çevrilir. Sonraki ders bu ölçütün ne ödüllendirdiğini sayar ve şunu
gösterir: girdiyi olduğu gibi geri veren, hiçbir şey öğrenmemiş bir yordam örtüşme temelli ölçütte
yüksek bir sayı alır.

### Metin Üretimi ve Özetleme

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/metin-uretimi-ve-ozetleme

Çıktının bir etiket değil metin olduğu görevlerde ölçütün ne ödüllendirdiğinin sayılması: girdiyi olduğu gibi geri veren, hiçbir şey öğrenmemiş bir yordam örtüşme temelli ölçütün duyarlılık yönünde 1,0000 alıyor ve dört yordamın birincisi oluyor. Aynı yordam kesinlik yönünde 0,6362, dengeli biçimde 0,7777 veriyor ve üçüncülüğe düşüyor. Kopyanın sonuna sekiz ilgisiz sözcük eklendiğinde duyarlılık 1,0000'de kalırken kesinlik 0,6362'den 0,2700'e iniyor. Kaynak metnin içeriğini doğru bildiren ama başka sözcüklerle yazan üretici yordam dengeli biçimde 0,0684, iki'li dizide 0,0114 alıyor; içerik denetiminde 0,9320 ile ikinci sırada.

Altı derste modelin çıktısı hep bir etiketti ve doğru cevap elde vardı. Bir saha notunun özeti
istendiğinde bu kurulum çöker: aynı içeriği taşıyan birden çok doğru özet vardır ve hiçbiri
"doğru cevap" listesinde yazılı değildir. Denetçinin yazdığı özet bir örnektir, tek doğru değil.

Bu durumda ölçüt, aday metin ile kaynak metin arasındaki **örtüşmeye** çevrilir: kaç sözcük, kaç
ikili dizi ortaktır. Ölçüt böylece hesaplanabilir olur — ama ne ödüllendirdiği ayrı bir sorudur ve
bu ders o soruyu sayıyla cevaplar. Cevabın en sert biçimi şudur: girdiyi olduğu gibi geri veren,
hiçbir şey öğrenmemiş bir yordam bu ölçütte alınabilecek **en yüksek sayıyı** alır.

- **NL56.** Metin kurgusu önceki derslerinkiyle aynıdır ve **kurgudur**; tohum 20260218.
- **NL57.** **Kaynak özet de kurgudur** ve bir kuralla üretilir: notun kendi olay türünden gelen
  öbekler tutulur, ödünç alınan yan kayıt, gürültü ifadesi ve hat işareti atılır. Bu, özetin
  notun kendi sözcüklerinden kurulduğu anlamına gelir ve dersin sonucunun kaynağıdır.
- **NL58.** Kurgu, kararı bildiren öbeğin **notun başında** yazıldığını varsayar. "İlk öbek"
  yordamının içerik ölçüsündeki sayısı bu varsayımın sonucudur, bir yöntem üstünlüğü değil.
- **NL59.** Örtüşme iki yönde ayrı ayrı hesaplanır: **kesinlik yönü** (adayın n'li dizilerinin kaçı
  kaynakta var) ve **duyarlılık yönü** (kaynağın n'li dizilerinin kaçı adayda var). Dengeli biçim
  ikisinin uyumlu ortalamasıdır. Ölçüt tekil sözcük (1'li) ve ikili dizi (2'li) üzerinde ölçülür.
- **NL60.** Tekrarlı n'li diziler **kırpılarak** sayılır: adaydaki bir dizi kaynakta kaç kez
  geçiyorsa o kadar sayılır. Aksi hâlde aynı sözcüğü yineleyen bir aday kesinliği şişirir.
- **NL61.** **Alanın tabanı girdiyi olduğu gibi geri vermektir.** Özetleme görevinde bu, en aptal
  yordamdır: hiçbir seçim yapmaz, hiçbir şey öğrenmez, girdiyi çıktı diye yazar.
- **NL62.** **İçerik denetimi ölçütten ayrı bir sayıdır**: adayın işaret ettiği olay türleri
  kümesi, notun gerçek türüne eşit mi. Bu sayı örtüşme ölçütünün göremediğini ölçer.
- **NL63.** Seçici ve üretici yordamların ağırlıkları **yalnız eğitim kümesinden** öğrenilir;
  ayrılmış küme son 500 nottur.

#### Kaynak Metin ve Aday Metin

Ölçütün iki ucu vardır: denetçinin yazdığı **kaynak metin** ve yordamın ürettiği **aday metin**.
Kurgu, kaynak metni notun kendi öbeklerinden seçerek kurar — gerçek özetleyicilerin de sıkça
yaptığı gibi. Bu seçimin bedeli dersin sonunda ortaya çıkar.

```python
# KURGU saha notlari — M27/K02'nin not alaninin genisletilmis hali. Tohum 20260218.

TOHUM, M32 = 20260218, 0xFFFFFFFF
TUR = ("olagan", "erisilemedi", "sayac arizasi", "kacak suphesi")
PAY = (0.46, 0.22, 0.19, 0.13)
OBEK = {t: s.split("|") for t, s in zip(TUR, (
    "okuma normal|okuma normaldi|sayac erisimi saglandi|sayaca erisildi|olcum tekrarlandi|"
    "olcumu yineledik|vana kontrol edildi|vanada sorun yok|kapak temiz|kapakta iz yok|"
    "gosterge okunakli|gostergede rakam net",
    "abone evde degildi|abone bulunamadi|erisim saglanamadi|erisim yok|kapi zili calismiyor|"
    "zil calismadi|bahce kapisi kilitli|bahce kapisi kapali|bodrum katina inilemedi|"
    "bodrum kilitli|adres bulunamadi|adres eksik",
    "gosterge donmuyor|gostergede hareket yok|sayac cami kirik|sayacin cami catlak|"
    "rakam okunmuyor|rakamlar silik|ibre sabit kalmis|ibre kilitli|mekanizma takilmis|"
    "mekanizmada takilma|sayac durmus|sayac calismiyor",
    "muhur izi var|muhurde iz goruldu|muhur kopmus|muhurler kopuk|baglanti degistirilmis|"
    "baglantida degisiklik|kelepce gevsek|kelepcede gevseme|boru ek yeri yeni|boruda yeni ek|"
    "sayac ters takilmis|sayaci ters takmislar"))}
GURULTU = ("arac park halinde|kapak kirli|hava yagisli|adres teyit edildi|not kisa tutuldu|"
           "ikinci ziyaret|bahce icinde|kaldirim uzerinde").split("|")
BOLGE = "kuzey hatti|guney hatti|dogu hatti|bati hatti|merkez hatti".split("|")
KLM = {c: t for t in TUR for c in OBEK[t]}


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 not_ozet(no):
    r = uretec(TOHUM + 41000 + no)
    u, k = r(), 0.0
    for i, p in enumerate(PAY):
        k += p
        if u < k:
            t = TUR[i]
            break
    p = [OBEK[t][int(r() * 12)]]
    if r() < 0.55:
        p.append(OBEK[t][int(r() * 12)])
    if r() < 0.34:
        p.append(OBEK[TUR[int(r() * 4)]][int(r() * 12)])
    if r() < 0.62:
        p.append(GURULTU[int(r() * 8)])
    if r() < 0.30:
        p.append(BOLGE[int(r() * 5)])
    return {"metin": ", ".join(p), "tur": t, "obek": p,
            "ozet": ", ".join(c for c in p if KLM.get(c) == t)}


VERI = [not_ozet(i) for i in range(1600)]
EGT, SIN = VERI[:1100], VERI[1100:]
for i in (25, 40):
    print(f"not  : {VERI[i]['metin']}")
    print(f"ozet : {VERI[i]['ozet']}  ({VERI[i]['tur']})")
print("ort not", round(sum(len(x["metin"].split()) for x in SIN) / len(SIN), 2),
      "ort ozet", round(sum(len(x["ozet"].split()) for x in SIN) / len(SIN), 2))
```

```
not  : bodrum katina inilemedi, abone evde degildi, sayac cami kirik, bahce icinde
ozet : bodrum katina inilemedi, abone evde degildi  (erisilemedi)
not  : vanada sorun yok, gostergede rakam net, sayac durmus, kuzey hatti
ozet : vanada sorun yok, gostergede rakam net  (olagan)
ort not 6.61 ort ozet 3.99
```

Ortalama not 6,61 belirteç, ortalama özet 3,99 belirteç. Özet notun yaklaşık beşte üçü
uzunluğunda ve tamamı notun içinden geliyor. Bu iki cümle, sonraki tablonun ilk satırını önceden
belirler.

#### Dört Yordam, Altı Sayı

Dört yordam karşılaştırılır. **Girdiyi kopyala** notu olduğu gibi yazar. **İlk öbek** yalnız ilk
virgüle kadarını yazar. **Öğrenilmiş seçici** her öbek için "bu öbek eğitim kümesinde özete kaç kez
girdi" oranını sayar ve yarıdan yukarısını tutar. **Üretici yordam** hiçbir öbeği kopyalamaz:
notun öbeklerinden olay türünü kestirir ve o türün kanonik cümlesini yazar — çıktısı notta geçmeyen
sözcüklerden kurulur.

```python
def blr(m):
    return [w.strip(",").lower() for w in m.split() if w.strip(",")]


def nli(z, n):
    return [tuple(z[i:i + n]) for i in range(len(z) - n + 1)]


def ortusme(aday, kaynak, n=1):
    a, k = nli(blr(aday), n), nli(blr(kaynak), n)
    if not a or not k:
        return 0.0, 0.0
    ort = 0
    kalan = list(k)
    for g in a:
        if g in kalan:
            kalan.remove(g)
            ort += 1
    return ort / len(a), ort / len(k)


# --- yordamlar
def y_kopya(x):
    return x["metin"]


def y_ilk(x):
    return x["obek"][0]


AGIR = {}
for x in EGT:
    for c in x["obek"]:
        a = AGIR.setdefault(c, [0, 0])
        a[0] += 1
        a[1] += c in x["ozet"].split(", ")
SEC = {c: (a[1] / a[0]) for c, a in AGIR.items()}


def y_secici(x):
    p = [c for c in x["obek"] if SEC.get(c, 0.0) > 0.5]
    return ", ".join(p) if p else x["obek"][0]


OZ = {"olagan": "olagan okuma", "erisilemedi": "erisim yok",
      "sayac arizasi": "sayac arizasi", "kacak suphesi": "kacak suphesi"}
PUAN = {}
for x in EGT:
    for c in x["obek"]:
        if c in KLM:
            PUAN.setdefault(c, {})
            PUAN[c][x["tur"]] = PUAN[c].get(x["tur"], 0) + 1


def y_uretici(x):
    s = {}
    for c in x["obek"]:
        for t, v in PUAN.get(c, {}).items():
            s[t] = s.get(t, 0) + v
    t = max(s, key=s.get) if s else "olagan"
    return OZ[t] + " bildirildi"


ISARET = dict(KLM, **{OZ[t]: t for t in TUR})


def icerik(aday, x):
    var = {ISARET[c] for c in ISARET if c in aday}
    return 1 if var == {x["tur"]} else 0


YORDAM = (("girdiyi kopyala", y_kopya), ("ilk obek", y_ilk),
          ("ogrenilmis secici", y_secici), ("uretici yordam", y_uretici))
SONUC = {}
print(f"{'yordam':<19}{'uzunluk':>8}{'duyarlilik':>11}{'kesinlik':>9}"
      f"{'dengeli':>8}{'2li dengeli':>12}{'icerik':>8}")
for ad, f in YORDAM:
    u = d1 = k1 = d2 = k2 = ic = 0.0
    for x in SIN:
        a = f(x)
        u += len(blr(a))
        p, r = ortusme(a, x["ozet"], 1)
        k1 += p
        d1 += r
        p2, r2 = ortusme(a, x["ozet"], 2)
        k2 += p2
        d2 += r2
        ic += icerik(a, x)
    n = len(SIN)
    u, d1, k1, d2, k2, ic = u / n, d1 / n, k1 / n, d2 / n, k2 / n, ic / n
    g1 = 2 * d1 * k1 / (d1 + k1) if d1 + k1 else 0.0
    g2 = 2 * d2 * k2 / (d2 + k2) if d2 + k2 else 0.0
    SONUC[ad] = (u, d1, k1, g1, g2, ic)
    print(f"{ad:<19}{u:>8.2f}{d1:>11.4f}{k1:>9.4f}{g1:>8.4f}{g2:>12.4f}{ic:>8.4f}")
for j, ad in ((1, "duyarlilik"), (3, "dengeli"), (5, "icerik")):
    s = sorted(SONUC, key=lambda a: -SONUC[a][j])
    print(f"{ad:<11} siralama: " + " > ".join(s))
```

```
yordam              uzunluk duyarlilik kesinlik dengeli 2li dengeli  icerik
girdiyi kopyala        6.61     1.0000   0.6362  0.7777      0.7265  0.7440
ilk obek               2.41     0.6901   1.0000  0.8167      0.7576  1.0000
ogrenilmis secici      4.60     1.0000   0.8948  0.9445      0.9312  0.7440
uretici yordam         3.00     0.0622   0.0760  0.0684      0.0114  0.9320
duyarlilik  siralama: girdiyi kopyala > ogrenilmis secici > ilk obek > uretici yordam
dengeli     siralama: ogrenilmis secici > ilk obek > girdiyi kopyala > uretici yordam
icerik      siralama: ilk obek > uretici yordam > girdiyi kopyala > ogrenilmis secici
```

İlk satır bu dersin kursa ödediği borçtur. Girdiyi olduğu gibi geri veren yordam duyarlılık
yönünde **1,0000** alıyor — ölçekte alınabilecek en yüksek sayı — ve dört yordamın birincisi
oluyor. Bu yordam hiçbir eğitim görmedi, hiçbir parametresi yok, hiçbir seçim yapmıyor. Sayının
nedeni kurgunun tanımındadır: kaynak özet notun kendi sözcüklerinden kurulduğu için, notun tamamını
yazan bir aday kaynağın her dizisini zorunlu olarak kapsar. Duyarlılık yönü **kapsamayı** ölçer ve
kapsamanın en ucuz yolu her şeyi yazmaktır.

Aynı yordam kesinlik yönünde 0,6362, dengeli biçimde 0,7777 alıyor ve üçüncülüğe düşüyor. Üç
sıralama satırı yan yana okunduğunda dört yordamın sırası üç ölçütte üç ayrı biçimde çıkıyor;
"hangi yordam daha iyi" sorusunun cevabı hangi sayının basıldığına bağlı.

Son satır ikinci borçtur. Üretici yordam içerik denetiminde 0,9320 alıyor — dört yordamın
ikincisi — ama örtüşme ölçütünün dengeli biçiminde 0,0684, iki'li dizide 0,0114. Ölçüt bu yordamı
neredeyse hiç göremiyor, çünkü doğru şeyi **başka sözcüklerle** söylüyor. Örtüşme temelli bir ölçüt
sözcük paylaşımını ölçer, bildirimin doğruluğunu değil.

İkinci satır bir uyarı taşır. "İlk öbek" yordamı içerik denetiminde 1,0000 alıyor ve bu sayı bir
yöntem üstünlüğü değildir: kurgu, kararı bildiren öbeğin notun başında yazıldığını varsayar, o
yüzden ilk öbeği almak türü hiçbir zaman kaçırmaz. Aynı yordam duyarlılıkta 0,6901'de kalıyor,
çünkü notların bir bölümünde kaynak özet iki öbekten oluşuyor ve ikincisi atılıyor. Bir sayının
kurgunun hangi maddesinden geldiği yazılmadığında, bu satır "en iyi özetleyici en kısa olanıdır"
gibi okunabilir; kurgu yazıldığında öyle okunamaz.

İki'li dizi sütunu tekil sözcük sütununu tekrarlamaz. Kopyanın dengeli biçimi 0,7777'den 0,7265'e,
seçicininki 0,9445'ten 0,9312'ye, üretici yordamınki 0,0684'ten 0,0114'e iniyor. Dizi uzunluğu
arttıkça ölçüt sözcük seçimine değil **sıraya** da bakmaya başlar ve başka sözcüklerle yazılmış bir
aday için ceza altı katına çıkar.

Öğrenilmiş seçicinin 0,9445'i ile içerik ölçüsündeki 0,7440'ı arasındaki mesafe aynı boşluğun öbür
yüzüdür: seçici kaynak özetin sözcüklerini isabetle buluyor ama ödünç alınmış yan kaydı da
tutuyor, yani özetin bildirdiği olay türü dörtte bir olayda yanlış çıkıyor. Ölçüt bunu görmez,
çünkü o yan kayıt da notun içindedir ve kaynakta yoksa yalnız kesinliği bir miktar düşürür.

#### Ölçüt Neyi Ödüllendiriyor

Duyarlılık yönünün kapsamayı ödüllendirdiği iddiası doğrudan sınanabilir: kopyanın sonuna kaynak
özette hiç geçmeyen sözcükler eklenir ve sayıların hangisinin kımıldadığına bakılır.

```python
# Olcut neyi odullendiriyor: adayin sonuna ilgisiz sozcuk eklendiginde ne oluyor.
DOLGU = "kayit alindi ekip donusu form imzalandi saat girildi".split()
print(f"{'aday':<26}{'uzunluk':>8}{'duyarlilik':>11}{'kesinlik':>9}"
      f"{'dengeli':>8}{'icerik':>8}")
for e in (0, 2, 4, 8):
    u = d = k = ic = 0.0
    for x in SIN:
        a = x["metin"] + ("" if e == 0 else " " + " ".join(DOLGU[:e]))
        u += len(blr(a))
        p, r = ortusme(a, x["ozet"], 1)
        k += p
        d += r
        ic += icerik(a, x)
    n = len(SIN)
    u, d, k, ic = u / n, d / n, k / n, ic / n
    print(f"{'girdiyi kopyala + ' + str(e) + ' dolgu':<26}{u:>8.2f}{d:>11.4f}"
          f"{k:>9.4f}{2 * d * k / (d + k):>8.4f}{ic:>8.4f}")
d0, k0, g0, i0 = SONUC["uretici yordam"][1], SONUC["uretici yordam"][2], \
    SONUC["uretici yordam"][3], SONUC["uretici yordam"][5]
print(f"{'uretici yordam':<26}{SONUC['uretici yordam'][0]:>8.2f}{d0:>11.4f}"
      f"{k0:>9.4f}{g0:>8.4f}{i0:>8.4f}")
esit = [c for c in SIN if ortusme(y_kopya(c), c["ozet"], 1)[1] < 1.0]
print(f"kopyada duyarliligi 1,0000'in altinda kalan not: {len(esit)}/{len(SIN)}")
```

```
aday                       uzunluk duyarlilik kesinlik dengeli  icerik
girdiyi kopyala + 0 dolgu     6.61     1.0000   0.6362  0.7777  0.7440
girdiyi kopyala + 2 dolgu     8.61     1.0000   0.4685  0.6381  0.7440
girdiyi kopyala + 4 dolgu    10.61     1.0000   0.3750  0.5454  0.7440
girdiyi kopyala + 8 dolgu    14.61     1.0000   0.2700  0.4252  0.7440
uretici yordam                3.00     0.0622   0.0760  0.0684  0.9320
kopyada duyarliligi 1,0000'in altinda kalan not: 0/500
```

Duyarlılık sütunu dört satırda da tam olarak 1,0000. Aday metnin uzunluğu 6,61'den 14,61'e, iki
katından fazlasına çıkarken bu sayı bir basamak bile oynamıyor; içerik denetimi de oynamıyor,
çünkü eklenen sözcükler hiçbir olay türüne işaret etmiyor. Kımıldayan tek sayı kesinliktir:
0,6362'den 0,2700'e iniyor ve dengeli biçimi 0,7777'den 0,4252'ye çekiyor. Yalnız duyarlılık yönü
basılan bir raporda, aday metne ilgisiz sözcük eklemek **bedava** bir işlemdir.

Son satır kopyanın 1,0000'ini beş yüz notun beş yüzünde de aldığını söylüyor. Bu bir ortalama
değil, bir kimliktir: kurgunun kaynak özeti notun alt kümesi olduğu sürece kopya duyarlılıkta
hiçbir zaman 1,0000'in altına düşemez. Gerçek özetlerin çoğu da bu özelliği taşır, çünkü
özetleyiciler kaynağın sözcüklerini yeniden kullanır. Ölçütün bir yordamı ödüllendirmesi ile o
yordamın bir şey öğrenmiş olması arasında bu kurulumda hiçbir bağ yoktur.

#### Özet

- Çıktı metin olduğunda tek bir doğru cevap yoktur; ölçüt aday metin ile kaynak metin arasındaki
  örtüşmeye çevrilir ve iki yönde ayrı ayrı okunur.
- Girdiyi olduğu gibi geri veren yordam duyarlılık yönünde 1,0000 alır ve dört yordamın
  birincisidir; kesinlik yönünde 0,6362 alır ve üçüncülüğe düşer.
- Kopyanın sonuna sekiz ilgisiz sözcük eklendiğinde duyarlılık 1,0000'de kalır, kesinlik 0,2700'e
  iner: ölçütün duyarlılık yönü kapsamayı ödüllendirir, doğruluğu değil.
- Ölçüt sözcük paylaşımını görür, bildirimin doğruluğunu görmez: üretici yordam içerik denetiminde
  0,9320 alırken dengeli biçimde 0,0684, iki'li dizide 0,0114 alır.
- Aynı dört çıktı üç ölçütte üç ayrı sıralama verir; hangi yordamın daha iyi olduğu, hangi sayının
  basıldığına bağlıdır.

#### Sonraki Adım

Bu derste üç ölçüt üç ayrı sıralama verdi ve her birinin yanına neyin ödüllendirildiği yazıldı.
Aynı sorun bu kursun bütün görevlerinde vardır: belirteç düzeyinde okunan bir sayı ile varlık
düzeyinde okunan sayı aynı çıktıyı iki ayrı biçimde sıralar, dengesiz bir sınıf kümesinde genel
doğruluk ile sınıf başına ortalama başka türlü sıralar. Sonraki ders konunun kapanışıdır: **aynı
dört çıktı dört ölçütte dört ayrı sıralama** verir ve her ölçütün hangi tabana karşı okunması
gerektiği tek tek yazılır.

### Doğal Dil İşleme Ölçütleri

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/dogal-dil-isleme-olcutleri

Tek bir çıktının dört ölçütte okunması ve dört ölçütün dört ayrı sıralama vermesi: aynı dört sistem belirteç düzeyinde B > A > C > D, varlık düzeyinde A > B > C > D, belge düzeyinde C > B > A > D, örtüşme duyarlılık yönünde D > B > A > C sıralanıyor ve her ölçütün birincisi başka bir sistem. Her ölçüt kendi tabanına karşı okunur: belirteç düzeyinde en sık etiket 0,3970, belge düzeyinde en sık sınıf 0,4420, varlık düzeyinde hiç aralık işaretlememek 0,0000, örtüşmenin duyarlılık yönünde bütün girdiyi işaretlemek 1,0000. Son satırda taban ile en iyi sistem arasındaki fark tam olarak 0,0000'dır.

Önceki derste üç ölçüt üç ayrı sıralama verdi ve girdiyi kopyalayan yordam duyarlılık yönünde
1,0000 aldı. O bulgu tek bir görevin özelliği değildir. Bu konunun sekiz dersinde ölçütler dört
ayrı düzeyde okundu: belirteç düzeyinde, varlık düzeyinde, belge düzeyinde ve örtüşme üzerinden.
Aynı sistem bu dört düzeyde dört ayrı sayı verir ve sayılar birbirinin sıralamasını korumaz.

Bu ders konunun kapanışıdır ve tek bir kurulumla bitirir: dört sistem, **tek bir çıktı biçimi**,
dört ölçüt. Çıktı her not için belirteç başına bir etikettir; dört ölçütün dördü de aynı
etiketlemeden okunur. Kesinlik, duyarlılık ve dengeli biçimin tanımları M27/K03
`model-degerlendirme`'de kuruldu ve burada tekrarlanmaz; buradaki soru tanım değil, **karar
biriminin** ve **tabanın** ölçütü nasıl değiştirdiğidir.

- **NL64.** Metin kurgusu önceki derslerinkiyle aynıdır ve **kurgudur**; tohum 20260218.
- **NL65.** **Altın etiketleme kurgudur**: notun kendi olay türünden gelen öbeklerin bütün
  belirteçleri o türle, geri kalan bütün belirteçler `yok` ile etiketlenir. Ödünç alınan yan kayıt
  `yok` sayılır — notun bildirdiği olay o değildir.
- **NL66.** **Çıktı biçimi tektir**: her sistem her belirteç için bir etiket üretir. Dört ölçüt de
  bu tek çıktıdan hesaplanır; hiçbir sistem ölçüte göre ayrı bir çıktı vermez.
- **NL67.** **Aralık** ardışık ve aynı etiketli belirteçlerin en uzun dizisidir. Varlık düzeyinde
  bir aralık ancak başlangıcı, bitişi ve etiketi birlikte tutarsa doğru sayılır.
- **NL68.** **Belge düzeyi karar çıktıdan türetilir**: işaretli belirteçlerin en sık etiketi notun
  türü sayılır; hiç işaret yoksa en sık sınıf yazılır.
- **NL69.** Örtüşme ölçütü önceki dersin **duyarlılık yönüdür**: altın etiketlemede işaretli olan
  belirteçlerin kaçı çıktıda da işaretli. Tekrarlı belirteçler kırpılarak sayılır.
- **NL70.** **Dört ölçütün dört ayrı tabanı vardır** ve her taban o ölçütün en aptal yordamıdır:
  en sık etiketi her belirtece yazmak, hiç aralık işaretlememek, en sık sınıfı yazmak, bütün
  girdiyi işaretlemek.
- **NL71.** Sistemlerin öğrendiği tablolar **yalnız eğitim kümesinden** kurulur; ayrılmış küme son
  500 nottur.
- **NL72.** Dört sistemin hiçbiri ötekinden türetilmemiştir; dördü de aynı ayrılmış kümede,
  aynı çıktı biçimiyle koşar.

#### Tek Çıktı, Dört Okuma

Altın etiketleme kurulduğunda iki taban doğrudan okunabilir: belirteç düzeyinde en sık etiketi her
belirtece yazan yordam ve belge düzeyinde en sık sınıfı yazan yordam.

```python
# KURGU saha notlari — M27/K02'nin not alaninin genisletilmis hali. Tohum 20260218.

TOHUM, M32 = 20260218, 0xFFFFFFFF
TUR = ("olagan", "erisilemedi", "sayac arizasi", "kacak suphesi")
PAY = (0.46, 0.22, 0.19, 0.13)
OBEK = {t: s.split("|") for t, s in zip(TUR, (
    "okuma normal|okuma normaldi|sayac erisimi saglandi|sayaca erisildi|olcum tekrarlandi|"
    "olcumu yineledik|vana kontrol edildi|vanada sorun yok|kapak temiz|kapakta iz yok|"
    "gosterge okunakli|gostergede rakam net",
    "abone evde degildi|abone bulunamadi|erisim saglanamadi|erisim yok|kapi zili calismiyor|"
    "zil calismadi|bahce kapisi kilitli|bahce kapisi kapali|bodrum katina inilemedi|"
    "bodrum kilitli|adres bulunamadi|adres eksik",
    "gosterge donmuyor|gostergede hareket yok|sayac cami kirik|sayacin cami catlak|"
    "rakam okunmuyor|rakamlar silik|ibre sabit kalmis|ibre kilitli|mekanizma takilmis|"
    "mekanizmada takilma|sayac durmus|sayac calismiyor",
    "muhur izi var|muhurde iz goruldu|muhur kopmus|muhurler kopuk|baglanti degistirilmis|"
    "baglantida degisiklik|kelepce gevsek|kelepcede gevseme|boru ek yeri yeni|boruda yeni ek|"
    "sayac ters takilmis|sayaci ters takmislar"))}
GURULTU = ("arac park halinde|kapak kirli|hava yagisli|adres teyit edildi|not kisa tutuldu|"
           "ikinci ziyaret|bahce icinde|kaldirim uzerinde").split("|")
BOLGE = "kuzey hatti|guney hatti|dogu hatti|bati hatti|merkez hatti".split("|")
KLM = {c: t for t in TUR for c in OBEK[t]}


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 not_ozet(no):
    r = uretec(TOHUM + 41000 + no)
    u, k = r(), 0.0
    for i, p in enumerate(PAY):
        k += p
        if u < k:
            t = TUR[i]
            break
    p = [OBEK[t][int(r() * 12)]]
    if r() < 0.55:
        p.append(OBEK[t][int(r() * 12)])
    if r() < 0.34:
        p.append(OBEK[TUR[int(r() * 4)]][int(r() * 12)])
    if r() < 0.62:
        p.append(GURULTU[int(r() * 8)])
    if r() < 0.30:
        p.append(BOLGE[int(r() * 5)])
    return {"metin": ", ".join(p), "tur": t, "obek": p,
            "ozet": ", ".join(c for c in p if KLM.get(c) == t)}
YOK = "yok"


def blr(m):
    return [w.strip(",").lower() for w in m.split() if w.strip(",")]


VERI = []
for i in range(1600):
    x = not_ozet(i)
    z, e = [], []
    for c in x["obek"]:                      # ALTIN etiket: kendi turunden obekler
        w = blr(c)
        z += w
        e += [x["tur"] if KLM.get(c) == x["tur"] else YOK] * len(w)
    x["z"], x["e"] = z, e
    VERI.append(x)
EGT, SIN = VERI[:1100], VERI[1100:]
et = {}
for x in EGT:
    for u in x["e"]:
        et[u] = et.get(u, 0) + 1
EN_SIK_ET = max(et, key=et.get)
EN_SIK_TUR = max(TUR, key=lambda t: sum(y["tur"] == t for y in EGT))
n = len(SIN)
T_BEL = sum(u == EN_SIK_ET for x in SIN for u in x["e"]) / sum(len(x["e"]) for x in SIN)
T_BLG = sum(x["tur"] == EN_SIK_TUR for x in SIN) / n
print(f"ayrilmis {n} not, {sum(len(x['z']) for x in SIN)} belirtec, "
      f"isaretli belirtec {sum(u != YOK for x in SIN for u in x['e'])}")
tp = sum(et.values())
print("altin etiket dagilimi (egitim):  " + "  ".join(
    f"{u}={et[u] / tp:.3f}" for u in sorted(et, key=lambda u: -et[u])[:3]))
print("                                 " + "  ".join(
    f"{u}={et[u] / tp:.3f}" for u in sorted(et, key=lambda u: -et[u])[3:]))
print(f"belirtec duzeyi taban ('{EN_SIK_ET}' her belirtece) {T_BEL:.4f}, "
      f"belge duzeyi taban ('{EN_SIK_TUR}') {T_BLG:.4f}")
```

```
ayrilmis 500 not, 3305 belirtec, isaretli belirtec 1993
altin etiket dagilimi (egitim):  yok=0.413  olagan=0.267  erisilemedi=0.125
                                 sayac arizasi=0.111  kacak suphesi=0.084
belirtec duzeyi taban ('yok' her belirtece) 0.3970, belge duzeyi taban ('olagan') 0.4420
```

Etiket dağılımı belirteç düzeyi tabanının niçin 0,3970 olduğunu söylüyor: belirteçlerin yaklaşık
beşte ikisi hiçbir olaya ait değil ve `yok` tek başına en sık etiket. M27/K03 dengesiz sınıf
kümesinde genel doğruluğun ne kadar aldatıcı olduğunu ölçmüştü; burada aynı dengesizlik ölçütün
**karar birimi** seçildiği anda ortaya çıkıyor. 3.305 belirtecin 1.993'ü işaretli, 1.312'si değil.

#### Dört Sistem, Dört Sıralama

Dört sistem dört ayrı tasarım kararını temsil eder. **A — öbek düzeyi seçici** kararı öbek
üzerinden verir: bir öbeğin eğitim kümesinde altın etiketlemeye girme oranı 0,75'in üstündeyse
öbeğin bütün belirteçleri işaretlenir, etiket belge kestiriminden gelir. **B — belirteç düzeyi
seçici** kararı tek tek belirteçler üzerinden verir: bir sözcüğün işaretlenme oranı 0,40'ın
üstündeyse işaretlenir. **C — dar işaretleyici** yalnız ilk öbeği işaretler ve etiketi o öbeğin
kendi türünden alır. **D — hepsini işaretle** her belirtece en sık türü yazar; hiçbir şey öğrenmez.

```python
AGIR, BAGIR, PUAN = {}, {}, {}
for x in EGT:
    for c in x["obek"]:
        a = AGIR.setdefault(c, [0, 0])
        a[0] += 1
        a[1] += KLM.get(c) == x["tur"]
        if c in KLM:
            PUAN.setdefault(c, {})
            PUAN[c][x["tur"]] = PUAN[c].get(x["tur"], 0) + 1
    for w, u in zip(x["z"], x["e"]):
        a = BAGIR.setdefault(w, [0, 0])
        a[0] += 1
        a[1] += u != YOK
SEC = {c: a[1] / a[0] for c, a in AGIR.items()}
BSEC = {w: a[1] / a[0] for w, a in BAGIR.items()}


def kestir_tur(x):
    s = {}
    for c in x["obek"]:
        for t, v in PUAN.get(c, {}).items():
            s[t] = s.get(t, 0) + v
    return max(s, key=s.get) if s else EN_SIK_TUR


def s_obek(x):
    t, e = kestir_tur(x), []
    for c in x["obek"]:
        e += [(t if SEC.get(c, 0.0) > 0.75 else YOK)] * len(blr(c))
    return e


def s_belirtec(x):
    t = kestir_tur(x)
    return [(t if BSEC.get(w, 0.0) > 0.40 else YOK) for w in x["z"]]


def s_dar(x):
    e = []
    for i, c in enumerate(x["obek"]):
        e += [(KLM.get(c, YOK) if i == 0 else YOK)] * len(blr(c))
    return e


def s_hepsi(x):
    return [EN_SIK_TUR] * len(x["z"])


def araliklar(e):
    a, i = [], 0
    while i < len(e):
        if e[i] == YOK:
            i += 1
            continue
        j = i
        while j + 1 < len(e) and e[j + 1] == e[i]:
            j += 1
        a.append((i, j, e[i]))
        i = j + 1
    return a


def olc(f):
    bd = bt = ad = ak = at = be = 0
    du = 0.0
    for x in SIN:
        e = f(x)
        bd += sum(u == v for u, v in zip(e, x["e"]))
        bt += len(e)
        g, p = araliklar(x["e"]), araliklar(e)
        ad += sum(u in g for u in p)
        ak += len(p)
        at += len(g)
        s = {}
        for u in e:
            if u != YOK:
                s[u] = s.get(u, 0) + 1
        be += (max(s, key=s.get) if s else EN_SIK_TUR) == x["tur"]
        kal = [w for w, u in zip(x["z"], x["e"]) if u != YOK]
        o = 0
        for w in [w for w, u in zip(x["z"], e) if u != YOK]:
            if w in kal:
                kal.remove(w)
                o += 1
        du += o / max(1, sum(u != YOK for u in x["e"]))
    k, d = ad / max(1, ak), ad / max(1, at)
    return (bd / bt, 2 * k * d / (k + d) if k + d else 0.0, be / len(SIN),
            du / len(SIN))


SIS = (("A", "obek duzeyi secici", s_obek), ("B", "belirtec duzeyi secici", s_belirtec),
       ("C", "dar isaretleyici", s_dar), ("D", "hepsini isaretle", s_hepsi))
S = {k: olc(f) for k, _, f in SIS}
OLCUT = ("belirtec", "varlik", "belge", "ortusme")
print(f"{'':<3}{'sistem':<24}" + "".join(f"{o:>11}" for o in OLCUT))
for k, ad, _ in SIS:
    print(f"{k:<3}{ad:<24}" + "".join(f"{v:>11.4f}" for v in S[k]))
for j, o in enumerate(OLCUT):
    print(f"{o:<9} siralamasi: " + " > ".join(
        sorted(S, key=lambda a: -S[a][j])))
```

```
   sistem                     belirtec     varlik      belge    ortusme
A  obek duzeyi secici           0.8136     0.6779     0.8320     0.8423
B  belirtec duzeyi secici       0.8378     0.6036     0.9320     0.9693
C  dar isaretleyici             0.7619     0.4000     1.0000     0.6901
D  hepsini isaretle             0.2732     0.0920     0.4420     1.0000
belirtec  siralamasi: B > A > C > D
varlik    siralamasi: A > B > C > D
belge     siralamasi: C > B > A > D
ortusme   siralamasi: D > B > A > C
```

Dört sıralama satırı bu dersin cevabıdır. Dört ölçütün dördü de aynı dört çıktıyı okuyor ve
dördünde de sıralama başka: B > A > C > D, A > B > C > D, C > B > A > D, D > B > A > C. Dört
ölçütün **birincisi de dört ayrı sistem**. "Hangi sistem daha iyi" sorusunun bu kurulumda cevabı
yoktur; cevabı olan soru "hangi ölçütte" sorusudur.

Farkların nereden geldiği tek tek okunabilir. A ile B arasındaki ayrım karar birimindedir: B
belirteç başına karar verdiği için belirteç düzeyinde 0,8378 ile öndedir, ama kararını komşusundan
bağımsız verdiği için bir öbeğin ortasındaki bir sözcüğü atlar ve aralığı ikiye böler; varlık
düzeyinde 0,6036'ya, A'nın 0,0743 altına düşer. Aynı çıktı, aynı sayıda doğru belirteç, iki ayrı
sıralama.

C bütün sistemler içinde en az belirteç işaretleyen sistemdir ve belge düzeyinde 1,0000 alır. Bu
sayı kurgunun bir sonucudur — kararı bildiren öbek notun başında yazılır — ve bir yöntem üstünlüğü
olarak okunamaz. Aynı sistem varlık düzeyinde 0,4000'de kalır, çünkü notların bir bölümünde altın
aralık iki öbeği kapsar ve C ikincisini hiç işaretlemez.

D satırı kursun ikinci iddiasının bu konudaki üçüncü ödemesidir. D hiçbir şey öğrenmez: her
belirtece eğitim kümesinin en sık türünü yazar. Belirteç düzeyinde 0,2732 ile tabanın bile altına
düşer, varlık düzeyinde 0,0920 alır — ve örtüşme ölçütünün duyarlılık yönünde **1,0000** ile dört
sistemin birincisi olur. Bir ölçüt, hiçbir şey öğrenmemiş bir yordamı birinci sıraya
koyabiliyorsa, o ölçütün tek başına basılması bir ölçüm değil bir seçimdir.

#### Her Ölçütün Kendi Tabanı

Dört ölçütün dört ayrı tabanı vardır ve tabanlar aynı ölçekte değildir. Bir sayının büyüklüğü
kendi başına hiçbir şey söylemez; söyleyen şey o sayının kendi tabanından ne kadar uzakta
durduğudur.

```python
TB = (("belirtec duzeyi dogruluk", "en sik etiketi her belirtece yaz", T_BEL),
      ("varlik duzeyi dengeli bicim", "hic aralik isaretleme", 0.0),
      ("belge duzeyi dogruluk", "en sik sinifi yaz", T_BLG),
      ("ortusme duyarlilik yonu", "butun girdiyi isaretle", 1.0))
print(f"{'olcut':<28}{'taban yordami':<34}{'taban':>7}{'en iyi':>8}{'fark':>8}")
for j, (o, ty, tv) in enumerate(TB):
    en = max(S, key=lambda a: S[a][j])
    print(f"{o:<28}{ty:<34}{tv:>7.4f}{S[en][j]:>8.4f}{S[en][j] - tv:>+8.4f}")
```

```
olcut                       taban yordami                       taban  en iyi    fark
belirtec duzeyi dogruluk    en sik etiketi her belirtece yaz   0.3970  0.8378 +0.4408
varlik duzeyi dengeli bicim hic aralik isaretleme              0.0000  0.6779 +0.6779
belge duzeyi dogruluk       en sik sinifi yaz                  0.4420  1.0000 +0.5580
ortusme duyarlilik yonu     butun girdiyi isaretle             1.0000  1.0000 +0.0000
```

Tablo dört satırda dört ayrı mesafe veriyor. Varlık düzeyinde en iyi sistem tabanın 0,6779
üstünde, belge düzeyinde 0,5580, belirteç düzeyinde 0,4408. Bu üç satır sıralanabilir ama
karşılaştırılamaz: üç ayrı karar birimi, üç ayrı taban, üç ayrı ölçek.

Son satır konunun kapanış cümlesidir. Örtüşme ölçütünün duyarlılık yönünde taban 1,0000'dir,
çünkü bütün girdiyi işaretleyen yordam altın etiketlemenin her belirtecini zorunlu olarak kapsar.
En iyi sistem de 1,0000 alır ve fark tam olarak **0,0000**'dır. Bu ölçüt, üstüne hiçbir şey
konulamayacak bir tabana sahiptir: hiçbir öğrenme onu geçemez, yalnız eşitleyebilir. Bir ölçüt
seçilirken sorulacak ilk soru, o ölçütün en aptal yordamının aynı ölçütte kaç aldığıdır; ikinci
soru, o sayının üstünde geçilecek bir yer kalıp kalmadığıdır.

Varlık düzeyindeki 0,0000'lık taban ise ters uçtadır ve o da yanıltır: hiç aralık işaretlemeyen
bir yordam sıfır alır, yani bu ölçütte tabanı geçmek bedavadır. Daha dürüst taban aynı tablodaki
D sistemidir: bütün notu tek aralık sayan yordam 0,0920 alır ve en iyi sistemin farkı 0,6779'dan
0,5859'a iner.

#### Özet

- Tek bir belirteç etiketlemesi dört ayrı düzeyde okunabilir ve dört ölçüt aynı çıktıdan dört ayrı
  sayı üretir.
- Dört ölçüt dört ayrı sıralama verir ve dördünün birincisi dört ayrı sistemdir: belirteç
  düzeyinde B, varlık düzeyinde A, belge düzeyinde C, örtüşmede D.
- Karar birimi ölçütü belirler: belirteç başına karar veren sistem belirteç düzeyinde önde,
  aralığı bölmesi yüzünden varlık düzeyinde 0,0743 geride kalır.
- Hiçbir şey öğrenmeyen sistem belirteç düzeyinde tabanın altına düşer ama örtüşmenin duyarlılık
  yönünde 1,0000 ile birinci olur.
- Her ölçütün kendi tabanı vardır ve tabanlar aynı ölçekte değildir: 0,3970, 0,0000, 0,4420 ve
  1,0000; sonuncusunda tabanla en iyi sistemin farkı 0,0000'dır.

#### Sonraki Adım

Sekiz derste girdi hep bir **diziydi**. Belirteçler soldan sağa sıralıydı, bir sözcüğün komşusu
tek bir eksende bulunuyordu, aralık başlangıç ve bitiş indisiyle tanımlanıyordu ve sıranın kendisi
bilgi taşıyordu: "muhur izi var" ile "var izi muhur" aynı sözcük torbasına sahiptir ama aynı şey
değildir. Örtüşme ölçütünün iki'li dizilerde tekil sözcüklerden ayrılması da bu tek eksenin
sonucuydu.

Girdinin **iki boyutlu** olduğu ve komşuluğun sağa sola değil **her yöne** açıldığı bir alanda bu
kurulumun her parçası yeniden sorulur. Bir aralık artık bir başlangıç ve bitiş değil, bir
dikdörtgendir; örtüşme bir sayaç değil, bir alan oranıdır; sözlük diye bir şey yoktur, çünkü
girdinin birimi bir sözcük değil bir sayıdır ve o sayının kendi başına anlamı yoktur. Sonraki konu
görüntüyle başlar ve aynı soruyla açılır: bu alanın en aptal yordamı nedir ve o yordam kendi
ölçütünde kaç alıyor.

## Bilgisayarla Görme

Kapsama ızgarasından üretilen kurgu görüntülerde her görevin kendi tabanına karşı ölçülmesi: normalleştirme ve artırmanın katkısı ile artırmanın etiketi bozduğu dönüşüm, ortalama görüntü tabanına karşı uçtan uca eğitim ve aktarımın kaç örnekle kattığı, görüntünün ortasına konan sabit bir kutunun örtüşme ölçütünde aldığı sayı ve eşik 0,3'ten 0,7'ye çıkarken hem yöntemin hem sabit kutunun düşmesi, her pikseli baskın sınıfa atayan tabanın piksel dengesizliği yüzünden yüksek çıkması ve bitişik iki nesnede anlamsal bölütlemenin ayıramaması, bağımsız kare kararı ile zamanı kullanan kararın ardışık karelerdeki tutarsızlığı, notu görüntüsüyle eşleştiren ortak temsilin rastgele eşleştirmeye göre başarısı ve tek kipin tek başına verdiği pay.

### Görüntü Verisi ve Ön İşleme

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/goruntu-verisi-ve-on-isleme

Pikselin sayıya çevrilme biçiminin ne kadarını taşıdığının ölçülmesi: aynı iki yordam üç temsilde okunduğunda küme geneli ölçekleme hiçbir sayıyı oynatmıyor (0,5500 ve 0,6937 aynen kalıyor), görüntü başına normalleştirme eşik kuralını 0,6937'den 0,9250'ye çıkarıyor, ortalama görüntü tabanını 0,5500'den 0,4875'e düşürüyor. Beş artırma dönüşümünden çeyrek dönüş 160 örneğin 160'ında etiketi ters çeviriyor, kaydırma 1'inde bozuyor. Kırk etiketle en yakın komşu artırmasız 0,5938 ve 0,6250 okurken iki çevirme 0,6875 ve 0,6250, çeyrek dönüş etiketi korunarak eklendiğinde 0,5188 ve 0,5000 okuyor: en sık sınıfın 0,5312'sinin altı.

Sekiz derste girdi bir **dizi** idi. Belirteçler soldan sağa sıralanıyordu, bir belirtecin komşusu
önündeki ve ardındakiydi ve sıranın kendisi bilgi taşıyordu. Görüntüde tek bir sıra yoktur: bir
pikselin komşusu sağında, solunda, üstünde, altında ve dört köşesindedir, hiçbiri ötekinden önce
gelmez. Aranan şey de tek bir hücrede değil, bitişik hücrelerin oluşturduğu bir düzendedir ve o
düzen ızgaranın herhangi bir yerinde bulunabilir.

İkinci fark daha sessizdir. Metinde bir belirteç bir **simgedir**; iki ayrı belgede aynı belirteç
tıpatıp aynı şeydir. Piksel ise bir **ölçümdür**: aynı nesne, ölçüm koşulları değiştiğinde başka
sayılarla yazılır. Bu yüzden görüntüde **normalleştirme** piksel değerlerinin dönüştürülmesi
demektir ve M26/K03'ün bir dizgiyi kanonik biçime getiren metin normalleştirmesiyle ilgisi yoktur.
Dersin ölçüsü budur — pikselin sayıya çevrilme kararı, hiçbir model değişmeden, aynı yordamın
sayısını ne kadar oynatıyor.

- **BG1. Görüntü kurgudur.** M26/K06'nın 12x12'lik kapsama ızgarası burada tek kanallı, gri
  düzeyli küçük bir görüntü yerine geçer. Her hücre bir **piksel**, değeri 0 ile 255 arasında bir
  **gri düzeydir**. Tohum 20260218.
- **BG2. Zemin ve karşıtlık görüntüden görüntüye değişir;** bu, kurgunun bilerek konmuş güçlüğüdür.
- **BG3. Nesne kurgudur.** Izgaraya tek bir dikdörtgen **blok** ekilir; kenarları 2 ile 6 arasında
  ve birbirinden farklıdır.
- **BG4. Etiket bloğun yönüdür.** Genişlik yükseklikten büyükse 1, değilse 0. Etiket bloğun
  **nerede** olduğuna değil, **biçimine** bağlıdır.
- **BG5. Blok ızgaranın ortasına doğru toplanır.** Konum üç bağımsız çekimin ortalamasıyla
  seçilir; bu, gerçek görüntü kümelerindeki merkez yanlılığının karşılığıdır ve üçüncü derste bir
  bedeli olacaktır.
- **BG6. Bölme 400 görüntü üzerinde 160/80/160'tır** ve konu boyunca sabittir.
- **BG7. Alanın tabanı iki yordamdır:** en sık sınıfı söylemek ve **ortalama görüntü** — sınıf
  ortalamaları hesaplanır, görüntü hangisine yakınsa o sınıfa yazılır.
- **BG8. Eşik ve ayar kararları doğrulama kümesinden okunur;** süpürme dokuz adayı aşmaz.
  Kütüphane çağrılmaz, yordamlar ders içinde yazılır.

#### Görüntü, Piksel ve Kanal

```python
# goruntu.py — MODELDIR. Goruntu kurgusu: M26/K06'nin 12x12 kapsama izgarasi
# burada tek kanalli, gri duzeyli kucuk bir goruntu yerine gecer. Her hucre bir
# pikseldir ve degeri 0-255 arasinda bir gri duzeydir.
import statistics

TOHUM, M32, BOY = 20260218, 0xFFFFFFFF, 12
EN_KUCUK, EN_BUYUK = 2, 6
RAMPA = " .:-=+*#%@"


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 goruntu(no):
    """Bir kapsama goruntusu: zemin, tek bir dikdortgen blok ve gurultu."""
    r = uretec(TOHUM + 700000 + no)
    zemin = 30 + int(r() * 70)
    karsitlik = 20 + int(r() * 36)
    yuk = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    while gen == yuk:
        gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    i = int((r() + r() + r()) / 3 * (BOY - yuk + 1))    # merkeze toplanan konum
    j = int((r() + r() + r()) / 3 * (BOY - gen + 1))
    g = [[0] * BOY for _ in range(BOY)]
    for a in range(BOY):
        for b in range(BOY):
            v = zemin + (karsitlik if i <= a < i + yuk and j <= b < j + gen else 0)
            v += int(r() * 61) - 30
            g[a][b] = 0 if v < 0 else (255 if v > 255 else v)
    return g, (i, j, yuk, gen), (1 if gen > yuk else 0)


def karistir(n, tohum):
    r, s = uretec(tohum), list(range(n))
    for i in range(n - 1, 0, -1):
        j = int(r() * (i + 1))
        s[i], s[j] = s[j], s[i]
    return s


def ciz(g):
    for satir in g:
        print("   " + "".join(RAMPA[v * len(RAMPA) // 256] for v in satir))


HAM = [goruntu(i) for i in range(400)]
VERI = [HAM[i] for i in karistir(400, TOHUM + 40000)]
EGT, DOG, SIN = VERI[:160], VERI[160:240], VERI[240:]
ortalamalar = [statistics.mean(v for s in g for v in s) for g, _, _ in VERI]

g0, k0, e0 = EGT[0]
print(f"ornek goruntu: blok satir {k0[0]}, sutun {k0[1]}, {k0[2]}x{k0[3]}, etiket {e0}")
ciz(g0)
print(f"{BOY}x{BOY} piksel = {BOY * BOY}, tek kanal; ayni goruntu uc kanalli olsaydi "
      f"{BOY * BOY * 3} sayi")
print(f"goruntu ortalamalari {min(ortalamalar):.1f} ile {max(ortalamalar):.1f} arasinda")
print(f"bolme {len(EGT)}/{len(DOG)}/{len(SIN)}")

ENSIK = max(sum(e for _, _, e in SIN), len(SIN) - sum(e for _, _, e in SIN)) / len(SIN)
print(f"alanin tabani, en sik sinif: {ENSIK:.4f}")
```

```
ornek goruntu: blok satir 4, sutun 2, 4x6, etiket 1
   :-:..::::::.
   ....:.::.:::
   :.::-.::.-:-
   ...-.:.::.:.
   ..=+==++:.-.
   --=---=--..:
   :.====---.-:
   :.=-==+=:..:
   .-::.:.-.:-:
   ::.:-:....::
   ::..:-::-:::
   .:-.:--:.-.:
12x12 piksel = 144, tek kanal; ayni goruntu uc kanalli olsaydi 432 sayi
goruntu ortalamalari 32.9 ile 108.0 arasinda
bolme 160/80/160
alanin tabani, en sik sinif: 0.5312
```

Örnek görüntüde blok dördüncü satırdan başlıyor, dört satır yüksekliğinde ve altı sütun
genişliğinde. Çizimde güçlükle seçiliyor: rampa 0-255 aralığına yayıldığı için hem zemin hem blok
aynı iki üç imgeye düşüyor. Sayı da bunu söylüyor — görüntü ortalamaları **32,9 ile 108,0**
arasında geziniyor, yani bir görüntüde bloğun içi, başka bir görüntüde zeminin kendisi kadar
parlaktır.

Bir görüntü 12x12 piksel ve tek kanal, yani **144** sayıdır; üç kanallı olsaydı **432** tutardı.
Kanal her piksel için ayrı ölçülen bir büyüklüktür ve sayıyı kendi adedince katlar. Sınamada en sık
sınıfı söylemek **0,5312** verir: alanın en ucuz tabanı budur.

#### Normalleştirme

```python
# onisleme.py — uc temsil ve iki yordam. Yordamlar ayni kalir, yalniz
# pikselin sayiya cevrilme bicimi degisir.
def ham_t(g):
    return g


def olcek_t(g):                                  # kume geneli olcekleme
    return [[v / 255 for v in s] for s in g]


def norm_t(g):                                   # goruntu basina normallestirme
    x = [v for s in g for v in s]
    m = sum(x) / len(x)
    sd = (sum((v - m) ** 2 for v in x) / len(x)) ** 0.5
    return [[(v - m) / sd for v in s] for s in g]


def parlak_kutu(x, esik):
    """Esik ustu piksellerin sinirlayici kutusu."""
    ak = [(a, b) for a in range(BOY) for b in range(BOY) if x[a][b] >= esik]
    if not ak:
        return None
    return (min(a for a, _ in ak), min(b for _, b in ak),
            max(a for a, _ in ak) - min(a for a, _ in ak) + 1,
            max(b for _, b in ak) - min(b for _, b in ak) + 1)


def esik_kurali(x, esik):
    k = parlak_kutu(x, esik)
    return 0 if k is None else (1 if k[3] > k[2] else 0)


def ortalama_goruntu(egt, don):
    """Alanin tabani: sinif ortalamalari, karar en yakin ortalamadir."""
    top = {0: [0.0] * (BOY * BOY), 1: [0.0] * (BOY * BOY)}
    say = {0: 0, 1: 0}
    for g, _, e in egt:
        x = [v for s in don(g) for v in s]
        for i in range(BOY * BOY):
            top[e][i] += x[i]
        say[e] += 1
    M = {e: [v / say[e] for v in top[e]] for e in (0, 1)}

    def karar(g):
        x = [v for s in don(g) for v in s]
        u0 = sum((x[i] - M[0][i]) ** 2 for i in range(BOY * BOY))
        u1 = sum((x[i] - M[1][i]) ** 2 for i in range(BOY * BOY))
        return 1 if u1 < u0 else 0
    return karar


def olc(veri, karar):
    return sum(1 for g, _, e in veri if karar(g) == e) / len(veri)


print("ayni goruntu, goruntu basina normallestirilmis; ayni rampa:")
ciz([[max(0, min(255, int((v + 2) * 51))) for v in s] for s in norm_t(g0)])

TEMSIL = (("ham piksel", ham_t, [100 + 10 * k for k in range(9)]),
          ("kume geneli olcekleme", olcek_t, [(100 + 10 * k) / 255 for k in range(9)]),
          ("goruntu basina normal.", norm_t, [0.6 + 0.15 * k for k in range(9)]))
print(f"\n{'temsil':<24}{'esik':>7}{'ort goruntu':>13}{'esik kurali':>13}")
for ad, don, adaylar in TEMSIL:
    en_iyi = max(adaylar, key=lambda t: olc(DOG, lambda g: esik_kurali(don(g), t)))
    print(f"{ad:<24}{en_iyi:>7.2f}{olc(SIN, ortalama_goruntu(EGT, don)):>13.4f}"
          f"{olc(SIN, lambda g: esik_kurali(don(g), en_iyi)):>13.4f}")
```

```
ayni goruntu, goruntu basina normallestirilmis; ayni rampa:
   ===..--:-:-.
   ..:.-::=:-==
   -.===:==:+-+
   ...=::.-=.=.
   :.#%##@%:.+:
   =+%+++%*+:.=
   -:%*%%+++.+:
   =.**%*%%=..:
   .=-:.-:+.=+=
   -=:-==:..::-
   ==..=+-=+-==
   :-+.==+=.+.=

temsil                     esik  ort goruntu  esik kurali
ham piksel               130.00       0.5500       0.6937
kume geneli olcekleme      0.51       0.5500       0.6937
goruntu basina normal.     1.65       0.4875       0.9250
```

Çizim tek başına yeterince şey söylüyor: her pikselden kendi görüntüsünün ortalaması çıkarılıp
kendi standart sapmasına bölündüğünde blok görünür oluyor. Izgara, blok ve gürültü aynıdır;
değişen yalnız sayıların ölçeğidir.

Tablonun ikinci satırı **sıfır** sonuç veriyor. Bütün pikselleri 255'e bölmek her iki yordamın da
her iki sayısını olduğu gibi bırakıyor: 0,5500 ve 0,6937. Her görüntüye **aynı** çarpanı uygulamak
ne en yakın ortalamayı ne eşik sıralamasını değiştirir; bu adım bir birim değişikliğidir.

Görüntü başına normalleştirme eşik kuralını **0,6937'den 0,9250'ye** taşıyor: fark **0,2313**.
Sabit bir eşik, zemini 33 olan bir görüntüde bloğu bulur, zemini 108 olan bir görüntüde zeminin
yarısını da bloğa katar; normalleştirmeden sonra "ortalamanın 1,65 standart sapma üstü" her
görüntüde aynı anlama gelir. Model değişmedi, veri değişmedi, yalnız **temsil** değişti.

Aynı temsil ortalama görüntü tabanını **0,5500'den 0,4875'e** düşürüyor. Bu bir çelişki değildir:
ortalama görüntü yordamı iki temsilde de tabanın çevresinde durur, çünkü blok her görüntüde başka
bir yerdedir ve ortalama alındığında yön silinir. Ham temsildeki 0,5500, en sık sınıfın 0,5312'sinin
yalnız **0,0188** üstüdür. Alanın tabanı burada bir alt sınır çizer, bir hedef değil.

#### Artırma ve Etiketi Bozan Dönüşüm

```python
# artirma.py — Artirma yalniz ogrenen bir yordamda olculebilir; esik kurali
# ogrenmez. Olcu araci en yakin komsudur ve burada yalnizca bir aractir.
def kaydir(g, di, dj):
    d = statistics.median(v for s in g for v in s)
    return [[g[a - di][b - dj] if 0 <= a - di < BOY and 0 <= b - dj < BOY else d
             for b in range(BOY)] for a in range(BOY)]


DONUSUM = (("kaydirma (1,1)", lambda g: kaydir(g, 1, 1)),
           ("yatay cevirme", lambda g: [s[::-1] for s in g]),
           ("dikey cevirme", lambda g: g[::-1]),
           ("ceyrek donus", lambda g: [[g[BOY - 1 - b][a] for b in range(BOY)]
                                       for a in range(BOY)]),
           ("parlaklik +25", lambda g: [[min(255, v + 25) for v in s] for s in g]))


def kutu_donusumu(k, ad):
    i, j, h, w = k
    if ad.startswith("kaydirma"):
        i, j = i + 1, j + 1
        h, w = min(h, BOY - i), min(w, BOY - j)
    elif ad == "yatay cevirme":
        j = BOY - j - w
    elif ad == "dikey cevirme":
        i = BOY - i - h
    elif ad == "ceyrek donus":
        i, j, h, w = j, BOY - i - h, w, h
    return (i, j, h, w)


print(f"{'donusum':<17}{'etiketi bozulan':>16}")
for ad, _ in DONUSUM:
    boz = sum(1 for _, k, e in EGT
              if (1 if kutu_donusumu(k, ad)[3] > kutu_donusumu(k, ad)[2] else 0) != e)
    print(f"{ad:<17}{f'{boz}/{len(EGT)}':>16}")


def ozet(g):                                 # normallestir, 2x2 ortalama havuzla
    x = [v for s in norm_t(g) for v in s]
    return [sum(x[(2 * a + p) * BOY + 2 * b + q] for p in (0, 1) for q in (0, 1)) / 4
            for a in range(6) for b in range(6)]


def en_yakin(depo, veri):
    d = 0
    for x, y in veri:
        t = min(depo, key=lambda u: sum((u[0][i] - x[i]) ** 2 for i in range(len(x))))
        d += 1 if t[1] == y else 0
    return d / len(veri)


SIN_O = [(ozet(g), e) for g, _, e in SIN]
print(f"\nkirk etiketle, iki ayri kirklik dilim (en sik sinif {ENSIK:.4f})")
print(f"{'kurulum':<36}{'ornek':>7}{'dilim 1':>9}{'dilim 2':>9}")
for ad, secim in (("artirmasiz", ()),
                  ("+ kaydirma", ("kaydirma (1,1)",)),
                  ("+ iki cevirme", ("yatay cevirme", "dikey cevirme")),
                  ("+ ceyrek donus, etiket korunmus", ("ceyrek donus",)),
                  ("+ ceyrek donus, etiket duzeltilmis", ("ceyrek donus*",))):
    say, sonuc = 0, []
    for bas in (0, 40):
        AZ = EGT[bas:bas + 40]
        depo = [(ozet(g), e) for g, _, e in AZ]
        for s in secim:
            f = dict(DONUSUM)[s.rstrip("*")]
            depo += [(ozet(f(g)), (1 - e) if s.endswith("*") else e) for g, _, e in AZ]
        say = len(depo)
        sonuc.append(en_yakin(depo, SIN_O))
    print(f"{ad:<36}{say:>7}{sonuc[0]:>9.4f}{sonuc[1]:>9.4f}")
```

```
donusum           etiketi bozulan
kaydirma (1,1)              1/160
yatay cevirme               0/160
dikey cevirme               0/160
ceyrek donus              160/160
parlaklik +25               0/160

kirk etiketle, iki ayri kirklik dilim (en sik sinif 0.5312)
kurulum                               ornek  dilim 1  dilim 2
artirmasiz                               40   0.5938   0.6250
+ kaydirma                               80   0.6625   0.6687
+ iki cevirme                           120   0.6875   0.6250
+ ceyrek donus, etiket korunmus          80   0.5188   0.5000
+ ceyrek donus, etiket duzeltilmis       80   0.6312   0.7063
```

Üst tablo bu dersin görüntüye özgü sayısıdır. Beş dönüşümün dördü etiketi olduğu gibi bırakıyor:
çevirmeler bloğu aynalar, boyutlarını değiştirmez; parlaklık geometriye dokunmaz; kaydırma yalnız
**1** örnekte, bloğun kenardan taşıp kırpıldığı örnekte bozuyor. Çeyrek dönüş ise **160 örneğin
160'ında** etiketi ters çeviriyor, çünkü yükseklikle genişliği yer değiştiriyor ve etiket tam
olarak bu ikisinin karşılaştırmasıdır.

Artırmanın görevden bağımsız bir listesi yoktur: aynı dönüşüm, etiketi bloğun **konumu** olan bir
görevde zararsız, etiketi bloğun **yönü** olan bir görevde yıkıcıdır. Alt tablo bedeli sayıyor. Kırk etiketle en yakın komşu artırmasız **0,5938** ve **0,6250**
okuyor. İki çevirme eklendiğinde birinci dilimde 0,6875, ikincisinde 0,6250; kaydırma
eklendiğinde 0,6625 ve 0,6687. Katkı birinci dilimde 0,0937'ye çıkıyor, ikincisinde 0,0437'de
kalıyor: iki dilim arasındaki fark, artırmanın kattığı farkla aynı büyüklüktedir. M27/K05'in eğitim
pratiği dersinde aynı katkı +0,0026, +0,0013 ve −0,0079 ölçülmüştü; ölçek büyüdükçe küçülür.

Etiketi bozan dönüşüm eklendiğinde sayı **0,5188** ve **0,5000** oluyor: artırmasız durumun
altında, en sık sınıfın 0,5312'sinin de altında. Aynı görüntüler etiketleri düzeltilerek
eklendiğinde 0,6312 ve 0,7063 okunuyor; iki satır arasındaki tek fark etiketin ne yazıldığıdır.
Dönüşümlerin **nereye** uygulandığı da kritiktir ve burada yalnız eğitim dilimine uygulanır.
M27/K05 artırmanın bölmeden önce yapılmasının ayrılmış küme sayısını +0,0203 kaydırdığını
ölçmüştü; o sızıntı burada tekrarlanmıyor.

#### Özet

- Görüntü 12x12 piksel ve tek kanaldır, yani 144 sayı; üç kanallı olsaydı 432 tutardı. Görüntü
  ortalamaları 32,9 ile 108,0 arasında gezinir.
- Alanın tabanı iki yordamdır: en sık sınıf 0,5312, ortalama görüntü 0,5500. Ortalama görüntü yönü
  okuyamaz, çünkü konum ortalandığında yön silinir.
- Küme geneli ölçekleme hiçbir sayıyı oynatmaz (0,5500 ve 0,6937 aynen kalır); bu adım bir ön
  işleme değil, bir birim değişikliğidir.
- Görüntü başına normalleştirme eşik kuralını 0,6937'den 0,9250'ye çıkarır; fark 0,2313'tür ve
  tümüyle temsilden gelir. Aynı temsil ortalama görüntüyü 0,5500'den 0,4875'e düşürür.
- Çeyrek dönüş 160 örneğin 160'ında etiketi ters çevirir, kaydırma 1'inde bozar, çevirmeler ve
  parlaklık hiçbirinde bozmaz.
- Kırk etiketle artırmasız 0,5938 ve 0,6250 okunur; iki çevirme 0,6875 ve 0,6250, etiketi korunmuş
  çeyrek dönüş 0,5188 ve 0,5000 verir — tabanın altı.

#### Sonraki Adım

Bu derste karar veren yordamlar ya hiç öğrenmiyordu (eşik kuralı) ya da eğitim kümesini olduğu gibi
saklıyordu (en yakın komşu). Eşik kuralının normalleştirilmiş temsilde okuduğu 0,9250, görevin
geometrisini **bilen** bir insanın yazdığı üç satırın sayısıdır. Sonraki ders o üç satırı kaldırıp
yerine öğrenen bir model koyar ve iki şey ölçer: modelin alanın tabanını ne kadar geçtiği ve etiket
sayısı yirmiye indiğinde başka bir görevden taşınan bir temsilin kaç örneğe bedel olduğu.

### Görüntü Sınıflandırma

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/goruntu-siniflandirma

Uçtan uca eğitimin ve öğrenme aktarımının alanın tabanına karşı ölçülmesi: en sık sınıf 0,5312 ve ortalama görüntü 0,5500 iken 1.169 parametreli ağ 144 pikselde iki koşumda da 0,6000, 305 parametreli ağ havuzlanmış 36 sayıda 0,6687 ve 0,7063 okuyor; ikisi de eğitim kümesini tamamen ezberliyor. Yirmi etiketle sıfırdan eğitim 0,5188 ve 0,5250 ile alanın tabanının altında kalırken kurgu bir kaynak görevden üretilen önceden eğitilmiş modelin dondurulması 0,6312 ve 0,5500, ince ayarı 0,5938 ve 0,5625 veriyor. Altmış etikette üstünlük kapanıyor, yüz altmışta sıfırdan eğitim 0,6125 ve 0,6875 ile öne geçiyor; dondurmanın iki koşumu arasındaki 0,0812'lik açıklık aktarımın kattığı farktan büyüktür.

Önceki dersin en yüksek sayısı bir modelden gelmedi. Görüntü başına normalleştirilmiş temsilde,
eşik üstü piksellerin sınırlayıcı kutusunu çıkarıp yüksekliğiyle genişliğini karşılaştıran üç
satırlık bir kural sınamada 0,9250 okudu. O kuralı yazabilmek için görevin geometrisini bilmek
gerekiyordu: etiketin bloğun yönü olduğunu, bloğun tek olduğunu, gürültünün eşiğin altında
kaldığını.

Bu ders o bilgiyi geri alır. Kural silinir, yerine etiketli örneklerden öğrenen bir model konur ve
iki soru sorulur. Birincisi, model alanın tabanını ne kadar geçiyor. İkincisi, etiket sayısı yirmiye
indiğinde ne oluyor — ve **başka bir görevde** eğitilmiş bir modelin taşıdığı temsil, kaç etiketli
örneğe bedel.

- **BG9. Görüntü kurgusu önceki dersteki ile aynıdır:** 12x12 tek kanallı gri düzeyli görüntü, tek
  dikdörtgen blok, etiket bloğun yönü, tohum 20260218, bölme 160/80/160.
- **BG10. Alanın tabanı iki yordamdır:** en sık sınıf ve **ortalama görüntü**. İkincisi ham
  piksellerde ölçülür ve bu kümede 0,5500 verir.
- **BG11. Model bir gizli katmanlı küçük bir ağdır** ve ders içinde yazılır. Sekiz gizli birim,
  çıkış sigmoit, güncelleme örnek başına, yüz tur.
- **BG12. Her kurulum iki kez koşulur.** İkinci koşumda yalnız başlangıç değerleri ve karıştırma
  sırası değişir; veri, bölme, tur sayısı ve öğrenme adımı aynıdır.
- **BG13. Havuzlama ve evrişim burada kurulmaz.** 2x2 ortalama havuzlama M27/K05'te ölçülmüş bir
  işlemdir ve bu derste yalnız bir **girdi temsili** olarak kullanılır.
- **BG14. Kaynak görev kurgudur ve hedef görevden ayrıdır:** başka 240 görüntü, "blok geniş mi"
  sorusu. Önceden eğitilmiş model bu görevden **kendi elimizle** üretilir; hedef görevin hiçbir
  etiketini ve hiçbir görüntüsünü görmez.
- **BG15. Dondurma** gizli katmanın kaynaktan alınıp değiştirilmemesi, **ince ayar** aynı katmanın
  hedef görevde eğitilmeye devam etmesidir. İkisinde de çıkış katmanı yeniden kurulur.

#### Alanın Tabanı ve Temsil

```python
# veri.py — MODELDIR. Onceki dersin goruntu kurgusu aynen surer: 12x12 tek
# kanalli gri duzeyli goruntu, tek dikdortgen blok, etiket blogun yonu.
TOHUM, M32, BOY = 20260218, 0xFFFFFFFF, 12
EN_KUCUK, EN_BUYUK, GIZ = 2, 6, 8


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 goruntu(no):
    r = uretec(TOHUM + 700000 + no)
    zemin, karsitlik = 30 + int(r() * 70), 20 + int(r() * 36)
    yuk = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    while gen == yuk:
        gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    i = int((r() + r() + r()) / 3 * (BOY - yuk + 1))
    j = int((r() + r() + r()) / 3 * (BOY - gen + 1))
    g = [[0] * BOY for _ in range(BOY)]
    for a in range(BOY):
        for b in range(BOY):
            v = zemin + (karsitlik if i <= a < i + yuk and j <= b < j + gen else 0)
            v += int(r() * 61) - 30
            g[a][b] = 0 if v < 0 else (255 if v > 255 else v)
    return g, (i, j, yuk, gen), (1 if gen > yuk else 0)


def karistir(n, tohum):
    r, s = uretec(tohum), list(range(n))
    for i in range(n - 1, 0, -1):
        j = int(r() * (i + 1))
        s[i], s[j] = s[j], s[i]
    return s


HAM = [goruntu(i) for i in range(400)]
VERI = [HAM[i] for i in karistir(400, TOHUM + 40000)]
EGT, DOG, SIN = VERI[:160], VERI[160:240], VERI[240:]


def duz(g):
    return [v for s in g for v in s]


def norm_t(g):                                   # goruntu basina normallestirme
    x = duz(g)
    m = sum(x) / len(x)
    sd = (sum((v - m) ** 2 for v in x) / len(x)) ** 0.5
    return [(v - m) / sd for v in x]


def ozet(g):                                     # normallestir, 2x2 ortalama havuzla
    x = norm_t(g)
    return [sum(x[(2 * a + p) * BOY + 2 * b + q] for p in (0, 1) for q in (0, 1)) / 4
            for a in range(6) for b in range(6)]


def ortalama_goruntu(egt, sin):
    """Alanin tabani: sinif ortalamalari, karar en yakin ortalamadir."""
    M = {}
    for e in (0, 1):
        alt = [x for x, y in egt if y == e]
        M[e] = [sum(a[i] for a in alt) / len(alt) for i in range(len(alt[0]))]

    def uzak(x, e):
        return sum((x[i] - M[e][i]) ** 2 for i in range(len(x)))
    return sum(1 for x, y in sin if (1 if uzak(x, 1) < uzak(x, 0) else 0) == y) / len(sin)


ENSIK = max(sum(e for _, _, e in SIN), len(SIN) - sum(e for _, _, e in SIN)) / len(SIN)
TABAN = ortalama_goruntu([(duz(g), e) for g, _, e in EGT],
                         [(duz(g), e) for g, _, e in SIN])
print(f"bolme {len(EGT)}/{len(DOG)}/{len(SIN)}, girdi {BOY * BOY} piksel; "
      f"2x2 havuzlamadan sonra {len(ozet(EGT[0][0]))} sayi")
print(f"alanin tabani, en sik sinif : {ENSIK:.4f}")
print(f"alanin tabani, ortalama goruntu: {TABAN:.4f}")
```

```
bolme 160/80/160, girdi 144 piksel; 2x2 havuzlamadan sonra 36 sayi
alanin tabani, en sik sinif : 0.5312
alanin tabani, ortalama goruntu: 0.5500
```

Ortalama görüntü yordamı iki sınıfın ortalama görüntüsünü tutar ve yeni görüntüyü hangisine daha
yakınsa oraya yazar. Toplam 288 sayı saklar, hiçbir yineleme yapmaz, hiçbir ayar değişkeni
istemez. Bu alanın en aptal yordamıdır ve **0,5500** okur; en sık sınıfın 0,5312'sinden 0,0188
yüksek. Bundan sonraki her sayı bu ikisiyle birlikte okunur.

Bu derste doğrulama kümesine bakılmıyor. Tur sayısı, öğrenme adımı ve gizli birim sayısı bütün
kurulumlarda aynı tutuluyor; hiçbir süpürme yapılmıyor. Bunun nedeni ölçünün ne olduğudur: sorulan
soru "en iyi ağ hangisi" değil, "girdi temsilini ya da başlangıç ağırlıklarını değiştirmek aynı
bütçede sayıyı ne kadar oynatıyor". Ayar bütçesi kurulumlar arasında değişseydi fark ayardan mı
temsilden mi geldiği okunamazdı.

#### Uçtan Uca Eğitim

```python
# ag.py — MODELDIR. Bir gizli katmanli kucuk bir ag, ders icinde yazilir.
# Cikis sigmoit, guncelleme ornek basina, kayip capraz duzensizlik.
import math


def kur(D, tohum):
    r, a = uretec(tohum), (1 / D) ** 0.5
    return [[[(r() * 2 - 1) * a for _ in range(D)] for _ in range(GIZ)], [0.0] * GIZ,
            [(r() * 2 - 1) * (1 / GIZ) ** 0.5 for _ in range(GIZ)], [0.0]]


def ileri(P, x):
    W, b, v, c = P
    h = [max(0.0, b[k] + sum(W[k][i] * x[i] for i in range(len(x)))) for k in range(GIZ)]
    z = c[0] + sum(v[k] * h[k] for k in range(GIZ))
    return h, (1 / (1 + math.exp(-z)) if z > -30 else 0.0)


def egit(P, veri, tur, gadim, tohum, gizli=True):
    W, b, v, c = P
    r, n, D = uretec(tohum), len(veri), len(veri[0][0])
    for _ in range(tur):
        s = list(range(n))
        for i in range(n - 1, 0, -1):
            j = int(r() * (i + 1))
            s[i], s[j] = s[j], s[i]
        for idx in s:
            x, y = veri[idx]
            h, p = ileri(P, x)
            for k in range(GIZ):
                if gizli and h[k] > 0.0:
                    dh = (p - y) * v[k]
                    b[k] -= gadim * dh
                    for i in range(D):
                        W[k][i] -= gadim * dh * x[i]
                v[k] -= gadim * (p - y) * h[k]
            c[0] -= gadim * (p - y)
    return P


def dogruluk(P, veri):
    return sum(1 for x, y in veri if (ileri(P, x)[1] >= 0.5) == (y == 1)) / len(veri)


def kume(don, veri):
    return [(don(g), e) for g, _, e in veri]


print(f"{'girdi':<22}{'parametre':>10}{'kosum':>7}{'egitim':>8}{'sinama':>8}")
print(f"{'en sik sinif':<22}{0:>10}{'-':>7}{'-':>8}{ENSIK:>8.4f}")
print(f"{'ortalama goruntu':<22}{2 * BOY * BOY:>10}{'-':>7}{'-':>8}{TABAN:>8.4f}")
for ad, don, D in (("144 piksel", norm_t, BOY * BOY), ("36 sayi (havuzlanmis)", ozet, 36)):
    E, S = kume(don, EGT), kume(don, SIN)
    for t in (0, 1):
        P = egit(kur(D, TOHUM + 11 + t), E, 100, 0.05, TOHUM + 511 + t)
        print(f"{ad if t == 0 else '':<22}{D * GIZ + 2 * GIZ + 1 if t == 0 else '':>10}"
              f"{t + 1:>7}{dogruluk(P, E):>8.4f}{dogruluk(P, S):>8.4f}")
```

```
girdi                  parametre  kosum  egitim  sinama
en sik sinif                   0      -       -  0.5312
ortalama goruntu             288      -       -  0.5500
144 piksel                  1169      1  1.0000  0.6000
                                      2  1.0000  0.6000
36 sayi (havuzlanmis)        305      1  1.0000  0.6687
                                      2  1.0000  0.7063
```

Dört satırın hepsinde eğitim doğruluğu **1,0000**. Yüz altmış görüntü 144 boyutlu bir uzayda
birbirine benzemez; ağ hepsini ayrı ayrı ezberleyecek kadar geniştir ve ezberlemek, yönün ne
olduğunu öğrenmekten kolaydır. Sınama sayıları bunun karşılığıdır: **0,6000** ve **0,6000**.

Girdiyi 144 sayıdan 36 sayıya indirmek — 2x2 pencerelerin ortalamasını almak — sınama sayısını
**0,6687** ve **0,7063**'e çıkarıyor. Parametre sayısı 1.169'dan **305**'e düşüyor. Fark bir
eniyileme kazancı değil, bir varsayımdır: havuzlama "bir pikselin tek başına değeri değil,
komşularıyla birlikte ortalaması önemlidir" der ve bu kurguda doğrudur, çünkü blok tek bir pikselle
değil bitişik bir bölgeyle tanımlıdır.

İki koşum arasındaki açıklık havuzlanmış girdide **0,0376**'dır. Aynı ağın, aynı verinin ve aynı
bütçenin yalnız başlangıç değerleri değişerek açtığı bu aralık, havuzlamanın kattığı 0,0875'lik
farkın yarısı kadardır. Elle yazılmış eşik kuralının 0,9250'si hâlâ çok uzaktadır ve bu ağın
kusuru değil, ölçünün kendisidir: kural görevin geometrisini biliyor, ağ onu yüz altmış örnekten
çıkarmak zorunda.

#### Öğrenme Aktarımı

```python
# aktarim.py — MODELDIR. Onceden egitilmis model KURGU bir kaynak gorevden
# kendi elimizle uretilir: kaynak gorev "blok genis mi" sorusudur, hedef
# gorevin hicbir etiketini gormez ve hedef goruntulerin hicbirini kullanmaz.
KAYNAK = [goruntu(1000 + i) for i in range(240)]
KVERI = [(ozet(g), 1 if k[3] >= 4 else 0) for g, k, _ in KAYNAK]
ON = [egit(kur(36, TOHUM + 21 + t), KVERI, 100, 0.05, TOHUM + 521 + t) for t in (0, 1)]
print(f"kaynak gorev: {len(KVERI)} goruntu, etiket 1 orani "
      f"{sum(y for _, y in KVERI) / len(KVERI):.4f}, kaynak gorevde dogruluk "
      f"{dogruluk(ON[0], KVERI):.4f} ve {dogruluk(ON[1], KVERI):.4f}")


def aktar(P, tohum):
    """Gizli katman kaynaktan alinir; cikis katmani yeniden kurulur."""
    r, (W, b, _, _) = uretec(tohum), P
    return [[s[:] for s in W], b[:],
            [(r() * 2 - 1) * (1 / GIZ) ** 0.5 for _ in range(GIZ)], [0.0]]


E36, S36 = kume(ozet, EGT), kume(ozet, SIN)
print(f"\n{'etiket':>7}{'sifirdan':>19}{'dondurma':>19}{'ince ayar':>19}")
print(f"{'':>7}{'kosum 1  kosum 2':>19}{'kosum 1  kosum 2':>19}{'kosum 1  kosum 2':>19}")
for n in (20, 60, 160):
    satir = f"{n:>7}"
    for kurulum in ("sifirdan", "dondurma", "ince ayar"):
        for t in (0, 1):
            if kurulum == "sifirdan":
                P = kur(36, TOHUM + 31 + t)
            else:
                P = aktar(ON[t], TOHUM + 41 + t)
            P = egit(P, E36[:n], 100, 0.05, TOHUM + 531 + t,
                     gizli=(kurulum != "dondurma"))
            satir += f"{dogruluk(P, S36):>9.4f}" if t else f"{dogruluk(P, S36):>10.4f}"
    print(satir)
print(f"alanin tabani: en sik sinif {ENSIK:.4f}, ortalama goruntu {TABAN:.4f}")
```

```
kaynak gorev: 240 goruntu, etiket 1 orani 0.6292, kaynak gorevde dogruluk 1.0000 ve 0.9958

 etiket           sifirdan           dondurma          ince ayar
          kosum 1  kosum 2   kosum 1  kosum 2   kosum 1  kosum 2
     20    0.5188   0.5250    0.6312   0.5500    0.5938   0.5625
     60    0.6188   0.6625    0.5938   0.6250    0.6188   0.6250
    160    0.6125   0.6875    0.6000   0.5625    0.6188   0.6562
alanin tabani: en sik sinif 0.5312, ortalama goruntu 0.5500
```

Önceden eğitilmiş model burada bir depodan indirilmiyor, kurgu bir kaynak görevden üretiliyor.
Kaynak görev, hedeften farklı 240 görüntü üzerinde "blok geniş mi" sorusudur ve bu görevin etiketi
boldur. Gizli katmanın orada öğrendiği şey, bloğun **yatay uzanımını** okumaktır.

Yirmi etiketle sıfırdan eğitim **0,5188** ve **0,5250** okuyor: en sık sınıfın 0,5312'sinin ve
ortalama görüntünün 0,5500'ünün **altında**. Aktarım aynı yirmi etiketle dondurmada 0,6312 ve
0,5500, ince ayarda 0,5938 ve 0,5625 veriyor. Ortalamalar üzerinden aktarımın kattığı fark
dondurmada **+0,0687**, ince ayarda **+0,0562**.

Altmış etikette üstünlük kapanıyor (sıfırdan 0,6406, dondurma 0,6094, ince ayar 0,6219), yüz
altmışta sıfırdan eğitim **0,6500** ile öne geçiyor ve dondurma 0,5812'de kalıyor. Sorunun ikinci
yarısı — kaç örnekle — bu üç satırdan okunur: aktarımın üstünlüğü yirmi ile altmış etiket arasında
tükeniyor. Kırk etiketlik bir aralık, bu kurguda önceden eğitilmiş bir modelin bütün değeridir.

Nedeni kaynak görevin ne öğrettiğindedir. "Blok geniş mi" sorusu gizli katmana bloğun **yatay**
uzanımını okumayı öğretir; hedef görev ise yatay uzanımın **dikey** uzanımdan büyük olup olmadığını
sorar. Kaynak, gereken iki ölçünün birini taşır, karşılaştırmayı taşımaz. Dondurulmuş bir katman
veri arttıkça yerinde sayar, çünkü öğrenebileceği şey kaynak görevde donmuştur. M27/K05'in
öğrenme aktarımı dersinde aynı desen bir tabloda ölçülmüştü: taban 0,6444 iken yirmi etiketle
sıfırdan 0,7194, dondurma 0,8417, ince ayar 0,8083; ve dondurma dört ölçümde de düz durmuştu.
Görüntüde ölçülen desen aynı, aradaki farklar daha küçüktür.

Bir sayı bu tablonun okunmasını sınırlıyor. Dondurmanın yirmi etiketteki iki koşumu 0,6312 ile
0,5500, aralarındaki açıklık **0,0812**. Bu, aktarımın kattığı 0,0687'lik farktan **büyüktür**.
Tek bir koşumun sayısını yazmak aktarımı olduğundan güçlü ya da olduğundan zayıf gösterirdi; iki
koşum, farkın işaretine güvenilebileceğini ama büyüklüğüne güvenilemeyeceğini söylüyor.

#### Özet

- Alanın tabanı bu görevde en sık sınıf 0,5312 ve ortalama görüntü 0,5500'dür; ikincisi 288 sayı
  saklar ve hiçbir yineleme yapmaz.
- 1.169 parametreli ağ 144 pikselde iki koşumda da 0,6000 okur; 305 parametreli ağ havuzlanmış 36
  sayıda 0,6687 ve 0,7063 okur. Dördü de eğitim kümesini 1,0000 ile ezberler.
- Havuzlamanın kattığı 0,0875'lik fark temsilden gelir; aynı ağın iki koşumu arasındaki açıklık
  0,0376'dır ve bu farkın yarısı kadardır.
- Yirmi etiketle sıfırdan eğitim 0,5188 ve 0,5250 ile alanın tabanının altında kalır; kurgu bir
  kaynak görevden üretilen modelin dondurulması +0,0687, ince ayarı +0,0562 katar.
- Altmış etikette üstünlük kapanır, yüz altmışta sıfırdan eğitim 0,6500 ile öne geçer ve dondurma
  0,5812'de kalır.
- Dondurmanın yirmi etiketteki iki koşumu arasındaki 0,0812'lik açıklık, aktarımın kattığı farktan
  büyüktür.

#### Sonraki Adım

Bu iki derste soru hep aynıydı: görüntüde **ne var**. Cevap tek bir sayıydı ve modelin bloğu
bulması gerekmiyordu, yalnız yönünü söylemesi yeterliydi. Oysa kurgunun içinde bir kutu duruyor:
her görüntüde bloğun satırı, sütunu, yüksekliği ve genişliği yazılı. Sonraki ders soruyu
değiştirir — nesne **nerede**. Bu, yeni bir ölçüt gerektirir, çünkü iki kutunun ne kadar tuttuğunu
doğruluk söyleyemez. Ve alanın tabanı da değişir: her görüntüye bakmadan aynı kutuyu söyleyen bir
yordamın o ölçütte kaç aldığı, bu kursun en şaşırtıcı sayısıdır.

### Nesne Tespiti

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/nesne-tespiti

Örtüşme oranının ve eşiğinin, hiçbir görüntüye bakmayan bir yordamla birlikte okunması: ızgaranın ortasına konan 4x4'lük sabit bir kutu ortalama 0,3011 örtüşme alıyor ve 0,3 eşiğinde sınama görüntülerinin 0,5125'inde tespit sayılıyor, ama eşik 0,5'te 0,1938'e, 0,7'de 0,0125'e düşüyor. Yalnız konum arayan 81 adaylı sabit boyutlu pencere 0,5687 ortalama ile 0,9750, 0,6875 ve 0,2375; boyutu da arayan 2.025 adaylı pencere 0,9076 ortalama ile 0,9812, 0,9625 ve 0,8500 veriyor. İki yordam 0,3 eşiğinde 0,0062 ile ayrılıyor, 0,7 eşiğinde aradaki fark 0,6125'e çıkıyor. Güven eşiği doğrulama kümesinin dörtte birlik puanına çekildiğinde kesinlik 0,9812'den 1,0000'e çıkıyor, duyarlılık 0,7063'e iniyor.

İki derste soru hep aynıydı: görüntüde **ne var**. Cevap tek bir sayıydı ve modelin bloğu bulması
gerekmiyordu, yalnız yönünü söylemesi yeterliydi. Oysa kurgunun içinde bir kutu duruyor: her
görüntüde bloğun satırı, sütunu, yüksekliği ve genişliği yazılı. Bu ders soruyu değiştirir —
nesne **nerede**.

Soru değişince ölçüt de değişir. Doğruluk iki kutunun ne kadar tuttuğunu söyleyemez, çünkü cevap
doğru ya da yanlış değil, **kısmen doğrudur**: tahmin edilen kutu gerçek kutuyu bir hücre kaçırmış
da olabilir, yarısını kapsamış da. Bu dersin ilk işi bu kısmiliği tek bir sayıya çeviren ölçütü
kurmak, ikinci işi o sayının **kendi başına** ne kadar yanıltıcı olduğunu göstermektir.

- **BG16. Görüntü kurgusu değişmedi;** değişen, kullanılan alandır. Etiket yerine her görüntünün
  **gerçek kutusu** okunur: satır, sütun, yükseklik, genişlik.
- **BG17. Her görüntüde tam olarak bir nesne vardır.** Bu, görevi saf bir **yer belirleme**
  problemi yapar; **tespit**, yer belirlemeye bir de "nesne var mı, kutu yayımlanmalı mı" kararının
  eklenmesidir ve son bölümde eklenir.
- **BG18. Ölçüt örtüşme oranıdır:** iki **sınırlayıcı kutunun** kesişim alanının birleşim
  alanına bölümü. Sıfır
  hiç değmemek, bir tıpatıp örtüşmektir. Yönü **büyük iyidir**.
- **BG19. Bir örtüşme eşiği seçilmeden başarı sayılamaz.** Eşik 0,3, 0,5 ve 0,7'de ayrı ayrı
  okunur ve üçü de basılır.
- **BG20. Alanın tabanı sabit kutudur:** eğitim kümesindeki ortalama kutu boyutunda, ızgaranın
  ortasına konan tek bir kutu, her görüntü için aynen söylenir. Bu yordam görüntüye **hiç bakmaz**.
- **BG21. Kesinlik ve duyarlılık M27/K03'te tanımlandı** ve tekrarlanmaz. Bu derste eklenen tek
  şey, bir tahminin doğru sayılması için gereken **örtüşme eşiğidir**.
- **BG22. Güven eşiği adayları doğrulama kümesinin puanlarından okunur;** sınama kümesi yalnız
  raporlama için kullanılır.

#### Örtüşme Oranı ve Sabit Kutu

```python
# kutu.py — MODELDIR. Ayni goruntu kurgusu; bu derste etiket degil, her
# goruntunun GERCEK KUTUSU kullanilir: (satir, sutun, yukseklik, genislik).
import statistics

TOHUM, M32, BOY = 20260218, 0xFFFFFFFF, 12
EN_KUCUK, EN_BUYUK = 2, 6


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 goruntu(no):
    r = uretec(TOHUM + 700000 + no)
    zemin, karsitlik = 30 + int(r() * 70), 20 + int(r() * 36)
    yuk = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    while gen == yuk:
        gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    i = int((r() + r() + r()) / 3 * (BOY - yuk + 1))
    j = int((r() + r() + r()) / 3 * (BOY - gen + 1))
    g = [[0] * BOY for _ in range(BOY)]
    for a in range(BOY):
        for b in range(BOY):
            v = zemin + (karsitlik if i <= a < i + yuk and j <= b < j + gen else 0)
            v += int(r() * 61) - 30
            g[a][b] = 0 if v < 0 else (255 if v > 255 else v)
    return g, (i, j, yuk, gen), (1 if gen > yuk else 0)


def karistir(n, tohum):
    r, s = uretec(tohum), list(range(n))
    for i in range(n - 1, 0, -1):
        j = int(r() * (i + 1))
        s[i], s[j] = s[j], s[i]
    return s


HAM = [goruntu(i) for i in range(400)]
VERI = [HAM[i] for i in karistir(400, TOHUM + 40000)]
EGT, DOG, SIN = VERI[:160], VERI[160:240], VERI[240:]


def ortusme(a, b):
    """Ortusme orani: kesisim alani bolu birlesim alani."""
    di = max(0, min(a[0] + a[2], b[0] + b[2]) - max(a[0], b[0]))
    dj = max(0, min(a[1] + a[3], b[1] + b[3]) - max(a[1], b[1]))
    kes = di * dj
    return kes / (a[2] * a[3] + b[2] * b[3] - kes)


def icinde(k, a, b):
    return k[0] <= a < k[0] + k[2] and k[1] <= b < k[1] + k[3]


sy = round(statistics.mean(k[2] for _, k, _ in EGT))
sx = round(statistics.mean(k[3] for _, k, _ in EGT))
SABIT = ((BOY - sy) // 2, (BOY - sx) // 2, sy, sx)
ESIKLER = (0.3, 0.5, 0.7)


def rapor(ad, kutular):
    o = [ortusme(k, g) for k, (_, g, _) in zip(kutular, SIN)]
    print(f"{ad:<32}{statistics.mean(o):>10.4f}"
          + "".join(f"{sum(1 for v in o if v >= e) / len(o):>10.4f}" for e in ESIKLER))
    return o


g0, k0, _ = SIN[0]
print(f"egitim kumesinde ortalama kutu {sy}x{sx}; sabit kutu {SABIT}")
print(f"ornek: gercek kutu {k0}; X kesisim, g yalniz gercek, s yalniz sabit")
for a in range(BOY):
    print("   " + "".join("Xgs."[(0 if icinde(SABIT, a, b) else 1)
                                 if icinde(k0, a, b)
                                 else (2 if icinde(SABIT, a, b) else 3)]
                          for b in range(BOY)))
print(f"bu ornekte ortusme orani {ortusme(SABIT, k0):.4f}")
print(f"\n{'alanin tabani':<32}{'ort ortusme':>10}"
      + "".join(f"{'esik ' + str(e):>10}" for e in ESIKLER))
SABIT_O = rapor("sabit kutu (goruntuye bakmaz)", [SABIT] * len(SIN))
```

```
egitim kumesinde ortalama kutu 4x4; sabit kutu (4, 4, 4, 4)
ornek: gercek kutu (3, 6, 6, 5); X kesisim, g yalniz gercek, s yalniz sabit
   ............
   ............
   ............
   ......ggggg.
   ....ssXXggg.
   ....ssXXggg.
   ....ssXXggg.
   ....ssXXggg.
   ......ggggg.
   ............
   ............
   ............
bu ornekte ortusme orani 0.2105

alanin tabani                   ort ortusme  esik 0.3  esik 0.5  esik 0.7
sabit kutu (goruntuye bakmaz)       0.3011    0.5125    0.1938    0.0125
```

Çizim ölçütün tanımını hücre hücre gösteriyor. Kesişim 8 hücre, birleşim ise gerçek kutunun 30
hücresiyle sabit kutunun 16 hücresinin toplamından kesişim çıkarılarak 38 hücre; oran
$8/38 = 0{,}2105$. Bu tek bir örnektir ve kutular oldukça kaymıştır.

Alt satır bu kursun ikinci iddiasının ödendiği yerdir. Sabit kutu hiçbir görüntüye bakmaz, hiçbir
piksel okumaz, hiçbir şey öğrenmez: eğitim kümesinden aldığı tek bilgi ortalama kutu boyutudur ve
konumu ızgaranın ortasıdır. Bu yordam ortalama **0,3011** örtüşme alıyor ve **0,3 eşiğinde sınama
görüntülerinin 0,5125'inde tespit sayılıyor** — yarısından fazlasında.

Sayının kaynağı ölçütte değil kurgudadır ve kurgu bunu bilerek taşıyor. Bloğun konumu üç bağımsız
çekimin ortalamasıyla seçildiği için nesneler ızgaranın ortasına toplanıyor. Gerçek görüntü
kümelerinde de nesne çoğunlukla ortadadır ve bu, hiçbir şey öğrenmemiş bir yordamın örtüşme
ölçütünde iyi görünmesine yeter. Eşik yükseltildiğinde aynı yordam **0,1938** ve **0,0125**'e
düşüyor: aynı kutu, aynı sınama kümesi, tek değişen okuma eşiği.

#### Aramanın Kattığı Fark

```python
# pencere.py — MODELDIR. Kayan pencere: her aday kutunun puani, icindeki
# normallestirilmis piksellerin toplaminin alanin karekokune bolunmesidir.
# Toplamlar birikimli toplam tablosundan sabit surede okunur.
def norm_t(g):
    x = [v for s in g for v in s]
    m = sum(x) / len(x)
    sd = (sum((v - m) ** 2 for v in x) / len(x)) ** 0.5
    return [[(v - m) / sd for v in s] for s in g]


def toplam_tablo(x):
    T = [[0.0] * (BOY + 1) for _ in range(BOY + 1)]
    for a in range(BOY):
        for b in range(BOY):
            T[a + 1][b + 1] = x[a][b] + T[a][b + 1] + T[a + 1][b] - T[a][b]
    return T


def ara(x, boyutlar):
    T, en, kutu = toplam_tablo(x), None, SABIT
    for h, w in boyutlar:
        kok = (h * w) ** 0.5
        for a in range(BOY - h + 1):
            for b in range(BOY - w + 1):
                p = (T[a + h][b + w] - T[a][b + w] - T[a + h][b] + T[a][b]) / kok
                if en is None or p > en:
                    en, kutu = p, (a, b, h, w)
    return kutu, en


TEK = [(SABIT[2], SABIT[3])]
TUM = [(h, w) for h in range(EN_KUCUK, EN_BUYUK + 1)
       for w in range(EN_KUCUK, EN_BUYUK + 1)]
SIN_N = [norm_t(g) for g, _, _ in SIN]


def aday_sayisi(boyutlar):
    return sum((BOY - h + 1) * (BOY - w + 1) for h, w in boyutlar)


print(f"{'yordam':<32}{'ort ortusme':>10}"
      + "".join(f"{'esik ' + str(e):>10}" for e in ESIKLER))
rapor("sabit kutu (goruntuye bakmaz)", [SABIT] * len(SIN))
rapor("sabit boyutlu kayan pencere", [ara(x, TEK)[0] for x in SIN_N])
TAM = [ara(x, TUM) for x in SIN_N]
rapor("boyutu da arayan pencere", [k for k, _ in TAM])
print(f"aday kutu sayisi: sabit boyutlu {aday_sayisi(TEK)}, "
      f"boyutu da arayan {aday_sayisi(TUM)}")
```

```
yordam                          ort ortusme  esik 0.3  esik 0.5  esik 0.7
sabit kutu (goruntuye bakmaz)       0.3011    0.5125    0.1938    0.0125
sabit boyutlu kayan pencere         0.5687    0.9750    0.6875    0.2375
boyutu da arayan pencere            0.9076    0.9812    0.9625    0.8500
aday kutu sayisi: sabit boyutlu 81, boyutu da arayan 2025
```

İki yordam arasındaki tek fark aranan şeydir. Sabit boyutlu pencere yalnız **konumu** arar: kutunun
boyu eğitim kümesinin ortalamasına sabitlenmiştir ve 81 konum denenir. İkincisi **boyutu da** arar
ve 2.025 aday değerlendirir. Ortalama örtüşme 0,5687'den **0,9076**'ya çıkıyor; 25 kat daha büyük
bir arama uzayı 0,3389 katıyor.

Asıl sayı satırlarda değil, sütunlar arasındaki farktadır. **0,3 eşiğinde** iki pencere 0,9750 ile
0,9812 okuyor; aralarındaki fark **0,0062**, yani hiç yok sayılabilir. **0,7 eşiğinde** aynı iki
yordam 0,2375 ile 0,8500 okuyor; fark **0,6125**. Aynı iki yordam, aynı sınama kümesi, aynı ölçüt
ailesi — yalnız eşik değişiyor ve biri "neredeyse eşit", öteki "üç buçuk kat üstün" oluyor.

Eşiğin ne anlama geldiği de yordamdan yordama değişiyor. Sabit boyutlu pencere nesneyi bulur ama
boyunu tutturamaz: doğru konumda duran 4x4'lük bir kutu, gerçek kutu 6x5 olduğunda kesişimi en çok
16 hücre yapabilir ve birleşim 30 hücre kalır, yani örtüşme $16/30 = 0{,}5333$'ü aşamaz ve 0,7
eşiğini **yapısal olarak** geçemez. Düşük eşik bu kusuru tümüyle gizler. Bir örtüşme sayısı, hangi
eşikte okunduğu yazılmadan taşınamaz.

Puanın biçimi de bir karardır ve ölçülebilir bir sonucu vardır. Aday kutuların ham piksel toplamına
bakılsaydı arama en büyük kutuyu seçerdi, çünkü zemin pikselleri ortalamada sıfır olsa da toplam
kutu büyüdükçe artan gürültüyle şişer; kutu içindeki **ortalamaya** bakılsaydı arama tek bir parlak
gürültü hücresini seçerdi, çünkü en yüksek ortalamayı en küçük kutu verir. Toplamı alanın karekökune
bölmek bu iki eğilimi dengeler: puan, bölgenin gürültüye göre ne kadar öne çıktığını ölçer.

#### Güven Eşiği, Kesinlik ve Duyarlılık

```python
# guven.py — Yordamlar simdiye kadar her goruntude bir kutu yayimladi. Puan
# bir guven esiginin altindayken kutu yayimlanmazsa kesinlik ile duyarlilik
# ayrisir. Esik adaylari DOGRULAMA kumesinin puanlarindan okunur.
KUTULAR, PUANLAR = [k for k, _ in TAM], [p for _, p in TAM]
DOG_P = sorted(ara(norm_t(g), TUM)[1] for g, _, _ in DOG)
ADAYLAR = [("hepsi", 0.0)] + [(f"dorttebir {q}", DOG_P[len(DOG_P) * q // 4])
                              for q in (1, 2, 3)]


def kesinlik_duyarlilik(guven, esik):
    yayin = [(k, g) for k, p, (_, g, _) in zip(KUTULAR, PUANLAR, SIN) if p >= guven]
    dogru = sum(1 for k, g in yayin if ortusme(k, g) >= esik)
    return (dogru / len(yayin) if yayin else 0.0), dogru / len(SIN)


print(f"{'guven esigi':<14}{'yayin':>8}"
      + "".join(f"{f'{e} kes':>9}{f'{e} duy':>9}" for e in ESIKLER))
for ad, guven in ADAYLAR:
    oran = sum(1 for p in PUANLAR if p >= guven) / len(PUANLAR)
    print(f"{ad:<14}{oran:>8.4f}"
          + "".join(f"{k:>9.4f}{d:>9.4f}"
                    for k, d in (kesinlik_duyarlilik(guven, e) for e in ESIKLER)))
print(f"{'sabit kutu':<14}{1.0:>8.4f}"
      + "".join(f"{v:>9.4f}{v:>9.4f}"
                for v in (sum(1 for o in SABIT_O if o >= e) / len(SABIT_O)
                          for e in ESIKLER)))
```

```
guven esigi      yayin  0.3 kes  0.3 duy  0.5 kes  0.5 duy  0.7 kes  0.7 duy
hepsi           1.0000   0.9812   0.9812   0.9625   0.9625   0.8500   0.8500
dorttebir 1     0.7063   1.0000   0.7063   1.0000   0.7063   0.9735   0.6875
dorttebir 2     0.4437   1.0000   0.4437   1.0000   0.4437   1.0000   0.4437
dorttebir 3     0.2625   1.0000   0.2625   1.0000   0.2625   1.0000   0.2625
sabit kutu      1.0000   0.5125   0.5125   0.1938   0.1938   0.0125   0.0125
```

Şimdiye kadar her yordam her görüntüde bir kutu yayımladı; yayımlamak zorunda olduğu için de
kesinlik ile duyarlılık aynı sayıydı. İlk satır bunu gösteriyor: 1,0000 yayın oranında ikisi de
0,9812. Puanı düşük olan tahminler yayımlanmadığında ikisi ayrışıyor. Doğrulama kümesinin en düşük
dörtte birlik puanı eşik alındığında görüntülerin 0,7063'ünde kutu yayımlanıyor ve 0,3 eşiğinde
kesinlik **1,0000**'e çıkarken duyarlılık **0,7063**'e iniyor.

M27/K03 bu değiş tokuşu kurmuştu ve tanımları burada tekrarlanmıyor. Görüntüye özgü olan tek şey
şudur: orada bir tahmin "doğru" ya da "yanlış"tı, burada doğruluğu bir **örtüşme eşiği** tanımlıyor
ve o eşik tablonun sütunlarını birbirinden ayırıyor. Dörtte birlik eşikte 0,7 sütunundaki kesinlik
0,9735 kalıyor, çünkü yüksek puanlı bir tahmin bile 0,7 örtüşmeyi kaçırabiliyor. Puan, kutunun
doğru olduğunu değil, o bölgede parlak bir yığılma bulunduğunu söylüyor.

Son satır tabanı aynı tabloya koyuyor. Sabit kutu hep yayımladığı için kesinliği ve duyarlılığı
eşittir ve 0,3 eşiğinde 0,5125'tir. Kesinliğe bakıp "yordamım 1,0000" demek, hangi eşikte ve kaç
görüntüde yayın yapıldığı yazılmadan hiçbir şey söylemez; alanın tabanı yazılmadan ise ölçülmemiş
sayılır.

#### Özet

- Örtüşme oranı iki kutunun kesişim alanının birleşim alanına bölümüdür; örnekte 8 hücre kesişim,
  38 hücre birleşim, oran 0,2105.
- Izgaranın ortasına konan 4x4'lük sabit kutu görüntüye hiç bakmadan ortalama 0,3011 örtüşme alır
  ve 0,3 eşiğinde sınama görüntülerinin 0,5125'inde tespit sayılır; kaynağı kurgudaki merkez
  yanlılığıdır.
- Aynı sabit kutu eşik 0,5'te 0,1938'e, 0,7'de 0,0125'e düşer: sayı yordamdan değil eşikten
  gelmektedir.
- Yalnız konum arayan 81 adaylı pencere 0,5687, boyutu da arayan 2.025 adaylı pencere 0,9076
  ortalama örtüşme verir; 25 kat arama 0,3389 katar.
- İki pencere 0,3 eşiğinde 0,0062 ile ayrılır, 0,7 eşiğinde fark 0,6125'e çıkar; düşük eşik boyut
  hatasını tümüyle gizler.
- Güven eşiği doğrulama kümesinin dörtte birlik puanına çekildiğinde yayın oranı 0,7063 olur,
  kesinlik 0,9812'den 1,0000'e çıkar, duyarlılık 0,7063'e iner.

#### Sonraki Adım

Kutu nesnenin **nerede** olduğunu söyledi, ama **hangi piksellerin** nesne olduğunu söylemedi.
Boyutu da arayan pencere 0,9076 ortalama örtüşme aldığında bile verdiği cevap bir dikdörtgendir ve
o dikdörtgenin içindeki her piksel nesne sayılır. Bu kurguda nesne zaten bir dikdörtgen olduğu için
kaybın çoğu görünmez; nesnenin kenarı düz olmadığında kutunun içine giren zemin pikselleri hiç
sayılmaz. Sonraki ders kararı **piksel düzeyine** indirir ve ilk işi yine tabanı yazmak olur: her
pikseli baskın sınıfa atayan bir yordam, piksel dengesizliği yüzünden şaşırtıcı biçimde yüksek bir
sayı alır.

### Bölütleme

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/bolutleme

Piksel düzeyinde kararın kendi tabanına karşı okunması: sınamadaki 17.280 pikselin 2.193'ü nesne olduğu için her pikseli baskın sınıfa atayan taban piksel doğruluğunda 0,8731 alıyor, aynı çıktının nesne örtüşme oranı 0,0000. Tek piksel değerinden karar veren doğrusal model 0,9540 ve 0,6412, aynı model 3x3 komşuluk penceresiyle 0,9851 ve 0,8843 veriyor; fark modelden değil temsilden geliyor. Yüz yirmi görüntünün 45'i bitişik blok taşıyor ve kusursuz maskeyle bile bağlı bileşen sayarak örnek sayısı bu 45 görüntüde yanlış çıkıyor; dikdörtgen ayrıştırma 24'ünü düzeltip 21'inde duruyor, kestirilen maskede ise yanlış sayı 46'dan 79'a çıkıyor.

Önceki ders nesnenin **nerede** olduğunu bir kutuyla söyledi ve o kutunun örtüşme oranını
görüntünün ortasına konan sabit bir kutunun aynı ölçütteki sayısıyla karşılaştırdı; boyutu da arayan
pencere 0,9076 ortalama örtüşme aldı. Kutunun söylemediği bir şey kaldı: bulunan dikdörtgenin
içindeki **her piksel** nesne sayılıyor. Bir kutu, dört sayıdan
oluşan kaba bir yanıttır; "hangi pikseller" sorusunun yanıtı ise piksel sayısı kadar karardır.

Bu dersin kurgusunda nesneler dikdörtgen bloklardır, yani kusursuz bir kutu zaten kusursuz bir
maske verir. Kurgu bu yönüyle **kutunun lehinedir** ve ders yine de iki şey gösterir. Birincisi,
piksel düzeyine inildiğinde alanın tabanı değişir ve **şaşırtıcı biçimde yüksek** çıkar. İkincisi,
piksel düzeyinde ne kadar iyi karar verilirse verilsin, **iki nesnenin bitiştiği yerde** anlamsal
bölütleme ikisini ayıramaz; bu bir doğruluk sorunu değil, çıktının biçimiyle ilgili bir sınırdır.

- **BG31. Görüntü kurgudur.** 12x12 kapsama ızgarası burada gri düzeyli küçük bir görüntüdür;
  ızgara M26/K06'dan gelir ve M27/K05'te öğrenme girdisine çevrilmişti. Tohum 20260218.
- **BG32. Nesneler kurgu dikdörtgen bloklardır.** Yükseklik ve genişlik 2 ile 4 arasındadır, blok
  pikselleri zeminden daha yüksek bir gri düzeye oturur ve gürültü üç düzgün sayının toplamıyla
  üretilir; iki düzeyin dağılımları uçlarda örtüşür.
- **BG33. Bir görüntüde bir, iki ya da üç blok bulunur.** İkinci ve üçüncü blok 0,40 olasılıkla bir
  öncekinin kenarına dayanır; dayanmıyorsa aralarında en az bir hücre boşluk bırakılır.
- **BG34. İki etiket vardır.** Nesne maskesi her piksel için 0/1'dir ve **anlamsal bölütlemenin**
  hedefidir; örnek maskesi her piksele blok numarasını yazar ve **örnek bölütlemenin** hedefidir.
- **BG35. Bölme 80/120'dir** ve bu görüntü kümesinde sabittir. Eğitim kümesi bilerek küçüktür.
- **BG36. Alanın tabanı her pikseli baskın sınıfa atamaktır.** Baskın sınıf zemindir; seçimin
  gerekçesi piksel oranıdır ve o oran basılır.
- **BG37. İki ölçüt yan yana okunur.** Piksel doğruluğu (büyük iyi) bütün pikselleri sayar; nesne
  sınıfının **örtüşme oranı** (kesişim bölü birleşim, büyük iyi) yalnız nesne pikselini sayar.
  Örtüşme oranı 03. derste kutular üzerinde tanımlanmıştı, burada piksel kümeleri üzerinde okunur.
- **BG38. Model doğrusaldır ve en küçük karelerle uydurulur**; karar eşiği 0,5'te sabittir. Eşik
  seçiminin sayıyı oynatması M27/K03'te ölçüldü ve **tekrarlanmaz**. Kütüphane çağrılmaz.
- **BG39. Örnek sayısı iki yordamla okunur:** bağlı bileşenler ve "nesneler dikdörtgendir"
  önbilgisiyle dikdörtgen ayrıştırma.

#### Kurgu Görüntü ve Alanın Tabanı

```python
# goruntu.py — MODELDIR. Goruntu kumesi KURGUDUR: M26/K06 ve M27/K05'in 12x12
# kapsama izgarasi burada gri duzeyli kucuk bir goruntudur ve uzerine kurgu
# dikdortgen bloklar yerlestirilir. Tohum 20260218.
TOHUM, M32, BOY = 20260218, 0xFFFFFFFF, 12
ZEMIN, BLOK, GURULTU = 0.30, 0.74, 0.30


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 ortusuyor(a, b, bosluk):
    return not (a[0] + a[2] + bosluk <= b[0] or b[0] + b[2] + bosluk <= a[0]
                or a[1] + a[3] + bosluk <= b[1] or b[1] + b[3] + bosluk <= a[1])


def goruntu(no):
    """Bir kapsama karesi: gri duzeyler, nesne maskesi, ornek maskesi, blok sayisi."""
    r = uretec(TOHUM + 400000 + no)
    bloklar = []
    for _ in range(1 + ayrik(r(), [0.24, 0.46, 0.30])):
        h, w = 2 + int(r() * 3), 2 + int(r() * 3)
        bitisik = bool(bloklar) and r() < 0.40
        for _ in range(24):
            if bitisik:                       # onceki blogun kenarina dayali
                a, yan = bloklar[int(r() * len(bloklar))], int(r() * 4)
                sy = a[0] - h if yan == 0 else a[0] + a[2] if yan == 1 else a[0]
                sx = a[1] if yan < 2 else a[1] - w if yan == 2 else a[1] + a[3]
            else:
                sy, sx = int(r() * (BOY - h + 1)), int(r() * (BOY - w + 1))
            yeni = (sy, sx, h, w)
            if not (0 <= sy <= BOY - h and 0 <= sx <= BOY - w):
                continue
            if any(ortusuyor(yeni, b, 0 if bitisik else 1) for b in bloklar):
                continue
            bloklar.append(yeni)
            break
    g = [[ZEMIN + (r() + r() + r() - 1.5) * GURULTU for _ in range(BOY)] for _ in range(BOY)]
    ornek = [[0] * BOY for _ in range(BOY)]
    for sira, (sy, sx, h, w) in enumerate(bloklar, 1):
        for i in range(sy, sy + h):
            for j in range(sx, sx + w):
                g[i][j] += BLOK - ZEMIN
                ornek[i][j] = sira
    maske = [[1 if ornek[i][j] else 0 for j in range(BOY)] for i in range(BOY)]
    return g, maske, ornek, len(bloklar)


VERI = [goruntu(i) for i in range(200)]
EGT, SIN = VERI[:80], VERI[80:]
PIKSEL = len(SIN) * BOY * BOY
NESNE = sum(sum(sum(s) for s in m) for _, m, _, _ in SIN)
print(f"kurgu: 200 goruntu {BOY}x{BOY}, egitim {len(EGT)}, sinama {len(SIN)}; "
      f"sinamada {NESNE} nesne pikseli / {PIKSEL}")
print(f"taban - her pikseli baskin sinifa (zemin) atamak: "
      f"piksel dogrulugu {(PIKSEL - NESNE) / PIKSEL:.4f}, nesne ortusme orani 0.0000")
g, _, o, k = VERI[97]
for i in range(BOY):
    print("   " + "".join(str(min(9, max(0, int(g[i][j] * 10)))) for j in range(BOY))
          + "    " + "".join(".12345"[o[i][j]] for j in range(BOY)))
print(f"   solda gri duzey, sagda ornek numarasi; bu karede {k} blok var")
```

```
kurgu: 200 goruntu 12x12, egitim 80, sinama 120; sinamada 2193 nesne pikseli / 17280
taban - her pikseli baskin sinifa (zemin) atamak: piksel dogrulugu 0.8731, nesne ortusme orani 0.0000
   102330223332    ............
   222322797803    ......2222..
   333006674822    ......2222..
   410235775913    ......2222..
   426354786802    ......2222..
   045333776830    ......1111..
   302211787842    ......1111..
   344130859630    ......1111..
   234251999753    ......1111..
   231130223333    ............
   432153222132    ............
   332423044303    ............
   solda gri duzey, sagda ornek numarasi; bu karede 2 blok var
```

Dersin ilk sayısı taban satırındadır. Sınamadaki 17.280 pikselin 2.193'ü nesnedir; oran 0,1269.
Hiçbir şey öğrenmeyen, her piksele "zemin" yazan yordam bu yüzden piksel doğruluğunda **0,8731**
alır. Bu sayı bir başarı değil, sınıf oranının kendisidir: nesne pikselleri azınlıkta olduğu için
onları tümüyle ıskalamanın bedeli düşüktür.

Aynı çıktının ikinci ölçütteki sayısı **0,0000**'dır. Örtüşme oranı yalnız nesne sınıfını sayar;
kesişim boş olduğu için oran sıfırdır. Tek bir çıktı, iki ölçütte 0,8731 ve 0,0000 veriyor. Ölçüt
seçimi burada bir tercih değil, sayının anlamını belirleyen karardır.

Basılan kare kursun ikinci sorusunu da gösteriyor. Sağdaki örnek haritası altıncı ile dokuzuncu
sütunlar arasında **iki ayrı blok** olduğunu söylüyor; soldaki gri düzeylerde ise tek bir parlak
dikdörtgen var. İki bloğun bitiştiği yerde piksel değerleri arasında hiçbir sınır yok.

#### Aynı Model, İki Temsil

```python
def pencere(g, i, j):
    return [g[min(BOY - 1, max(0, a))][min(BOY - 1, max(0, b))]
            for a in (i - 1, i, i + 1) for b in (j - 1, j, j + 1)]


def oznitelik(g, i, j, genis):
    return [1.0] + (pencere(g, i, j) if genis else [g[i][j]])


def coz(A, b):
    n, x = len(b), [0.0] * len(b)
    M = [A[i][:] + [b[i]] for i in range(n)]
    for k in range(n):
        p = max(range(k, n), key=lambda r: abs(M[r][k]))
        M[k], M[p] = M[p], M[k]
        for r in range(k + 1, n):
            f = M[r][k] / M[k][k]
            for c in range(k, n + 1):
                M[r][c] -= f * M[k][c]
    for k in range(n - 1, -1, -1):
        x[k] = (M[k][n] - sum(M[k][c] * x[c] for c in range(k + 1, n))) / M[k][k]
    return x


def egit(kume, genis):
    """Piksel basina dogrusal karar islevi; en kucuk karelerle uydurulur. MODELDIR."""
    d = 10 if genis else 2
    A, b = [[0.0] * d for _ in range(d)], [0.0] * d
    for g, m, _, _ in kume:
        for i in range(BOY):
            for j in range(BOY):
                x, y = oznitelik(g, i, j, genis), float(m[i][j])
                for p in range(d):
                    b[p] += x[p] * y
                    for q in range(p, d):
                        A[p][q] += x[p] * x[q]
    for p in range(d):
        for q in range(p):
            A[p][q] = A[q][p]
    return coz(A, b)


def kestir(w, g, genis):
    return [[1 if sum(a * c for a, c in zip(w, oznitelik(g, i, j, genis))) >= 0.5 else 0
             for j in range(BOY)] for i in range(BOY)]


def olc(kume, w, genis):
    dogru = kesisim = birlesim = 0
    for g, m, _, _ in kume:
        k = kestir(w, g, genis) if w else [[0] * BOY for _ in range(BOY)]
        for i in range(BOY):
            for j in range(BOY):
                dogru += k[i][j] == m[i][j]
                kesisim += k[i][j] and m[i][j]
                birlesim += k[i][j] or m[i][j]
    return dogru / (len(kume) * BOY * BOY), kesisim / max(1, birlesim)


W1, W9 = egit(EGT, False), egit(EGT, True)
print(f"{'temsil':<22}{'piksel dogrulugu':>18}{'ortusme orani':>16}")
for ad, w, genis in (("taban (hepsi zemin)", None, False),
                     ("tek piksel degeri", W1, False),
                     ("3x3 komsuluk penceresi", W9, True)):
    d, iou = olc(SIN, w, genis)
    print(f"{ad:<22}{d:>18.4f}{iou:>16.4f}")
```

```
temsil                  piksel dogrulugu   ortusme orani
taban (hepsi zemin)               0.8731          0.0000
tek piksel degeri                 0.9540          0.6412
3x3 komsuluk penceresi            0.9851          0.8843
```

İki satır arasındaki tek fark **temsildir**. Model ailesi aynı (doğrusal karar işlevi), uydurma
yordamı aynı (en küçük kareler), eşik aynı (0,5), eğitim kümesi aynı. Değişen şey girdinin ne
olduğudur: bir sayı mı, yoksa pikselin kendisiyle birlikte sekiz komşusu mu.

Fark iki ölçütte iki ayrı büyüklükte görünüyor. Piksel doğruluğu 0,9540'tan 0,9851'e çıkıyor,
oynama **0,0311**. Örtüşme oranı 0,6412'den 0,8843'e çıkıyor, oynama **0,2431**. İkinci temsilin
kattığı şey aynı şeydir; birinci ölçüt onun sekizde birini gösteriyor, çünkü doğruluk paydasının
yüzde 87'si zaten zemin pikselidir ve iki temsil de zemin pikselinde hemen hemen hiç
yanılmıyor.

Tabana karşı okunduğunda 3x3 penceresinin piksel doğruluğundaki kazancı 0,1120'dir. Bu sayının
yanına 0,8731 yazılmadığında "yüzde 98,5 doğruluk" cümlesi kurulabilir ve cümle, hiçbir şey
öğrenmeyen yordamın 0,8731 aldığını gizler. Kursun kuralı burada bir kez daha ödenir: **alanın
tabanı yazılmayan sayı ölçülmemiş sayılır.**

Komşuluk penceresinin katkısı nereden geliyor sorusunun yanıtı gürültüdedir. Tek piksel değeri,
iki gri düzeyin dağılımı uçlarda örtüştüğü için tek başına yanılır; komşuların ortalaması aynı
gürültüyü küçültür ve zemindeki yalnız parlak bir piksel çevresi tarafından bastırılır. Bu, evrişim
katmanının M27/K05'te ölçülen ağırlık paylaşımından farklı bir şeydir: burada öğrenilen tek bir
küçük ağırlık kümesi vardır ve kazanç **girdinin kapsamından** gelir.

#### Anlamsal Bölütleme Nerede Duruyor

```python
def bagli_bilesenler(maske):
    gor, liste = [[0] * BOY for _ in range(BOY)], []
    for i in range(BOY):
        for j in range(BOY):
            if maske[i][j] and not gor[i][j]:
                gor[i][j], yigit, hucre = 1, [(i, j)], []
                while yigit:
                    a, b = yigit.pop()
                    hucre.append((a, b))
                    for da, db in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                        p, q = a + da, b + db
                        if 0 <= p < BOY and 0 <= q < BOY and maske[p][q] and not gor[p][q]:
                            gor[p][q] = 1
                            yigit.append((p, q))
                liste.append(hucre)
    return liste


def dikdortgen_say(hucre):
    """Nesneler dikdortgendir onbilgisiyle bir bilesen kac dikdortgene bolunur."""
    say = []
    for eksen in (0, 1):
        profil, parca, onceki = {}, 0, None
        for a, b in hucre:
            profil.setdefault(a if eksen == 0 else b, set()).add(b if eksen == 0 else a)
        for k in sorted(profil):
            if onceki is None or k != onceki + 1 or profil[k] != profil[onceki]:
                parca += 1
            onceki = k
        say.append(parca)
    return min(say)


def sayim(kume, w):
    bitisik = bilesen = dikdortgen = 0
    for g, m, _, k in kume:
        maske = kestir(w, g, True) if w else m
        b = bagli_bilesenler(maske)
        bitisik += len(bagli_bilesenler(m)) < k
        bilesen += len(b) != k
        dikdortgen += sum(dikdortgen_say(h) for h in b) != k
    return bitisik, bilesen, dikdortgen


for ad, w in (("gercek maske", None), ("3x3 kestirimi", W9)):
    bitisik, bilesen, dikdortgen = sayim(SIN, w)
    print(f"{ad:<14} bitisik blok tasiyan {bitisik:>3}/{len(SIN)} goruntu; "
          f"ornek sayisi yanlis: bilesen sayarak {bilesen:>3}, "
          f"dikdortgen ayristirarak {dikdortgen:>3}")
```

```
gercek maske   bitisik blok tasiyan  45/120 goruntu; ornek sayisi yanlis: bilesen sayarak  45, dikdortgen ayristirarak  21
3x3 kestirimi  bitisik blok tasiyan  45/120 goruntu; ornek sayisi yanlis: bilesen sayarak  46, dikdortgen ayristirarak  79
```

Birinci satır anlamsal bölütlemenin tavanıdır ve bu tavan **kusursuz maskeyle** ölçülmüştür. Yüz
yirmi sınama görüntüsünün 45'i bitişik blok taşıyor; bağlı bileşenleri sayan yordam örnek sayısını
tam olarak o 45 görüntüde yanlış veriyor, kalan 75'inde doğru. Maskede hiçbir hata yokken bile
oran budur, çünkü hata maskede değil **sorunun biçimindedir**: anlamsal bölütleme her piksele bir
sınıf yazar ve iki bitişik bloğun pikselleri aynı sınıftadır.

İkinci yordam nesne biçimi hakkında bir önbilgi ekliyor — bloklar dikdörtgendir — ve bileşeni en az
kaç dikdörtgene bölmek gerektiğini sayıyor. Bu, kusursuz maskede 45 yanlışı **21**'e indiriyor:
24 görüntüde bitişiklik, bileşenin dikdörtgen olmayan biçiminden okunabiliyor. Kalan 21 görüntüde
iki bloğun birleşimi **kendisi de bir dikdörtgendir**; bir önceki bölümde basılan kare tam olarak
budur ve orada hiçbir biçim önbilgisi iki bloğu ayıramaz.

Üçüncü sayı önbilginin bedelini gösteriyor. Kestirilen maskede bileşen sayan yordamın yanlışı 45'ten
46'ya çıkıyor, yani maske hatası neredeyse hiç zarar vermiyor. Dikdörtgen ayrıştırma ise 21'den
**79**'a fırlıyor: kestirimdeki tek bir eksik ya da fazla piksel bileşeni dikdörtgen olmaktan
çıkarıyor ve yordam onu iki üç parçaya bölüyor. Önbilgi kusursuz girdide kazandırıyor, gürültülü
girdide kaybettiriyor; ve bu, örtüşme oranı 0,8843 olan bir maskede oluyor.

Anlamsal ile örnek bölütlemenin ayrıştığı yer buradadır. Anlamsal bölütlemenin çıktısı **piksel
başına bir sınıftır** ve iyi bir piksel doğruluğu bu ayrımı hiçbir zaman getirmez; örnek
bölütlemenin çıktısı **piksel kümeleridir** ve bunun için ya nesne başına ayrı bir çıktı ya da
biçim gibi bir dış bilgi gerekir. Ölçüt de ayrışır: piksel doğruluğu ve örtüşme oranı 45 görüntüde
tavana yakın kalırken örnek sayısı yanlıştır.

#### Özet

- Sınamadaki 17.280 pikselin 2.193'ü nesne olduğu için her pikseli baskın sınıfa atayan taban
  piksel doğruluğunda 0,8731 alıyor; aynı çıktının nesne örtüşme oranı 0,0000.
- Aynı doğrusal model tek piksel değeriyle 0,9540 ve 0,6412, 3x3 komşuluk penceresiyle 0,9851 ve
  0,8843 veriyor; fark model ailesinden değil temsilden geliyor ve iki ölçütte 0,0311 ile 0,2431
  olarak görünüyor.
- Yüz yirmi görüntünün 45'i bitişik blok taşıyor; kusursuz maskeyle bile bağlı bileşen sayarak
  örnek sayısı bu 45 görüntüde yanlış çıkıyor, çünkü sınır maskede değil sorunun biçimindedir.
- Nesnelerin dikdörtgen olduğu önbilgisi kusursuz maskede yanlışı 21'e indiriyor, kestirilen
  maskede 79'a çıkarıyor; önbilgi gürültülü girdide bedel ödetiyor.

#### Sonraki Adım

Dört derste görüntü tek bir kareydi ve her karar o karenin kendisinden okundu. Bir kapsama ağı ise
kareyi tek tek değil **arka arkaya** üretir: aynı bölgenin ardışık okumaları bir dizi oluşturur ve
dizinin komşuluğu uzayda değil zamandadır. Bu derste komşuluk penceresi piksel doğruluğunu 0,0311,
örtüşme oranını 0,2431 oynattı; pencere zamana açıldığında hangi sayı oynar. Sonraki ders kare
başına verilen kararın zaman içindeki **tutarsızlığını** sayar ve o ölçütte hiçbir şey öğrenmeyen
bir yordamın alabileceği en iyi sayının ne olduğunu gösterir.

### Video ve Zamansal Modeller

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/video-ve-zamansal-modeller

Kare başına kararın zaman içindeki tutarsızlığının sayılması: otuz altı sınama dizisinin 432 karesinde her kareye baskın sınıfı yazan taban 0,7014 doğruluk ve 0 kararsızlık verirken gerçek etiket dizileri 71 geçiş taşıyor. Bağımsız kare kararı 0,8634 doğrulukla 99 geçiş üretiyor, yani gerçeğin 28 fazlası. Aynı puanlara geçiş cezası uygulandığında ceza 0,05'te doğruluk 0,8657'ye çıkıyor, ceza 0,15'te kararsızlık gerçeğin 71'ine oturuyor ve ceza 4,00'te karar tabanın kendisine, 0,7014 ve 1 geçişe iniyor: alanın tabanı bu ölçütte ayrı bir yordam değil, cezanın uç değeridir.

Önceki ders piksel kararını komşularına bakarak verdi ve komşuluk penceresi örtüşme oranını 0,2431
oynattı. O komşuluk **uzaydaydı**: bir pikselin sekiz komşusu aynı karenin içindeydi. Bir kapsama
ağı kareyi tek tek değil arka arkaya üretir; aynı bölge belirli aralıklarla yeniden okunur ve
okumalar bir dizi oluşturur. Bu dizinin komşuluğu **zamandadır** ve dersin sorusu şudur: her kareye
bağımsız karar veren bir yordam, zamanı hiç kullanmadığında ne kaybediyor.

Kayıp, kare doğruluğuna bakılarak görülmez. Bir olay gerçekte başlar, bir süre sürer ve biter;
etiket dizisi bu yüzden iki üç kez değişir. Kare başına bağımsız karar veren bir yordam ise
gürültü her yön değiştirdiğinde fikir değiştirir. Bu dersin ikinci ölçütü **kararsızlıktır**:
ardışık iki karede kararın kaç kez değiştiği. Ölçüt yeni bir soru da getiriyor, çünkü hiçbir şey
öğrenmeyen taban bu ölçütte **sıfır** alır.

- **BG40. Zamansal kurgu, 04. dersin karesinin kısa bir dizisidir.** Aynı 12x12 gri düzeyli kapsama
  karesi bir bölge için on iki kez üretilir; zemin, blok düzeyi ve gürültü aynıdır, tohum 20260218.
- **BG41. Olay bir aralıktır.** Kurgu blok, dizinin ardışık iki ila beş karesinde bulunur; başlangıç
  karesi birinci ile yedinci kare arasındadır. Kare etiketi bloğun o karede bulunup bulunmadığıdır.
- **BG42. İki gürültü kaynağı vardır.** Etkin karelerin yaklaşık üçte birinde okuma zayıftır ve blok
  sönük görünür; etkin olmayan karelerin yaklaşık yedide birinde geçici parlak bir leke belirir.
  Birincisi kaçırma, ikincisi yanlış alarm üretir.
- **BG43. Bölme 24/36 dizidir**, yani sınamada 432 kare vardır. Bölme dizi düzeyindedir; aynı dizinin
  kareleri iki kümeye dağıtılmaz.
- **BG44. Alanın tabanı her kareye baskın sınıfı yazmaktır.** Baskın sınıf "etkin değil"dir.
- **BG45. İki ölçüt yan yana okunur.** Kare doğruluğu (büyük iyi) ve **kararsızlık**: ardışık
  karelerde kararın kaç kez değiştiği. Kararsızlıkta küçük olan iyi değildir; okunacak sayı
  **gerçek etiket dizilerinin kararsızlığıdır** ve o sayı da basılır.
- **BG46. Kare modeli doğrusaldır** ve kare başına üç sayıdan uydurulur: ortalama gri düzey, en
  parlak 3x3 pencerenin ortalaması, eşik üstü piksel oranı. En küçük kareler, eşik 0,5. Kütüphane
  çağrılmaz.
- **BG47. Zamanı kullanan karar aynı puanları kullanır.** Model, ağırlıklar ve kare puanları
  değişmez; yalnız dizinin tamamına **geçiş başına sabit bir ceza** eklenir ve en düşük maliyetli
  karar dizisi seçilir.

#### Zamansal Kurgu ve İki Taban Sayısı

```python
# dizi.py — MODELDIR. Zamansal kurgu, 04. dersin gri duzeyli 12x12 kapsama
# karesinin KISA BIR DIZISIDIR: ayni bolge on iki kez okunur ve olay
# karelerin bir bolumunde etkindir. Tohum 20260218.
TOHUM, M32, BOY, KARE = 20260218, 0xFFFFFFFF, 12, 12
ZEMIN, BLOK, GURULTU = 0.30, 0.74, 0.30


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 dizi(no):
    """Bir bolgenin on iki karelik okumasi: kareler ve kare basina olay etiketi."""
    r = uretec(TOHUM + 500000 + no)
    bas, boy = 1 + int(r() * 7), 2 + int(r() * 4)
    h, w = 2 + int(r() * 3), 2 + int(r() * 3)
    sy, sx = int(r() * (BOY - h + 1)), int(r() * (BOY - w + 1))
    kareler, etiket = [], []
    for t in range(KARE):
        etkin = bas <= t < bas + boy
        g = [[ZEMIN + (r() + r() + r() - 1.5) * GURULTU for _ in range(BOY)]
             for _ in range(BOY)]
        if etkin:
            guc = 0.35 if r() < 0.28 else 1.0        # bazi karelerde okuma zayif
            for i in range(sy, sy + h):
                for j in range(sx, sx + w):
                    g[i][j] += (BLOK - ZEMIN) * guc
        elif r() < 0.14:                             # gecici parlak leke
            a, b = int(r() * (BOY - 1)), int(r() * (BOY - 1))
            for i in (a, a + 1):
                for j in (b, b + 1):
                    g[i][j] += BLOK - ZEMIN
        kareler.append(g)
        etiket.append(int(etkin))
    return kareler, etiket


VERI = [dizi(i) for i in range(60)]
EGT, SIN = VERI[:24], VERI[24:]
TOPLAM = len(SIN) * KARE
ETKIN = sum(sum(e) for _, e in SIN)
TABAN = (TOPLAM - ETKIN) / TOPLAM
GERCEK_KARARSIZ = sum(sum(e[t] != e[t - 1] for t in range(1, KARE)) for _, e in SIN)
print(f"kurgu: {len(VERI)} dizi x {KARE} kare, egitim {len(EGT)}, sinama {len(SIN)}; "
      f"sinamada {ETKIN}/{TOPLAM} kare etkin")
print(f"taban - her kareye baskin sinifi (etkin degil) yazmak: "
      f"kare dogrulugu {TABAN:.4f}, kararsizlik 0")
print(f"gercek etiket dizilerinin kararsizligi: {GERCEK_KARARSIZ} gecis "
      f"({GERCEK_KARARSIZ / len(SIN):.2f} dizi basina)")
```

```
kurgu: 60 dizi x 12 kare, egitim 24, sinama 36; sinamada 129/432 kare etkin
taban - her kareye baskin sinifi (etkin degil) yazmak: kare dogrulugu 0.7014, kararsizlik 0
gercek etiket dizilerinin kararsizligi: 71 gecis (1.97 dizi basina)
```

Alanın tabanı iki sayı veriyor ve ikisi birbirine karşıt yönde okunuyor. Kare doğruluğunda **0,7014**
alıyor, çünkü 432 karenin yalnız 129'u etkin. Kararsızlıkta **0** alıyor, çünkü hiç fikir
değiştirmiyor; bir sabiti tekrarlayan yordam bu ölçütte yenilemez.

Üçüncü satır ölçütün nasıl okunacağını söylüyor. Gerçek etiket dizileri 36 dizide toplam **71 geçiş**
taşıyor, dizi başına 1,97. Bir olay başlıyor ve bitiyorsa iki geçiş olur; dizinin son karesine kadar
sürenlerde bir geçiş kalır. Kararsızlıkta küçük olan iyi değildir: aranan sayı sıfır değil,
**71'dir**. Tabanın sıfırı gerçeğin altındadır ve bu, ölçütün tek başına okunamayacağının en açık
biçimidir.

#### Bağımsız Kare Kararı

```python
def oznitelik(g):
    """Kare basina uc sayi: ortalama gri duzey, en parlak 3x3 pencere, esik ustu oran."""
    top = sum(sum(s) for s in g)
    enp = 0.0
    for i in range(BOY - 2):
        for j in range(BOY - 2):
            p = sum(g[i + a][j + b] for a in range(3) for b in range(3)) / 9.0
            if p > enp:
                enp = p
    ust = sum(1 for s in g for v in s if v > 0.55) / (BOY * BOY)
    return [1.0, top / (BOY * BOY), enp, ust]


def coz(A, b):
    n, x = len(b), [0.0] * len(b)
    M = [A[i][:] + [b[i]] for i in range(n)]
    for k in range(n):
        p = max(range(k, n), key=lambda r: abs(M[r][k]))
        M[k], M[p] = M[p], M[k]
        for r in range(k + 1, n):
            f = M[r][k] / M[k][k]
            for c in range(k, n + 1):
                M[r][c] -= f * M[k][c]
    for k in range(n - 1, -1, -1):
        x[k] = (M[k][n] - sum(M[k][c] * x[c] for c in range(k + 1, n))) / M[k][k]
    return x


def egit(kume):
    """Kare basina dogrusal karar islevi; en kucuk karelerle uydurulur. MODELDIR."""
    A, b = [[0.0] * 4 for _ in range(4)], [0.0] * 4
    for kareler, etiket in kume:
        for g, y in zip(kareler, etiket):
            x = oznitelik(g)
            for p in range(4):
                b[p] += x[p] * y
                for q in range(4):
                    A[p][q] += x[p] * x[q]
    return coz(A, b)


W = egit(EGT)
SKOR = [[sum(a * c for a, c in zip(W, oznitelik(g))) for g in kareler]
        for kareler, _ in SIN]
BAGIMSIZ = [[1 if s >= 0.5 else 0 for s in d] for d in SKOR]


def olc(kararlar):
    dogru = sum(k == y for kd, (_, e) in zip(kararlar, SIN) for k, y in zip(kd, e))
    kararsiz = sum(sum(kd[t] != kd[t - 1] for t in range(1, KARE)) for kd in kararlar)
    return dogru / TOPLAM, kararsiz


d, kz = olc(BAGIMSIZ)
print(f"bagimsiz kare karari: kare dogrulugu {d:.4f}, kararsizlik {kz} gecis "
      f"({kz / len(SIN):.2f} dizi basina)")
print(f"taban ile fark: dogrulukta {d - TABAN:+.4f}, kararsizlikta {kz - 0:+d}")
```

```
bagimsiz kare karari: kare dogrulugu 0.8634, kararsizlik 99 gecis (2.75 dizi basina)
taban ile fark: dogrulukta +0.1620, kararsizlikta +99
```

Birinci ölçütte model tabanı 0,1620 geçiyor ve bu, kare başına verilen kararın gerçekten bir şey
öğrendiğini söylüyor. İkinci ölçütte aynı model tabanın **99 geçiş** üstünde. Sayının okunacağı yer
gerçeğin 71'idir: model, gerçekliğin fikir değiştirdiğinden **28 kez fazla** fikir değiştiriyor,
oran olarak yüzde 39 fazla. Dizi başına bakıldığında gerçekte 1,97 geçiş varken kararda 2,75 geçiş
var.

Bu fazlalık kare doğruluğuna neredeyse hiç yansımaz. Bir dizide olayın ortasındaki tek bir karede
fikir değiştirmek doğruluktan yalnız 1/432 götürür, ama kararsızlığa iki geçiş ekler. Bir kapsama
ağında bu farkın karşılığı somuttur: aynı bölge için ardışık iki okumada iki ayrı uyarı üretilmesi
demektir ve uyarıyı okuyan taraf için bu, doğruluk kaybından daha pahalıdır.

#### Geçiş Cezası ile Zamanı Kullanan Karar

```python
def gecis_cezali(skor, ceza):
    """Zamani kullanan karar: kare maliyeti + gecis basina sabit ceza."""
    maliyet = [[(skor[0] - s) ** 2 for s in (0, 1)]]
    geri = [[0, 0]]
    for t in range(1, len(skor)):
        yeni, iz = [0.0, 0.0], [0, 0]
        for s in (0, 1):
            en, arg = None, 0
            for p in (0, 1):
                m = maliyet[t - 1][p] + (0.0 if p == s else ceza)
                if en is None or m < en:
                    en, arg = m, p
            yeni[s], iz[s] = en + (skor[t] - s) ** 2, arg
        maliyet.append(yeni)
        geri.append(iz)
    s = 0 if maliyet[-1][0] <= maliyet[-1][1] else 1
    yol = [s]
    for t in range(len(skor) - 1, 0, -1):
        s = geri[t][s]
        yol.append(s)
    return yol[::-1]


print(f"{'ceza':>6}{'kare dogrulugu':>16}{'kararsizlik':>13}{'dizi basina':>13}")
for ceza in (0.00, 0.05, 0.15, 0.40, 1.00, 4.00):
    d, kz = olc([gecis_cezali(skor, ceza) for skor in SKOR])
    print(f"{ceza:>6.2f}{d:>16.4f}{kz:>13}{kz / len(SIN):>13.2f}")
print(f"{'gercek':>6}{1.0:>16.4f}{GERCEK_KARARSIZ:>13}"
      f"{GERCEK_KARARSIZ / len(SIN):>13.2f}")
print(f"{'taban':>6}{TABAN:>16.4f}{0:>13}{0.0:>13.2f}")
ZAMANLI = [gecis_cezali(skor, 0.15) for skor in SKOR]
en = max(range(len(SIN)),
         key=lambda i: sum(BAGIMSIZ[i][t] != BAGIMSIZ[i][t - 1] for t in range(1, KARE)))
print(f"en cok fikir degistiren sinama dizisi ({en + 1}. sirada):")
for ad, d in (("gercek  ", SIN[en][1]), ("bagimsiz", BAGIMSIZ[en]), ("zamanli ", ZAMANLI[en])):
    print(f"   {ad} " + "".join(str(v) for v in d))
```

```
  ceza  kare dogrulugu  kararsizlik  dizi basina
  0.00          0.8634           99         2.75
  0.05          0.8657           86         2.39
  0.15          0.8611           71         1.97
  0.40          0.8472           45         1.25
  1.00          0.7801           21         0.58
  4.00          0.7014            1         0.03
gercek          1.0000           71         1.97
 taban          0.7014            0         0.00
en cok fikir degistiren sinama dizisi (18. sirada):
   gercek   000111110000
   bagimsiz 000101100010
   zamanli  000101100000
```

Tablonun ilk satırı ikinci bölümün sayılarıdır: sıfır ceza, bağımsız kare kararının kendisidir.
Sıfır cezada her kare kendi puanının en yakın olduğu değere yuvarlanır ve dizi hiçbir rol oynamaz.
Ceza büyüdükçe aynı puanlar aynı kalır — model, ağırlıklar ve kare puanları hiç değişmez — ama
kararlar değişir.

Farkın nereden geldiği bu yüzden kesin biçimde söylenebilir. Temsil değişmedi: kare başına aynı üç
sayı. Model değişmedi: aynı doğrusal işlev, aynı ağırlıklar. Değişen tek şey **kararın zaman
içinde nadiren değiştiği varsayımıdır** ve o varsayım tek bir sayıyla, geçiş cezasıyla girildi. Altı
satır, aynı modelin altı ayrı çıktısıdır.

Cezanın kendisi bir varsayımın sayıya çevrilmiş halidir: bir geçişin maliyeti, bir karede yanılmanın
maliyetiyle aynı birimden yazılır. Ceza 0,15 demek, bir geçişi ancak o geçişi haklı çıkaran kare
kanıtı yeterince güçlüyse kabul etmek demektir. Bu, olayın **ne kadar sürdüğü** hakkında dolaylı bir
varsayımdır ve kurguda olaylar iki ile beş kare arasında sürüyor.

Değiş tokuş üç yerde okunuyor. Doğruluk 0,05 cezada **0,8657** ile en yüksek değerine çıkıyor,
kararsızlık 99'dan 86'ya iniyor; küçük bir ceza hem doğruluk hem kararlılık kazandırıyor. Ceza
0,15'te kararsızlık **71**'e, yani gerçeğin sayısına oturuyor ve bunun bedeli en yüksek doğruluktan
0,0046 vermek. Ceza büyümeye devam ettiğinde doğruluk düşüyor: 0,40'ta 0,8472, 1,00'de 0,7801.

Son satır kursun ikinci iddiasını bu ders için ödüyor. Ceza 4,00'te karar dizisi neredeyse sabite
iniyor — 36 dizide **1 geçiş** — ve kare doğruluğu **0,7014**'e, yani tabanın kendi sayısına
düşüyor. Alanın tabanı burada ayrı bir yordam değil, **cezanın uç değeridir**; sonsuz cezayla
uygulanan zamansal düzeltme, her kareye baskın sınıfı yazmakla aynı çıktıyı verir. Kararsızlığı tek
başına küçültmeye çalışan bir ayar, sonunda hiçbir şey öğrenmemiş yordama varır.

Son üç satır bunu tek bir dizide gösteriyor. Gerçek dizi beş karelik bir olay taşıyor; bağımsız
karar olayın ortasında bir kare kaçırıyor ve olay bittikten sonra bir kare yanlış alarm veriyor,
altı geçiş. Zamanı kullanan karar yanlış alarmı siliyor ve dört geçişe iniyor, ama ortadaki
boşluğu **dolduramıyor**: o karede puan yeterince düşüktür ve 0,15 ceza onu çevirmeye yetmez.
Geçiş cezası kararı düzleştirir, kaçırılan kareyi geri getirmez.

#### Özet

- Kare başına kararın iki ölçütü vardır: kare doğruluğu ve ardışık karelerde kaç kez fikir
  değiştiğini sayan kararsızlık. Taban birincisinde 0,7014, ikincisinde 0 alır.
- Kararsızlıkta küçük olan iyi değildir; okunacak sayı gerçek etiket dizilerinin kararsızlığıdır ve
  o sayı 36 dizide 71 geçiştir.
- Bağımsız kare kararı 0,8634 doğrulukla 99 geçiş üretiyor: gerçeğin 28 fazlası, dizi başına 2,75
  yerine 1,97. Bu fazlalık kare doğruluğunda neredeyse görünmez.
- Geçiş cezası temsili ve modeli değiştirmeden altı ayrı çıktı üretiyor; 0,05'te doğruluk 0,8657 ile
  en yükseğine çıkıyor, 0,15'te kararsızlık gerçeğin 71'ine oturuyor.
- Ceza 4,00'te karar tabanın kendisine iniyor (0,7014 ve 1 geçiş): alanın tabanı bu ölçütte ayrı bir
  yordam değil, cezanın uç değeridir.

#### Sonraki Adım

Beş derste girdi hep aynı türdendi: bir gri düzey ızgarası, tek kare ya da kısa bir dizi olarak.
Bu kursun ilk sekiz dersinde ise girdi bir metindi ve aynı kurgu ölçüm ağının notlarından geliyordu.
İki kip şimdiye kadar ayrı ayrı ölçüldü; oysa saha ekibinin bir olay için düştüğü **not** ile aynı
olayın **kapsama karesi** aynı olaya aittir. Sonraki ders ikisini tek bir uzayda buluşturur ve şunu
sorar: bir not ile bir görüntünün aynı olaya ait olup olmadığını söyleyen bir temsil, rastgele
eşleştirmenin ne kadar üstüne çıkar ve tek kip tek başına bunun ne kadarını verir.

### Çok Kipli Modeller

Source: https://academia.sh/tr/kurslar/nlp-ve-goru/cok-kipli-modeller

Aynı olayın notunu ve kapsama karesini tek uzayda buluşturan ortak temsilin kendi tabanına karşı ölçülmesi: yirmi beş adaylık odalarda rastgele eşleştirme 0,0400 verirken karşıtlık hedefiyle öğrenilen ortak temsil 0,1660 veriyor ve kurgunun taşıdığı ortak bilginin tavanı 0,2659. Olay türü kararında en sık sınıf tabanı 0,4420, yalnız not 0,8940, yalnız kare 0,6140, ortak temsil 0,8660: eşleştirmeyi kazandıran temsil, sınıflandırmada notun tek başına verdiğinin altında kalıyor. Kurs kapanışı on dört dersin alan tabanını, yöntemin sayısını ve farkı tek tabloda toplar.

Beş ders görüntüyü, ilk sekiz ders metni tek başına ölçtü; oysa saha ekibinin bir olay için
düştüğü **not** ile aynı olayın **kapsama karesi** aynı olaya aittir.

Dersin ölçüsü bir doğruluk değil, **eşleştirmedir**: bir not verildiğinde aday kareler arasından
doğru olanı seçebiliyor muyuz. Tabanı **rastgele eşleştirmedir**; tavanı ise 1 değildir, iki kipin
**ortak taşıdığı** bilgi neyse tavan odur ve o da ders içinde hesaplanır.

- **BG48. Olay kaydı kurgudur ve iki kiplidir.** Not üretici `nlp` konusundakiyle, kare 04. dersin
  12x12 gri düzeyli kurgusuyla aynıdır. Tohum 20260218, bölme 1.100/500.
- **BG49. İki kip aynı bilgiyi eşit taşımaz.** Kare olay türünü desenle (blok yok, okunamayan bant,
  bir blok, iki blok), hattı sönük bir bantla taşır; not türü sözcüklerle taşır ama hattı yalnız
  kimi zaman yazar. Gürültü iki yandadır: notta ödünç bir yan kayıt, karede eksik kalan desen ve
  beklenmedik parlak leke.
- **BG50. Eşleştirme ölçütü oda başına 25 adaydır.** Tavan ayırt edilemeyen adaylardan hesaplanır:
  aynı türü ve — hat notta yazılıysa — aynı hattı taşıyan iki olay ayrılamaz.
- **BG51. Ortak temsil iki doğrusal izdüşümdür**: biri sözlükten, öteki kareden aynı uzaya.
  **Karşıtlık hedefi** ile öğrenilir: doğru çiftin benzerliği yükseltilir, kümedeki öteki yirmi
  dört çiftinki düşürülür.
- **BG52. Olay türü kararı üç temsilde aynı yordamla okunur:** sınıf ortalamasına açı benzerliği,
  taban en sık sınıf. Sözlük, ölçek ve ağırlıklar yalnız eğitimden öğrenilir; kütüphane çağrılmaz.

#### Aynı Olayın İki Kipi

```python
# KURGU olay kaydi: ayni olayin NOTU (nlp konusundan) ve KAPSAMA KARESI
# (04. dersin 12x12 gri duzeyli kurgusu). Tohum 20260218.
import math

TOHUM, M32, BOY = 20260218, 0xFFFFFFFF, 12
ZEMIN, BLOK, GURULTU = 0.30, 0.74, 0.30
TUR = ("olagan", "erisilemedi", "sayac arizasi", "kacak suphesi")
PAY, DESEN = (0.46, 0.22, 0.19, 0.13), (0, 0, 1, 2)
OBEK = [s.split("|") for s in (
    "okuma normal|okuma normaldi|sayac erisimi saglandi|sayaca erisildi|olcum tekrarlandi|"
    "olcumu yineledik|vana kontrol edildi|vanada sorun yok|kapak temiz|kapakta iz yok|"
    "gosterge okunakli|gostergede rakam net",
    "abone evde degildi|abone bulunamadi|erisim saglanamadi|erisim yok|kapi zili calismiyor|"
    "zil calismadi|bahce kapisi kilitli|bahce kapisi kapali|bodrum katina inilemedi|"
    "bodrum kilitli|adres bulunamadi|adres eksik",
    "gosterge donmuyor|gostergede hareket yok|sayac cami kirik|sayacin cami catlak|"
    "rakam okunmuyor|rakamlar silik|ibre sabit kalmis|ibre kilitli|mekanizma takilmis|"
    "mekanizmada takilma|sayac durmus|sayac calismiyor",
    "muhur izi var|muhurde iz goruldu|muhur kopmus|muhurler kopuk|baglanti degistirilmis|"
    "baglantida degisiklik|kelepce gevsek|kelepcede gevseme|boru ek yeri yeni|boruda yeni ek|"
    "sayac ters takilmis|sayaci ters takmislar")]
EK = ("arac park halinde|kapak kirli|hava yagisli|adres teyit edildi|"
      "not kisa tutuldu|ikinci ziyaret|bahce icinde|kaldirim uzerinde").split("|")
BOLGE = "kuzey hatti|guney hatti|dogu hatti|bati hatti|merkez hatti".split("|")


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 olay(no):
    """Ayni olayin iki kipi: kisa Turkce saha notu ve 12x12 kapsama karesi."""
    r, k, t = uretec(TOHUM + 41000 + no), 0.0, 0
    u = r()
    for i, p in enumerate(PAY):
        k += p
        if u < k:
            t = i
            break
    par = [OBEK[t][int(r() * 12)]]
    if r() < 0.55:
        par.append(OBEK[t][int(r() * 12)])
    if r() < 0.34:                            # baska turden odunc alinan yan kayit
        par.append(OBEK[int(r() * 4)][int(r() * 12)])
    if r() < 0.62:
        par.append(EK[int(r() * 8)])
    hat, yazili = int(r() * 5), r() < 0.30    # hat notta yalnizca kimi zaman yazilir
    if yazili:
        par.append(BOLGE[hat])
    q = uretec(TOHUM + 600000 + no)
    g = [[ZEMIN + (q() + q() + q() - 1.5) * GURULTU for _ in range(BOY)] for _ in range(BOY)]
    for i in range(BOY):                      # okunan hat sonuk bir bant olarak gorunur
        g[i][hat * 2] += 0.16
        g[i][hat * 2 + 1] += 0.16

    def blok(sy, sx):
        for i in range(sy, min(BOY, sy + 2 + int(q() * 2))):
            for j in range(sx, min(BOY, sx + 2 + int(q() * 2))):
                g[i][j] = BLOK + (q() + q() + q() - 1.5) * GURULTU
    for b in range(DESEN[t]):
        if q() >= 0.12:                       # kimi karede desen eksik kalir
            blok(int(q() * (BOY - 3)), hat * 2 + b * 2)
    if t == 1:                                # erisilemedi: okunamayan bant
        for i in range(BOY):
            g[i][hat * 2] = g[i][hat * 2 + 1] = 0.02 + q() * 0.05
    if q() < 0.15:                            # baska yerde beklenmeyen parlak leke
        blok(int(q() * (BOY - 3)), int(q() * (BOY - 3)))
    return {"metin": ", ".join(par), "tur": TUR[t], "hat": hat, "yazili": yazili, "kare": g}


VERI = [olay(i) for i in range(1600)]
SIN = VERI[1100:]
say, SOZLUK, gec = {}, {}, {}
for x in VERI[:1100]:
    say[x["tur"]] = say.get(x["tur"], 0) + 1
    for s in set(x["metin"].split()):
        gec[s] = gec.get(s, 0) + 1
for s in sorted(gec):
    if gec[s] >= 2:
        SOZLUK[s] = len(SOZLUK)
EN_SIK = max(say, key=say.get)
TABAN = sum(x["tur"] == EN_SIK for x in SIN) / len(SIN)
print(f"kurgu: 1600 olay, egitim 1100, ayrilmis {len(SIN)}; sozluk {len(SOZLUK)} sozcuk")
print(f"olay turu tabani (en sik sinif '{EN_SIK}') {TABAN:.4f}; hat notta yazili olan "
      f"olay orani {sum(x['yazili'] for x in SIN) / len(SIN):.4f}")
x = VERI[1124]
print(f"not: {x['metin']}  ->  {x['tur']}, hat {x['hat']}")
for satir in x["kare"]:
    print("   " + "".join(str(min(9, max(0, int(v * 10)))) for v in satir))
```

```
kurgu: 1600 olay, egitim 1100, ayrilmis 500; sozluk 154 sozcuk
olay turu tabani (en sik sinif 'olagan') 0.4420; hat notta yazili olan olay orani 0.2860
not: boruda yeni ek, dogu hatti  ->  kacak suphesi, hat 2
   143245002250
   114254245050
   423337867534
   531264793421
   351236684120
   231245223341
   212444253203
   435135111311
   154587830332
   622058911323
   222433403040
   241331231422
```

Olay türü tabanı **0,4420**'dir ve `nlp` konusunda ölçülen sayının aynısıdır. İkinci sayı dersin
sorununu kuruyor: hat, sınama olaylarının yalnız **0,2860**'ında notta yazılıdır, karede ise her
zaman görünür. Basılan örnekte not "dogu hatti" diyor; karede o bant beşinci ile altıncı sütunda
duruyor ve kaçak şüphesinin iki bloğu onun üstüne oturuyor.

#### Ortak Temsil ve Eşleştirme

```python
G, BOYUT, OLCEK, TOPLU, ADAY = 15, 12, 10.0, 25, 25


def kare_oznitelik(g):
    """On iki sutun ortalamasi, ortalama, en parlak 3x3, esik ustu oran."""
    return [sum(g[i][j] for i in range(BOY)) / BOY for j in range(BOY)] + [
        sum(sum(s) for s in g) / (BOY * BOY),
        max(sum(g[i + a][j + b] for a in range(3) for b in range(3)) / 9.0
            for i in range(BOY - 2) for j in range(BOY - 2)),
        sum(1 for s in g for v in s if v > 0.55) / (BOY * BOY)]


KELIME = [[SOZLUK[s] for s in x["metin"].split() if s in SOZLUK] for x in VERI]
KO = [kare_oznitelik(x["kare"]) for x in VERI]
for k in range(G):                            # olcek yalniz egitim kumesinden ogrenilir
    m = sum(o[k] for o in KO[:1100]) / 1100
    sd = math.sqrt(sum((o[k] - m) ** 2 for o in KO[:1100]) / 1100)
    for o in KO:
        o[k] = (o[k] - m) / sd
r = uretec(TOHUM + 77)
WM = [[(r() * 2 - 1) * 0.5 for _ in range(BOYUT)] for _ in range(len(SOZLUK))]
WK = [[(r() * 2 - 1) * 0.3 for _ in range(BOYUT)] for _ in range(G)]


def gom(i):
    """Notu ve kareyi ayni uzaya tasiyan izdusumler. MODELDIR."""
    c = []
    for v in ([sum(WM[w][d] for w in KELIME[i]) for d in range(BOYUT)],
              [sum(KO[i][k] * WK[k][d] for k in range(G)) for d in range(BOYUT)]):
        n = math.sqrt(sum(a * a for a in v)) + 1e-9
        c.append(([a / n for a in v], n))
    return c


for adim in range(800):                       # KARSITLIK HEDEFI
    bas = (adim * TOPLU) % (1100 - TOPLU)
    E = [gom(i) for i in range(bas, bas + TOPLU)]
    U, V = [e[0][0] for e in E], [e[1][0] for e in E]
    dU = [[0.0] * BOYUT for _ in E]
    dV = [[0.0] * BOYUT for _ in E]
    for i in range(TOPLU):                    # dogru cift yakin, oteki 24 cift uzak
        s = [OLCEK * sum(a * b for a, b in zip(U[i], V[j])) for j in range(TOPLU)]
        e = [math.exp(v - max(s)) for v in s]
        t = sum(e)
        for j in range(TOPLU):
            k = OLCEK * (e[j] / t - (1.0 if i == j else 0.0))
            for d in range(BOYUT):
                dU[i][d] += k * V[j][d]
                dV[j][d] += k * U[i][d]
    for p, i in enumerate(range(bas, bas + TOPLU)):
        for yon, (dv, W) in enumerate(((dU[p], WM), (dV[p], WK))):
            u, n = E[p][yon]
            ic = sum(a * b for a, b in zip(u, dv))
            eg = [(dv[d] - u[d] * ic) / n for d in range(BOYUT)]
            for w in (KELIME[i] if yon == 0 else range(G)):
                for d in range(BOYUT):
                    W[w][d] -= 0.15 * eg[d] * (1.0 if yon == 0 else KO[i][w])

ORTAK = [[gom(i)[y][0] for y in (0, 1)] for i in range(1600)]
dogru = tavan = 0
for bas in range(1100, 1600, ADAY):
    oda = list(range(bas, bas + ADAY))
    for i in oda:
        dogru += i == max(oda, key=lambda j: sum(a * b for a, b in zip(ORTAK[i][0],
                                                                      ORTAK[j][1])))
        ayni = [j for j in oda if VERI[j]["tur"] == VERI[i]["tur"]]
        tavan += 1.0 / len([j for j in ayni if VERI[j]["hat"] == VERI[i]["hat"]]
                           if VERI[i]["yazili"] else ayni)
print(f"eslestirme, oda basina {ADAY} aday, {len(SIN)} sinama olayi; "
      f"rastgele eslestirme {1.0 / ADAY:.4f}")
print(f"ortak temsil {dogru / len(SIN):.4f}, kurgunun tavani {tavan / len(SIN):.4f}")
```

```
eslestirme, oda basina 25 aday, 500 sinama olayi; rastgele eslestirme 0.0400
ortak temsil 0.1660, kurgunun tavani 0.2659
```

Taban **0,0400**'dür: yirmi beş adaydan birini rastgele seçmek. Ortak temsil **0,1660** veriyor,
tabanın dört katından fazlası. Üçüncü sayı bu ölçütün tek başına niçin okunamayacağını söylüyor:
kurgunun iki kipte ortak taşıdığı bilgi türden ve — notta yazılıysa — hattan ibarettir, o gruplardan
hesaplanan tavan **0,2659**'dur. 1,0000 ile karşılaştırılan 0,1660 bir başarısızlık gibi görünür;
0,2659 ile karşılaştırıldığında **öğrenilebilirin yüzde 62'si** öğrenilmiştir. Bir ölçütün tavanı da
tabanı kadar ölçülmesi gereken bir sayıdır.

Farkın kaynağı hedeftir: iki izdüşüm de doğrusaldır ve tek başlarına hiçbir şey yapmaz. Karşıtlık
hedefi doğru çifti yaklaştırıp yanlışları uzaklaştırdığında, iki kipin ortak taşıdığı ne varsa
izdüşümler onu aynı yöne çevirmek zorunda kalır.

#### Tek Kip Tek Başına

```python
def sinif_ortalamasi(X):
    """Her sinifin ortalama vektorune aci benzerligi. MODELDIR."""
    def birim(v):
        n = math.sqrt(sum(a * a for a in v)) + 1e-9
        return [a / n for a in v]
    M = {}
    for t in TUR:
        d = [i for i in range(1100) if VERI[i]["tur"] == t]
        M[t] = birim([sum(X[i][k] for i in d) / len(d) for k in range(len(X[0]))])
    return sum(max(TUR, key=lambda t: sum(a * b for a, b in zip(birim(X[i]), M[t])))
               == VERI[i]["tur"] for i in range(1100, 1600)) / len(SIN)


TORBA = [[1.0 if k in KELIME[i] else 0.0 for k in range(len(SOZLUK))] for i in range(1600)]
print(f"olay turu karari, sinif ortalamasi ile; taban {TABAN:.4f}")
for ad, X in (("yalniz not", TORBA), ("yalniz kare", KO),
              ("ortak temsil", [ORTAK[i][0] + ORTAK[i][1] for i in range(1600)])):
    print(f"  {ad:<17} {sinif_ortalamasi(X):.4f}")
```

```
olay turu karari, sinif ortalamasi ile; taban 0.4420
  yalniz not        0.8940
  yalniz kare       0.6140
  ortak temsil      0.8660
```

Üç satır aynı yordamla ve aynı tabana karşı okundu; değişen yalnız temsildir. Yalnız not
**0,8940**, yalnız kare **0,6140**: ikisi de tabanın üstünde, ama kare olay türünün ancak bir
bölümünü taşıyor, çünkü dört türden ikisi karede blok taşımaz.

Üçüncü satır ortak temsilin ne olduğunu ve ne olmadığını söylüyor: **0,8660**, yalnız notun 0,0280
altında. Bu temsil **eşleştirme için** öğrenildi ve orada tabanı dört kat geçti; olay türünde notun
tek başına verdiğine ulaşamıyor. İki kipi bir araya getirmek kendiliğinden kazandırmaz ve bir
temsilin iyiliği hangi görevde ölçüldüğüne bağlıdır.

#### Özet

- İki kip aynı bilgiyi eşit taşımaz: kare hattı her zaman gösterir, notların yalnız 0,2860'ı yazar.
- Ortak temsil eşleştirmede 0,1660 veriyor; taban 0,0400, kurgunun tavanı 0,2659, yani
  öğrenilebilirin yüzde 62'si.
- Olay türünde taban 0,4420, yalnız not 0,8940, yalnız kare 0,6140, ortak temsil 0,8660:
  eğitildiği görevde tabanı dört kat geçen temsil, başka bir görevde tek kipin altında kalabilir.

#### Kurs Kapanışı

On dört dersin hesabı tek tabloda ve her sayı kendi dersinden okundu. **Satırlar ortak birim
taşımaz**; son sütun her satırın ölçütünü ve yönünü yazar. **Fark tek işaret düzeniyle verilir:
yöntemin sayısı eksi alanın tabanı.** Yön küçük iyi olduğunda artı fark tabanın kazandığını söyler.

| Ders | Alanın tabanı | Yöntemin sayısı | Fark | Ölçüt |
|---|---|---|---|---|
| Metin 01 | 748 | 641 | −107 | sözlük boyu, küçük iyi |
| Metin 02 | 0,7383 | 0,8217 | +0,0833 | doğruluk, büyük iyi |
| Metin 03 | 0,4938 | 0,6049 | +0,1111 | komşuluk isabeti, büyük iyi |
| Metin 04 | 0,5061 | 0,9824 | +0,4763 | belirteç doğruluğu, büyük iyi |
| Metin 05 | 0,4420 | 0,9620 | +0,5200 | belge doğruluğu, büyük iyi |
| Metin 06 | 0,4420 | 0,7480 | +0,3060 | belge doğruluğu, büyük iyi |
| Metin 07 | 0,7777 | 0,9445 | +0,1668 | dengeli örtüşme, büyük iyi |
| Metin 08 | 0,3970 | 0,8378 | +0,4408 | belirteç doğruluğu, büyük iyi |
| Görü 01 | 0,4875 | 0,9250 | +0,4375 | doğruluk, büyük iyi |
| Görü 02 | 0,5500 | 0,6687 | +0,1187 | doğruluk, büyük iyi |
| Görü 03 | 0,3011 | 0,9076 | +0,6065 | ortalama örtüşme, büyük iyi |
| Görü 04 | 0,8731 | 0,9851 | +0,1120 | piksel doğruluğu, büyük iyi |
| Görü 05 | 0 | 99 | +99 | kararsızlık, küçük iyi |
| Görü 06 | 0,0400 | 0,1660 | +0,1260 | eşleştirme, büyük iyi |

**Kursun kuralı budur: bir alan ölçütü, o alanın en aptal yordamının aynı ölçütteki sayısı
yazılmadan okunamaz; alanın tabanı yazılmayan sayı ölçülmemiş sayılır.**

Kursun ikinci iddiası aynı tablodan okunur. Yedi derste alanın tabanı şaşırtıcı biçimde yüksek
çıktı: bölütlemede 0,8731, metin 07'de 0,7777, metin 02'de 0,7383, metin 04'te 0,5061 — aynı yordam
varlık düzeyinde 0,0000 alırken — görü 01 ile 02'de 0,5500 ve görü 05'te kararsızlık 0, ki bu
ölçütte yenilemez bir sayıdır. İki derste hiçbir şey öğrenmemiş bir yordam **birinci** oldu: metin
07'de girdiyi kopyalayan, metin 08'de her belirteci işaretleyen yordam, ikisi de örtüşmenin
duyarlılık yönünde 1,0000. Gizleyen ölçütler dört biçimdedir: **dengesiz sınıfta pay olarak okunan
doğruluk**, **sayılan birimden başka bir birimde okunan doğruluk**, **tek yönlü okunan örtüşme** ve
**sabit bir çıktının kendiliğinden kazandığı kararlılık**.

Otuz sekiz derste — on dördü alana özgü — model bir girdiye bakıp bir çıktı verdi ve doğru cevap ya
elde vardı ya da bir ölçüt onu tarif ediyordu. Kararın **sonucunu ancak verildikten sonra**
öğrendiği ve kararın kendisinin **bir sonraki girdiyi değiştirdiği** bir düzende neyin öğrenildiği
hiç sorulmadı. Sonraki kurs, Pekiştirmeli Öğrenme ve Öneri Sistemleri, bu soruyla açılır.

