İçeriğe geç
academia.sh

Ders 10 / 14

Yetenekler ve Sınırlar

Yirmi dört kurgu destek talebinde beş görev sınıfının düzeneksiz çağrıyla ölçülmesi: özetleme 0,7500, sınıflandırma 0,8750, sıralama 0,6250, sayma 0,4167 ve kesin hesap 0,2917. Tohum değiştirildiğinde ilk üç sınıfın sayısı oynuyor, son ikisi hiç oynamıyor ve yanıtı değişen istek sayısı 0/24 çıkıyor. Sayma isabeti çekimli biçim taşımayan 10/24 isteğe, kesin hesap isabeti öbek sınırını aşan taşıma taşımayan 7/24 isteğe birebir eşit. Üç koşumlu çoğunluk düzeneği üç kat belirteçle bu iki sınıfta hiçbir şey değiştirmiyor, hesabı belirteç dışına çıkaran yordam düzeneği ikisini de 1,0000'a taşıyor.

İçindekiler

Önceki ders bağlam penceresini bir sınır olarak ölçtü ve pencerenin nasıl doldurulacağının bir karar olduğunu gösterdi. Kırpma kararları kaç belirteç kazandırıyor ve isabeti ne kadar düşürüyor sorusu yanıtlandı. Sorulmayan şey daha önce gelir: pencereye ne konulursa konulsun, modelin neyi iyi yaptığı hiç ölçülmedi. Bir görev iyi gitmiyorsa suç istemde mi, pencerede mi, yoksa görevin kendisinde mi.

Bu ders beş görev sınıfını aynı veriyle, aynı düzeneksiz çağrıyla koşturur ve isabeti sınıf başına yazar. İki sınıfta sayı çöker, ve çöküşün kaynağı istemde değil belirteç düzeyindedir.

  • DL46. Kurgu talep kümesi 24 kısa Türkçe destek talebidir. Talepler beş ana tümce ile altı ek tümcenin birleşiminden üretilir ve her talebin sonunda iki sayaç okuması durur. Metinler, sınıflar ve okumalar kurgudur.
  • DL47. Model bir benzeticidir; gerçek bir uç nokta çağrılmaz. Benzetici standart kitaplıkla yazılmıştır, tohumu 20260218’dir ve yanıtını yalnız belirteç dizisinden üretir.
  • DL48. Belirteçleyici kurgudur ve bu konunun ilk dersinde kurulan ölçüyü sürdürür: harf öbekleri dörder, rakam öbekleri ikişer bölünür.
  • DL49. Beş görev sınıfı ölçülür: özetleme, sınıflandırma, sıralama, sayma ve kesin hesap. Her sınıfın ölçüsü isabettir: yirmi dört istekte kaçında yanıt doğru.
  • DL50. Bedel üç birimle yazılır: istek başına giriş belirteci, çağrı sayısı ve gecikme sınıfı. Ham süre yazılmaz.
  • DL51. Belirsizlik iki koşumla ölçülür. Aynı görev kümesi tohum 20260218 ve tohum 20260219 ile koşturulur; ayrıca iki koşumda yanıtı değişen istek sayısı basılır.

Beş Görev Sınıfında Çıplak Çağrı

# ORTAK -- KURGUDUR. Asagidaki benzetici gercek bir uc nokta cagirmaz; standart
# kitaplikla yazilmistir ve bir dil modelinin olculebilir yuzeyini tasir.
TOHUM, M32 = 20260218, 0xFFFFFFFF


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 belirtecle(metin):
    """Kurgu belirtecleyici: harf obekleri dorder, rakam obekleri ikiser bolunur."""
    cikti, tampon = [], ""
    for ch in metin + " ":
        if ch.isalnum():
            tampon += ch
            continue
        if tampon:
            n = 2 if tampon.isdigit() else 4
            cikti += [tampon[i:i + n] for i in range(0, len(tampon), n)]
            tampon = ""
        if ch.strip():
            cikti.append(ch)
    return cikti


