İçeriğe geç
academia.sh

Ders 21 / 22

İstem ve Bağlam Mühendisliği Farkı

Aynı hata kümesinin iki ayrı çözümle karşılaştırılması: 120 kurgu talepte taban konu isabeti 0,8833 ve arıza kodu isabeti 0,4083, ikisi birden 0,4083. İsteme ayırt edici kural yazmak konu isabetini 0,9667'ye çıkarıyor ve kod isabetine hiç dokunmuyor, kurgu kod tablosunu isteme koymak kod isabetini 0,9167'ye çıkarıyor ve konu isabetine hiç dokunmuyor. On dört konu hatasının onu yalnız yönergeyle, yetmiş bir kod hatasının altmış altısı yalnız bilgiyle düzeliyor ve her sınıfta bir hata ikisiyle de düzelmiyor. Bedel ayrışıyor: yönerge 1680, bilgi 14520 belirteç ekliyor.

İçindekiler

Önceki ders reddedilen kayıtları yeniden sorarak kurtardı ve on dört kayıt hiçbir denemeyle düzelmedi. Bu ders o kalıntının nedenini sorar. Bir yanlış yanıt iki ayrı sebeple yanlış olabilir ve ikisi birbirine benzemez. Model ne yapacağını yanlış anlamış olabilir: yönerge belirsizdir, yanıltıcı bir sözcük kararı çekmiştir. Ya da model bilmediği bir şeyi söylemek zorunda bırakılmıştır: istenen bilgi istemde hiç yoktur ve hiçbir yönerge onu üretemez.

Birinci sınıf istem tasarımının konusudur. İkincisi bağlam mühendisliğinin konusudur: modele ne söylendiği değil, yanına ne konduğu. Bu ders yalnız ayrımı kurar ve ölçer. Hangi belgenin nereden bulunacağı, nasıl getirileceği ve kaç parçanın seçileceği bir erişim hattı sorusudur ve Gömme Vektörleri ve Erişim Artırılmış Üretim kursuna bırakılır; burada kurgu tablo olduğu gibi isteme konur.

  • CD33. Kod bir benzeticidir; gerçek bir uç nokta çağrılmaz. Talepler, arıza kodları ve kod tablosu kurgudur, tohum 20260218.
  • CD34. Görev iki alanlıdır: talebe bir konu ve bir arıza kodu atamak. İki alan iki ayrı hata kaynağı taşır.
  • CD35. Konu hatasının kaynağı yanıltıcı bağlardır. Talebin yan cümlesindeki bir sözcük kararı başka bir konuya çeker. Bu bir yönerge sorunudur.
  • CD36. Kod hatasının kaynağı bilgi eksikliğidir. Kod tablosu istemde yoksa benzetici konunun en yaygın kodunu yazar; on beş koddan yalnız beşi böyle bulunabilir.
  • CD37. Yönerge çözümü isteme bir ayırt edici kural yazar. Kural her zaman izlenmez; benzetici kuralı yanıtların bir payında uygular.
  • CD38. Bilgi çözümü kurgu kod tablosunun tamamını isteme koyar. Erişim yapılmaz: hangi satırın gerektiği aranmaz, tablo bütünüyle verilir. Model tabloyu kendi tanım metinleriyle eşleştirir ve bir payında yanlış satırı okur.
  • CD39. Bir hata, o alandaki değerin yanlış olmasıdır; hatalar alan bazında sayılır. Aynı kayıt iki hata birden taşıyabilir.
  • CD40. Bedel giriş belirteci olarak yazılır ve ayrıca düzelen hata başına belirteç olarak verilir; iki koşum için ikinci tohum 20260219’dur.

İki Hatanın İki Ayrı Kaynağı

İki örnek talep dört düzenekte yan yana konur. Birincisi her iki hatayı birden taşır, ikincisi yalnız kod hatasını.

# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz. Kod tablosu da
# KURGU'dur ve erisim yapilmadan, oldugu gibi isteme konur.
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 ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


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


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"),
         ("faturami odedim ama sistemde borc gorunuyor", "fatura"),
         ("fatura ayrintisini nereden gorebilirim", "fatura"),
         ("evde su akmiyor bir ariza var galiba", "ariza"),
         ("baglanti bozuk oldu ve hic calismiyor", "ariza"),
         ("ariza kaydi actim ama ekip gelmedi", "ariza"),
         ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"),
         ("sayac degisimi icin randevu istiyorum", "sayac"),
         ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"),
         ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"),
         ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"),
         ("birim ucret abone tipine gore degisiyor mu", "tarife"),
         ("mahallede kesinti var ne zaman gelecek", "kesinti"),
         ("planli kesinti duyurusu nereden takip edilir", "kesinti"),
         ("aksamdan beri kesinti yasiyoruz", "kesinti")]