BAS = [  # (ana tumce, gercek sinif)
    ("sayac okunmadi tahmini fatura cikti", "olcum"),
    ("fatura tutari gecen aya gore iki kat cikti", "odeme"),
    ("gece boyunca su basinci dustu", "tesisat"),
    ("planli kesinti bildirimi ulasmadi", "kesinti"),
    ("abonelik devri sayaca islenmedi", "sozlesme"),
]
EK = ["sayacin numarasi degistirilmis olabilir", "adres bilgisi eski gorunuyor",
      "onceki ay ayni sorun yasanmadi", "sayaca ulasilamiyor kapi kapali",
      "kesinti suresi beklenenden uzun surdu", "otomatik talimat sayacta yok"]
SOZLUK = {  # sinif -> benzeticinin tanidigi obekler ve kurgu oncelik
    "kesinti": ({"kesi", "bild"}, 1), "olcum": ({"okun", "olcu", "tahm"}, 2),
    "tesisat": ({"basi", "vana", "tesi", "dust"}, 3),
    "odeme": ({"fatu", "odem", "tuta", "tali"}, 4),
    "sozlesme": ({"abon", "devr", "sozl", "adre"}, 5),
}
SINIFLAR = list(SOZLUK)
GOREV = {"ozetleme": 11, "siniflandirma": 23, "siralama": 41, "sayma": 59, "kesin_hesap": 71}
ORN = {}
TALEP = []
for i in range(24):
    r = uretec(TOHUM + 31 * i)
    a, b = 100000 + int(r() * 380000), 100000 + int(r() * 380000)
    TALEP.append({"no": 4100 + i, "sinif": BAS[i % 5][1], "a": a, "b": b,
                  "ana": BAS[i % 5][0], "ek": EK[(5 * i + 2) % 6],
                  "metin": f"{BAS[i % 5][0]}, {EK[(5 * i + 2) % 6]}."
                           f" ana sayac {a} ara sayac {b}."})


def ornek(gorev, tohum, t):
    """Ornekleme cizelgesi: gorev ve tohum basina tek akis, istek basina tek deger."""
    if (gorev, tohum) not in ORN:
        r = uretec(tohum + 1009 * GOREV[gorev])
        ORN[(gorev, tohum)] = [r() for _ in range(24)]
    return ORN[(gorev, tohum)][t["no"] - 4100]


def cagir(gorev, t, tohum, ornekleme=True):
    """Benzetici: yaniti yalniz belirtec dizisinden uretir. Aday arasindan secim
    yapilan gorevlerde ornekleme ikinci adayi getirebilir; sayma ile kesin hesap
    aday uretmez, belirtec dizisi uzerinde tek yol izler."""
    bel = belirtecle(t["metin"])
    if gorev == "sayma":
        return bel.count("saya")
    if gorev == "kesin_hesap":
        p = [(str(t["a"])[k:k + 2], str(t["b"])[k:k + 2]) for k in range(0, 6, 2)]
        return int("".join(f"{(int(x) + int(y)) % 100:02d}" for x, y in p))
    r = ornek(gorev, tohum, t)
    if gorev == "ozetleme":                       # ozete hangi tumce girecek
        tumce = sorted([t["ana"], t["ek"]], key=lambda c: -len(belirtecle(c)))
        return tumce[1] if ornekleme and r < 0.14 else tumce[0]
    puan = sorted(SINIFLAR, key=lambda s: (-sum(b in SOZLUK[s][0] for b in bel), s))
    return puan[1] if ornekleme and r < 0.14 else puan[0]


def olc(tohum, ornekleme=True):
    d, dizi = {}, 0
    d["ozetleme"] = sum(cagir("ozetleme", t, tohum, ornekleme) == t["ana"] for t in TALEP) / 24
    d["siniflandirma"] = sum(cagir("siniflandirma", t, tohum, ornekleme) == t["sinif"]
                             for t in TALEP) / 24
    for g in range(24):
        uc = [TALEP[g], TALEP[(g + 7) % 24], TALEP[(g + 13) % 24]]
        gercek = [t["no"] for t in sorted(uc, key=lambda t: (SOZLUK[t["sinif"]][1], t["no"]))]
        tahmin = [t["no"] for t in sorted(uc, key=lambda t: (
            SOZLUK[cagir("siralama", t, tohum, ornekleme)][1], t["no"]))]
        dizi += gercek == tahmin
    d["siralama"] = dizi / 24
    d["sayma"] = sum(cagir("sayma", t, tohum) == t["metin"].replace(",", " ")
                     .replace(".", " ").split().count("sayac") for t in TALEP) / 24
    d["kesin_hesap"] = sum(cagir("kesin_hesap", t, tohum) == t["a"] + t["b"] for t in TALEP) / 24
    return d


A, B = olc(TOHUM), olc(TOHUM + 1)
ORT = sum(len(belirtecle(t["metin"])) for t in TALEP) / 24
print(f"kurgu gorev kumesi: {len(TALEP)} destek talebi, bes gorev sinifi")
print(f"istek basina giris belirteci {ORT:.1f}, cagri 1, gecikme sinifi tek cagri")
print("gorev           tohum 20260218  tohum 20260219  yaniti degisen istek")
for g in GOREV:
    fark = sum(str(cagir(g, t, TOHUM)) != str(cagir(g, t, TOHUM + 1)) for t in TALEP)
    print(f"{g:<14}      {A[g]:.4f}        {B[g]:.4f}          {fark:>2}/24")
kurgu gorev kumesi: 24 destek talebi, bes gorev sinifi
istek basina giris belirteci 33.3, cagri 1, gecikme sinifi tek cagri
gorev           tohum 20260218  tohum 20260219  yaniti degisen istek
ozetleme            0.7500        0.6667           4/24
siniflandirma       0.8750        0.8750           2/24
siralama            0.6250        0.4583          11/24
sayma               0.4167        0.4167           0/24
kesin_hesap         0.2917        0.2917           0/24

Sayı sınıftan sınıfa düşüyor: sınıflandırma 0,8750, özetleme 0,7500, sıralama 0,6250, sayma 0,4167, kesin hesap 0,2917. Aynı model, aynı istek, aynı belirteç sayısı. Değişen tek şey görevin ne istediği.

Sıralamanın üstteki üçlü içinde en düşük sayıyı vermesinin kendi nedeni var. Sıralama tek bir karar değil, üç kararın birleşimidir: benzetici her talebi ayrı ayrı sınıflandırır ve üçlüyü sınıfların önceliğine göre dizer. Tek bir talepte yapılan hata bütün diziyi bozduğu için, sınıf başına 0,8750 olan isabet üçlü başına 0,6250’ye iniyor. Bileşik görevlerin sayısı bileşenlerinin sayısından her zaman düşüktür ve bu ders boyunca sürecek bir kuraldır.

Üstteki üç sınıfın ortak yanı da görülüyor: hepsi bir seçim görevidir. Özetleme iki tümceden birini, sınıflandırma beş etiketten birini, sıralama üç talebin dizilişini seçiyor. Seçim görevlerinde belirteç yüzeyi yeterli bilgiyi taşıyor, çünkü doğru yanıt zaten metnin içinde bir yerde duruyor. Alttaki iki sınıf ise üretim görevidir: doğru yanıt metnin içinde bulunmuyor, metinden hesaplanması gerekiyor. Ayrımı gösteren şey ise ölçünün kendisi değil, ölçünün nasıl alındığıdır.

Son sütun bunu tek başına söylüyor. İlk üç sınıfta tohum değişince yanıtı değişen istek var: sıralamada 11/24, özetlemede 4/24, sınıflandırmada 2/24. Sınıflandırmanın iki koşumdaki isabeti aynı çıkıyor ama aynı isteklerde değil: iki istek yanıt değiştirdi, biri düzeldi biri bozuldu. Son iki sınıfta ise fark 0/24. Sayma ve kesin hesap iki koşumda birebir aynı yanlış yanıtı veriyor. Bu, örneklemenin gürültüsü değil.

Sayma ve Kesin Hesabın Belirteç Düzeyindeki Kaynağı

def cekimli(m):
    return [w for w in m.replace(",", " ").replace(".", " ").split()
            if w.startswith("sayac") and w != "sayac"]


t = TALEP[4]
print("talep:", t["ana"] + ",", t["ek"])
print("belirtec:", " ".join(belirtecle(t["ana"])))
gercek = t["metin"].replace(",", " ").replace(".", " ").split().count("sayac")
print(f"sayac gecisi: gercek {gercek}, benzetici {cagir('sayma', t, TOHUM)},"
      f" cekimli bicim {cekimli(t['metin'])}")
print(f"toplama: {t['a']} + {t['b']} = {t['a'] + t['b']},"
      f" benzetici {cagir('kesin_hesap', t, TOHUM)}")
tasima = sum(any(int(str(x["a"])[k:k + 2]) + int(str(x["b"])[k:k + 2]) > 99 for k in (2, 4))
             for x in TALEP)