TALEP = []
for i in range(120):                    # 120 KURGU destek talebi
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    TALEP.append({"no": 4001 + i, "konu": k,
                  "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]})

IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
KODLAR = [("FT-21", "fatura tutari yuksek geldi"),
          ("FT-34", "odenen fatura borc gorunuyor"),
          ("FT-47", "fatura ayrinti talebi"), ("AR-12", "evde su akmiyor sikayeti"),
          ("AR-25", "baglanti bozuk calismiyor"), ("AR-38", "acik kayit ekip gelmedi"),
          ("SY-16", "endeks yanlis girilmis"), ("SY-29", "sayac degisim randevusu"),
          ("SY-42", "endeks ile fatura uyusmuyor"), ("TR-13", "tarife basamagi sorusu"),
          ("TR-26", "tarife degisiklik talebi"), ("TR-39", "birim ucret abone tipi"),
          ("KS-15", "mahalle kesintisi suresi"), ("KS-28", "planli duyuru takibi"),
          ("KS-41", "aksamdan beri kesinti")]
KOD = {t: KODLAR[i][0] for i, (t, _) in enumerate(KALIP)}
KONU_KODU = {}
for i, (t, k) in enumerate(KALIP):
    KONU_KODU.setdefault(k, KODLAR[i][0])   # belgesiz durumda konunun ilk kodu
BELGE = " ; ".join(f"{k} {a}" for k, a in KODLAR)
SAYAC = [0]


def cekilis(istem, tohum, tuz):
    """Her karar icin ayri tuzlanmis tek cekilis; kararlar birbirine baglanmaz."""
    return uretec((tohum + tuz) ^ izno(istem))()


def cagir(istem, talep, tohum=TOHUM):
    """Konu ve ariza kodu birlikte istenir. Kod tablosu istemde yoksa model
    konunun en yaygin kodunu yazar; varsa tanimlarla ortusmeye bakarak secer."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    uyar = "ayirt" in bel and cekilis(istem, tohum, 91) < 0.78
    tuzak_agirligi = 0.9 if uyar else 1.3               # istemdeki ayirt edici kural
    p = {k: 0.15 for k in KONU}
    for t in belirtecle(talep["metin"]):
        for tablo, w in ((IZ, 1.0), (TUZAK, tuzak_agirligi)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    k = max(sorted(p), key=lambda a: p[a])
    if "tablo" not in bel:                              # kod tablosu istemde yok
        return k, KONU_KODU[k]
    tb = set(belirtecle(talep["metin"]))
    puan = [(len(tb & set(belirtecle(a))), -i) for i, (_, a) in enumerate(KODLAR)]
    i = -max(puan)[1]
    if cekilis(istem, tohum, 17) < 0.08:                # belgeyi yanlis okuma payi
        i = (i + 1) % len(KODLAR)
    return k, KODLAR[i][0]


AYIRT = "Ayirt edici kural: yan cumledeki sozcukler etiketi belirlemez . "
TABLO = "Ariza kodu tablosu: " + BELGE + " . "
print(f"KURGU kod tablosu {len(KODLAR)} satir, {len(belirtecle(BELGE))} belirtec")
print("ornek satirlar:", " | ".join(f"{k} {a}" for k, a in KODLAR[3:6]))
for j in (3, 0):
    x = TALEP[j]
    print(f"\ntalep {x['no']} : {x['metin']}")
    print(f"  gercek        konu {x['konu']:<8} kod {KOD[x['metin']]}")
    for ad, onek in (("taban", ""), ("yonerge", AYIRT), ("bilgi", TABLO),
                     ("ikisi", AYIRT + TABLO)):
        k, kod = cagir(onek + f"Talep {x['no']} : {x['metin']}", x)
        d = "dogru" if (k == x["konu"] and kod == KOD[x["metin"]]) else ""
        print(f"  {ad:<13} konu {k:<8} kod {kod}  {d}")
KURGU kod tablosu 15 satir, 116 belirtec
ornek satirlar: AR-12 evde su akmiyor sikayeti | AR-25 baglanti bozuk calismiyor | AR-38 acik kayit ekip gelmedi

talep 4004 : ariza kaydi actim ama ekip gelmedi
  gercek        konu ariza    kod AR-38
  taban         konu kesinti  kod KS-15  
  yonerge       konu ariza    kod AR-12  
  bilgi         konu kesinti  kod AR-38  
  ikisi         konu ariza    kod AR-38  dogru

talep 4001 : planli kesinti duyurusu nereden takip edilir
  gercek        konu kesinti  kod KS-28
  taban         konu kesinti  kod KS-15  
  yonerge       konu kesinti  kod KS-15  
  bilgi         konu kesinti  kod KS-28  dogru
  ikisi         konu kesinti  kod KS-28  dogru

Üstteki talep iki hatayı birden taşıyor. Konu kesinti çıkıyor, çünkü talebin son iki sözcüğü yanıltıcı bir bağ tetikliyor; ayırt edici kural yazıldığında konu arizaya dönüyor. Ama aynı satırda kod hâlâ yanlış: AR-12, doğrusu AR-38. Yönerge konuyu düzeltti ve kodu düzeltemedi, çünkü doğru kod istemde hiçbir yerde yazmıyordu. Tablo konduğunda kod AR-38 oluyor, bu kez konu yanlış kalıyor. Kayıt ancak ikisi birlikte doğru oluyor.

Alttaki talebin konusu baştan doğrudur ve yalnız kodu yanlıştır. Yönerge satırı tabanla birebir aynıdır: konu kesinti kalıyor, kod KS-15 kalıyor. İsteme on dört belirteçlik bir kural eklendi ve çıktının hiçbir alanı değişmedi. Tablo ise kodu tek adımda KS-28’e getiriyor. Aynı hata biçimi, iki ayrı çözüm — ve yanlış olanı seçmenin bedeli yalnız belirteçtir, kazancı hiç yoktur.

İki örneğin birlikte söylediği şey şudur: bir yanlış yanıta bakarak hangi düzeneğin gerektiği anlaşılmaz. Yanlışın kendisi iki durumda da aynı görünür. Ayrım ancak iki düzenek de ayrı ayrı denenip sayıldığında ortaya çıkar.

Hangi Hata Hangisiyle Düzeliyor

Aynı 120 talep dört düzenekte koşturulur ve hatalar alan bazında sayılır.

HAT = [("taban", ""), ("+ yonerge", AYIRT), ("+ bilgi", TABLO),
       ("+ ikisi", AYIRT + TABLO)]


def olc(onek, tohum=TOHUM):
    SAYAC[0] = 0
    d, g = [], 0
    for x in TALEP:
        istem = onek + f"Talep {x['no']} : {x['metin']}"
        k, kod = cagir(istem, x, tohum)
        d.append((k == x["konu"], kod == KOD[x["metin"]]))
        g += len(belirtecle(istem))
    return d, g


S = {ad: olc(onek) for ad, onek in HAT}
print("hat        konu isabeti  kod isabeti  ikisi birden  giris belirteci")
for ad, _ in HAT:
    d, g = S[ad]
    print(f"{ad:<10} {sum(a for a, b in d) / 120:>12.4f}  {sum(b for a, b in d) / 120:>11.4f}"
          f"  {sum(a and b for a, b in d) / 120:>12.4f}  {g:>15}")
print("\nhata sinifi   taban hata  yonergeyle  bilgiyle  ikisiyle  hicbiriyle")
for ad, j in (("konu hatasi", 0), ("kod hatasi", 1)):
    n = [i for i in range(120) if not S["taban"][0][i][j]]
    y = sum(S["+ yonerge"][0][i][j] for i in n)
    b = sum(S["+ bilgi"][0][i][j] for i in n)
    ik = sum(S["+ ikisi"][0][i][j] for i in n)
    h = sum(not (S["+ yonerge"][0][i][j] or S["+ bilgi"][0][i][j]
                 or S["+ ikisi"][0][i][j]) for i in n)
    print(f"{ad:<13} {len(n):>10}  {y:>10}  {b:>8}  {ik:>8}  {h:>10}")
b1 = olc(AYIRT + TABLO, TOHUM + 1)[0]
print(f"\nikinci kosum (+ ikisi): konu {sum(a for a, _ in b1) / 120:.4f}, "
      f"kod {sum(b for _, b in b1) / 120:.4f}, ikisi birden "
      f"{sum(a and b for a, b in b1) / 120:.4f}")
hat        konu isabeti  kod isabeti  ikisi birden  giris belirteci
taban            0.8833       0.4083        0.4083             1534
+ yonerge        0.9667       0.4083        0.4083             3214
+ bilgi          0.8833       0.9167        0.8000            16054
+ ikisi          0.9583       0.9000        0.8667            17734

hata sinifi   taban hata  yonergeyle  bilgiyle  ikisiyle  hicbiriyle
konu hatasi           14          10         0         9           1
kod hatasi            71           0        66        63           1

ikinci kosum (+ ikisi): konu 0.9667, kod 0.8917, ikisi birden 0.8583

İlk tablonun ikinci ve üçüncü satırı ayrımı çıplak biçimde gösteriyor. Yönerge konu isabetini 0,8833’ten 0,9667’ye çıkarıyor ve kod isabetini 0,4083’te olduğu gibi bırakıyor. Bilgi kod isabetini 0,4083’ten 0,9167’ye çıkarıyor ve konu isabetini 0,8833’te olduğu gibi bırakıyor. İki düzenek aynı görevde çalışıyor ama hiç aynı hataya dokunmuyor.

İkinci tablo bunu hata başına sayıyor. On dört konu hatasının onu yönergeyle düzeliyor, sıfırı bilgiyle. Yetmiş bir kod hatasının altmış altısı bilgiyle düzeliyor, sıfırı yönergeyle. İki sütunun biri diğerinin sıfırıdır; bu, iki çözümün birbirinin yerine geçemeyeceğinin sayısal karşılığıdır. Bir sistemi iyileştirmenin ilk adımı, hangi hatanın hangi sınıfta olduğunu saymaktır — çünkü yanlış sınıfa harcanan her belirteç boşa gider.

Her sınıfta bir hata hiçbir düzenekle düzelmiyor. Konu tarafında bu, ayırt edici kuralın izlenmediği bir çağrıdır; kod tarafında tablonun yanlış satırının okunduğu bir çağrıdır. İkisi de istem tasarımının değil, üreticinin belirsizliğinin kalıntısıdır ve daha fazla metin yazarak kapanmaz.

İki Çözümün Bedeli

Bedel sütunu iki çözümü keskin biçimde ayırıyor. Yönerge giriş belirtecini 1534’ten 3214’e çıkarıyor: talep başına on dört, toplamda 1680 belirteç. Bilgi ise 16054’e çıkarıyor: talep başına yüz yirmi bir, toplamda 14520 belirteç ve tabanın 10,5 katı. Bir kod tablosunun tamamını her isteğe koymanın bedeli budur.

Düzelen hata başına okunduğunda tablo yumuşuyor ama tersine dönmüyor: yönerge on hatayı 1680 belirteçle düzeltiyor, hata başına 168 belirteç; bilgi altmış altı hatayı 14520 belirteçle düzeltiyor, hata başına 220 belirteç. Bilgi daha pahalıdır ama karşılığında ölçülemeyecek kadar çok hata düzeltir: taban 71 kod hatası taşıyordu ve yönergeye ne kadar metin eklenirse eklensin bunların hiçbiri düzelmezdi.

Son satır iki düzeneğin birlikte çalışmasının bedelini de gösteriyor. İkisi birden doğru olan kayıt oranı 0,4083’ten 0,8667’ye çıkıyor; ikinci koşumda aynı sayı 0,8583, yani iki koşum farkı 0,0084. Kazanç bu farkın elli katından büyük olduğu için rahatça ölçülebilir. Buna karşın birleşik hat, tek tek hatlardan her alanda biraz daha kötüdür: konu 0,9667 yerine 0,9583, kod 0,9167 yerine 0,9000. İstem uzadıkça hem kuralın izlendiği hem tablonun doğru okunduğu çağrıların payı azalıyor. Ölçülmeden değiştirilen istem bir iyileştirme değil bir tahmindir, ve iki iyileştirmenin toplamı ikisinin toplamı değildir.

Özet

  • Bir yanlış yanıt ya modelin ne yapacağını yanlış anlamasından ya da bilmediği bir şeyi söylemek zorunda kalmasından gelir; ikisi ayrı düzeneklerle düzelir.
  • Yönerge konu isabetini 0,8833’ten 0,9667’ye çıkarır ve kod isabetine hiç dokunmaz; bilgi kod isabetini 0,4083’ten 0,9167’ye çıkarır ve konu isabetine hiç dokunmaz.
  • On dört konu hatasının onu yalnız yönergeyle, yetmiş bir kod hatasının altmış altısı yalnız bilgiyle düzelir; her iki sütunun karşılıklı değeri sıfırdır.
  • Her sınıfta bir hata hiçbir düzenekle düzelmez: bunlar üreticinin belirsizliğinin kalıntısıdır.
  • Yönerge 1680, bilgi 14520 belirteç ekler; düzelen hata başına 168 ve 220 belirteç. Bilgi pahalıdır ama yönergenin hiç ulaşamadığı hataları düzeltir.
  • İkisi birden doğru kayıt oranı 0,4083’ten 0,8667’ye çıkar, ama birleşik hat her alanda tek tek hatlardan biraz daha kötüdür.

Sonraki Adım

Bu derste hatalar iki kaynağa ayrıldı ve her ikisi de tek tek kayıtlarda ölçüldü. Sorulmayan şey, hataların kimin üzerinde toplandığıdır. Bir sistem 0,8667 oranında doğru olabilir ve kalan yanlışların tamamı belirli bir abone kümesinde toplanabilir; bu durumda ortalama iyidir ve o küme için sistem çalışmıyordur. Sonraki ders bunu ölçer: alt grup açıklığı istemle ne kadar daraltılabiliyor, hangi kısmı kalıyor, ve istemin veri yanlılığını niçin çözmediği sayıyla gösterilir.

İ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