cekim = sum(bool(cekimli(x["metin"])) for x in TALEP)
print(f"obek sinirini asan tasima tasiyan istek {tasima}/24 -> kalan {24 - tasima}/24")
print(f"cekimli sayac bicimi tasiyan istek {cekim}/24 -> kalan {24 - cekim}/24")
talep: abonelik devri sayaca islenmedi, kesinti suresi beklenenden uzun surdu
belirtec: abon elik devr i saya ca isle nmed i
sayac gecisi: gercek 2, benzetici 3, cekimli bicim ['sayaca']
toplama: 139039 + 302204 = 441243, benzetici 431243
obek sinirini asan tasima tasiyan istek 17/24 -> kalan 7/24
cekimli sayac bicimi tasiyan istek 14/24 -> kalan 10/24

Sayma önce. Model, metinde sözcük görmüyor; öbek görüyor. sayaca sözcüğü saya ve ca öbeklerine bölünüyor, sayac sözcüğü de saya ile başlıyor. Belirteç dizisinde ikisi aynı başlangıcı paylaştığı için model çekimli biçimi de sayıyor ve 2 yerine 3 yazıyor. Türkçenin eklemeli yapısı bunu istisna değil kural yapıyor: çekimli bir sayaç biçimi taşıyan istek 14/24, taşımayan 10/24. Sayma isabeti 0,4167, yani tam olarak 10/24. Model sayamadığı için değil, sayacağı birimi göremediği için yanılıyor.

Kesin hesap aynı kusurun sayı tarafı. 139039 okuması 13, 90, 39 öbeklerine bölünüyor. Model öbekleri karşılıklı topluyor ve her öbeği iki basamakta tutuyor: 90 + 22 sonucu 112 olduğunda üçüncü basamak, yani taşıma, bir sonraki öbeğe geçemiyor çünkü o öbek zaten yazılmış durumda. Çıkan sayı 431243, doğrusu 441243: fark tam olarak kaybolan taşımadır. Öbek sınırını aşan taşıma taşıyan istek 17/24, taşımayan 7/24. Kesin hesap isabeti 0,2917, yani tam olarak 7/24. İki sayı da veriden değil belirteçlemeden geliyor; tohum değiştirmek onları oynatmıyor.

Çöken Sınıfa Düzenek Eklemek

DOGRU = {"siniflandirma": lambda t: t["sinif"], "kesin_hesap": lambda t: t["a"] + t["b"],
         "sayma": lambda t: t["metin"].replace(",", " ").replace(".", " ")
         .split().count("sayac")}


def cogunluk(gorev):                        # duzenek 1: uc kosum, cogunluk yaniti
    s = 0
    for t in TALEP:
        y = [cagir(gorev, t, th) for th in (TOHUM, TOHUM + 1, TOHUM + 2)]
        s += max(y, key=y.count) == DOGRU[gorev](t)
    return s / 24


def yordamla(gorev, t):
    """Duzenek 2: model degeri ayiklar, hesabi belirtec disinda bir yordam yapar."""
    if gorev == "kesin_hesap":
        sayi, o, bel = [], 0, belirtecle(t["metin"])
        while o < len(bel):                     # bitisik rakam obekleri tek sayi
            p = ""
            while o < len(bel) and bel[o].isdigit():
                p, o = p + bel[o], o + 1
            o += 1 if not p else 0
            if p:
                sayi.append(int(p))
        return sum(sayi[:2])
    return sum(w == "sayac" for w in t["metin"].replace(",", " ").replace(".", " ").split())


print("gorev           ciplak  cogunluk  yordam")
for g in ("siniflandirma", "sayma", "kesin_hesap"):
    y = ("  -   " if g == "siniflandirma" else
         f"{sum(yordamla(g, t) == DOGRU[g](t) for t in TALEP) / 24:.4f}")
    print(f"{g:<14}  {olc(TOHUM)[g]:.4f}  {cogunluk(g):.4f}    {y}")
ek = sum(len(belirtecle(str(DOGRU['kesin_hesap'](t)))) for t in TALEP) / 24
print(f"bedel -- ciplak cagri: {ORT:.1f} belirtec, 1 cagri, gecikme sinifi tek cagri")
print(f"bedel -- cogunluk: {3 * ORT:.1f} belirtec, 3 cagri, gecikme sinifi paralel")
print(f"bedel -- yordam: {2 * ORT + ek:.1f} belirtec, 2 cagri, gecikme sinifi zincir")
gorev           ciplak  cogunluk  yordam
siniflandirma   0.8750  0.9167      -   
sayma           0.4167  0.4167    1.0000
kesin_hesap     0.2917  0.2917    1.0000
bedel -- ciplak cagri: 33.3 belirtec, 1 cagri, gecikme sinifi tek cagri
bedel -- cogunluk: 99.9 belirtec, 3 cagri, gecikme sinifi paralel
bedel -- yordam: 69.6 belirtec, 2 cagri, gecikme sinifi zincir

Çoğunluk düzeneği aynı isteği üç tohumla çağırıp en sık gelen yanıtı alıyor. Sınıflandırmada işe yarıyor: 0,8750 sayısı 0,9167’ye çıkıyor, çünkü oradaki hata örneklemeden geliyor ve üç koşumun ikisi doğruyu tutuyor. Sayma ve kesin hesapta ise sayı kılını kıpırdatmıyor: 0,4167 ve 0,2917 aynen kalıyor. Bedel gerçek ve peşin, çağrı sayısı üçe, belirteç 99,9’a çıkıyor. Yapısal bir hatanın üstüne konan istatistiksel düzenek, hatayı üç kez tekrarlamaktan başka bir şey yapmıyor.

İkinci düzenek işi belirteç katmanının dışına taşıyor: model yalnız sayıları ayıklıyor, toplamayı ve saymayı bir yordam yapıyor. İsabet iki sınıfta da 1,0000. Bedel iki çağrı, 69,6 belirteç ve zincir gecikme sınıfıdır — çünkü ikinci çağrı birincinin sonucunu beklemek zorundadır, çoğunluk düzeneğinin üç çağrısı ise paralel gidebilir. Daha ucuz olan düzenek kazandıran düzenektir: çoğunluk 99,9 belirteçle hiçbir şey vermiyor, yordam 69,6 belirteçle sınıfı tamamen düzeltiyor. Bedeli yazmadan bu iki düzenek birbirinden ayrılamazdı.

Özet

  • Beş görev sınıfı aynı kurgu talep kümesinde düzeneksiz çağrıyla ölçülünce isabet 0,8750’den 0,2917’ye iniyor: sınıflandırma 0,8750, özetleme 0,7500, sıralama 0,6250, sayma 0,4167, kesin hesap 0,2917.
  • Tohum değiştiğinde ilk üç sınıfta yanıtı değişen istek var (11/24, 4/24, 2/24), son iki sınıfta 0/24; sayma ve kesin hesabın hatası örnekleme gürültüsü değil.
  • Sayma isabeti çekimli biçim taşımayan 10/24 isteğe, kesin hesap isabeti öbek sınırını aşan taşıma taşımayan 7/24 isteğe birebir eşittir; iki sayı da belirteçlemeden gelir.
  • Üç koşumlu çoğunluk düzeneği sınıflandırmayı 0,9167’ye taşıyor ama sayma ile kesin hesapta hiçbir şey değiştirmiyor; bedeli 99,9 belirteç ve üç çağrıdır.
  • Hesabı belirteç katmanının dışına çıkaran yordam düzeneği iki sınıfı da 1,0000’a taşıyor; bedeli 99,6 belirteç, iki çağrı ve zincir gecikme sınıfıdır.

Sonraki Adım

Bu derste ölçülen yanlışlar bir bakıma dürüsttü: model sayamadığında yanlış bir sayı yazdı ve yanlış olduğu tek satırda görüldü. Sonraki ders daha zor bir yanlış türünü ele alır. Model bir soruya, elinde hiçbir dayanak yokken de akıcı ve kendinden emin bir yanıt üretir; yanıtın biçimi doğru olanla aynıdır ve yanlışlığı yanıtın kendisine bakarak anlaşılmaz. Bunun ölçüsü isabet değil uydurma oranıdır: yanıttaki kaç iddia bir belgeye dayanıyor. Aynı ders, müfredatın ikinci iddiasını ilk kez gösterir: uydurmayı azaltmak için eklenen üç düzenekten biri, uydurmayı gerçekten düşürürken isabeti de düşürür, ve bu saklanmaz.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat