Ders 11 / 16
Sorgu Dönüştürme
Kullanıcının yazdığı sorgunun dizine gitmeden önce tek bir model çağrısıyla belge diline çevrilmesi ve bu adımın kazandırdığı ile kaybettirdiğinin ayrı ayrı sayılması: kırk sorguluk kurgu kümede kısa yazımın tabanı 0,3750 anma ve 0,2000 üretim iken genişletme ikisini 0,7500 ve 0,7000'e çıkarıyor, yani dizin dilinde yazılmış sorgunun bıraktığı yere geliyor. Aynı düzenek uzun yazımda tabanı 0,5500'den 0,3500'e, yeniden yazma ise 0,2500'e düşürüyor, çünkü dönüştürücünün doğru kavramı bulma payı 0,9500'den 0,3500'e iniyor. Bedel her iki kümede de sorgu başına bir çağrı ve dört yüzden iki bin üç yüz altmışa kadar ek belirteçtir; iki koşum farkı anmada 0,0500, üretimde 0,1000 ölçüldü.
İçindekiler
Önceki dört ders hattın belge tarafını kurdu: dağarcık hazırlandı, parçalara bölündü, dizinlendi ve yenilendi. Dördünde de sessiz kalan bir varsayım vardı: sorgu, kullanıcının yazdığı biçimiyle dizine gider.
Abone “hangi dilim” yazar, dağarcıkta “kademe esigi” geçer. Boşluğu kapatmanın bir yolu, sorguyu dizine göndermeden önce bir modele verip belge diline çevirtmektir; bedeli sorgu başına bir çağrıdır. Dönüştürme tek adımlıdır; sonucu görüp yeniden sorgulamak M28/K05’in konusudur.
- EH41. Kod bir benzeticidir; gerçek bir gömme ya da model uç noktası çağrılmaz. Dağarcık, kavramlar, sorgular ve kullanıcı yazımları kurgudur, tohum 20260218.
- EH42. Hedef iki parçalıdır. Sorgunun hedefi hem bir kavram hem bir kayıt türüdür; parça ancak ikisini birden taşıyorsa ilgilidir. Anma@k ilk k içinde ilgili parça bulunan sorgu payı, kesinlik@k ilk k’nın ilgili olan payıdır.
- EH43. Hat,
gommeler/06’da ölçülen karma aramayı kullanır: açı benzerliğinin yanına belirteç örtüşmesi eklenir. Yordamı tekrarlanmaz, ağırlık sabittir. Bu dersin tabanı dönüştürmesiz erişimdir; erişimsiz çağrının tabanıerisim-hatti/01’de kuruldu. - EH44. Üretim benzeticisi bağlamdaki parçalardan birini seçer ve kodunu alıntılar; parçanın
yeri ağırlığı değiştirir. O ağırlık
erisim-hatti/07’nin konusudur, burada sabittir. - EH45. Aynı kırk sorgunun iki yazımı ölçülür: kısa yazım abonenin yazdığı kısaltılmış biçim, uzun yazım aynı sorunun bağlam cümleleriyle uzatılmışı. Hedef ikisinde de aynıdır.
- EH46. Dönüştürme hız sınırına takılırsa hat ham sorguya döner; başarısız çağrının belirteci yine sayılır.
Hat ve Hedef
Hat parça düzeyinde çalışır. Aşağıdaki blok dağarcığı, gömme benzeticisini, karma getirmeyi ve üretim benzeticisini kurar; sonra sorgu dizinin tanıdığı biçimde yazıldığında hattın nerede durduğunu basar: dönüştürmenin ulaşabileceği üst sınır.
# BENZETICI -- KURGUDUR. Gercek bir gomme ya da model uc noktasi cagrilmaz; dagarcik, # kavramlar ve sorgular kurgudur, tohum 20260218. import math TOHUM, M32 = 20260218, 0xFFFFFFFF BOYUT = 32 def uretec(t): x = ((t ^ (t >> 16)) * 2246822507) & M32 x = ((x ^ (x >> 13)) * 3266489909) & M32 s = [(x ^ (x >> 16)) & M32] def sonraki(): s[0] = (s[0] * 1664525 + 1013904223) & M32 return s[0] / 4294967296 return sonraki def ayrik(u, w): t = 0.0 for i, x in enumerate(w): t += x if u < t: return i return len(w) - 1 def belirtecle(m): b = [] for s in m.lower().replace(",", " , ").split(): while len(s) > 5: b.append(s[:5]) s = s[5:] b.append(s) return b # ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"] KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"} KAVRAM = { # kavram: (sinif, belge yuzeyi, sorgu yuzeyi) "basamak": ("tarife", "kademe esigi", "hangi dilimdeyim"), "birim": ("tarife", "birim ucret", "metrekup fiyati"), "abonetip": ("tarife", "abone tipi", "mesken mi isyeri mi"), "gecis": ("tarife", "tarife gecisi", "plan degistirme"), "arizakod": ("ariza", "ariza kodu", "hata numarasi"), "sizinti": ("ariza", "hat sizintisi", "su kacagi"), "basinc": ("ariza", "basinc dususu", "zayif akis"), "ekip": ("ariza", "saha ekibi", "gorevli ne zaman gelir"), "endeks": ("sayac", "endeks degeri", "sayac ustundeki rakam"), "okuma": ("sayac", "okuma yordami", "nasil kaydediliyor"), "degisim": ("sayac", "sayac degisimi", "cihaz yenileme"), "dogrula": ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"), "planli": ("kesinti", "planli kesinti", "onceden duyurulan durma"), "duyuru": ("kesinti", "duyuru kanali", "nereden ogrenirim"), "sure": ("kesinti", "kesinti suresi", "ne kadar surer"), "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"), "periyot": ("bakim", "periyodik bakim", "duzenli kontrol"), "vana": ("bakim", "vana kontrolu", "musluk kapatma duzeni"), "filtre": ("bakim", "filtre degisimi", "temizleme parcasi"), "kalib": ("bakim", "kalibrasyon kaydi", "olcum ayari"), } ANAHTAR = list(KAVRAM) ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"] # ---- KURGU dagarcik BELGE = [] for i in range(200): r = uretec(TOHUM + 7919 * i) s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])] kav = [k for k in ANAHTAR if KAVRAM[k][0] == s] ana = kav[int(r() * len(kav))] n = 2 + int(r() * 4) par, kavlar = [], [ana] for _ in range(n): y = kav[int(r() * len(kav))] kavlar.append(y) o = ORTAK[int(r() * len(ORTAK))] par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir") BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar, "baslik": f"{KAVRAM[ana][1]} yordami", "par": par}) def metin(d): return d["baslik"] + " " + " ".join(d["par"]) # ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor def _kavramla(m, alan=True): v = [0.0] * len(ANAHTAR) dm = " " + m.lower() + " " for i, k in enumerate(ANAHTAR): bel, sor = KAVRAM[k][1], KAVRAM[k][2] if bel in dm: v[i] += 1.0 if sor in dm: v[i] += 1.0 if alan else 0.0 # alan disi gomme sorgu dilini tanimaz if not alan: for o in ORTAK: if " " + o + " " in dm: for i in range(len(ANAHTAR)): v[i] += 0.05 return v IZDUS = [] for i in range(len(ANAHTAR)): r = uretec(TOHUM ^ (i + 1) * 2654435761) IZDUS.append([r() * 2 - 1 for _ in range(64)]) def gom(m, boyut=BOYUT, alan=True): k = _kavramla(m, alan) v = [0.0] * boyut for i, a in enumerate(k): if a: for j in range(boyut): v[j] += a * IZDUS[i][j % 64] n = sum(x * x for x in v) ** 0.5 return [x / n for x in v] if n else v def aci(a, b): return sum(x * y for x, y in zip(a, b)) # ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri SORGU = [] for i in range(40): r = uretec(TOHUM + 104729 * i) d = BELGE[int(r() * len(BELGE))] SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}", "sinif": d["sinif"], "kavram": d["ana"]}) # ---- hat: parcalar, karma getirme, hedef tanimi ve uretim PARCA = [{"kod": d["kod"], "ana": d["ana"], "metin": p} for d in BELGE for p in d["par"]] for p in PARCA: p["vek"], p["bel"] = gom(p["metin"]), set(belirtecle(p["metin"])) for s in SORGU: s["kayit"] = s["metin"].split()[-1] def getir(q, k=5, w=0.5): qv, qb = gom(q), set(belirtecle(q)) s = sorted(((aci(qv, p["vek"]) + w * len(qb & p["bel"]) / len(qb | p["bel"]), i) for i, p in enumerate(PARCA)), key=lambda t: (-t[0], t[1])) return [PARCA[i] for _, i in s[:k]] def ilgili(s, p): return KAVRAM[s["kavram"]][1] in p["metin"] and s["kayit"] in p["bel"] def izno(m): h = 2166136261 for c in m: h = ((h ^ ord(c)) * 16777619) & M32 return h PENCERE = 240 SAYAC = [0] YON_Y = "Asagidaki parcalara bakarak yanitla ve kullandigin parcanin kodunu yaz . " def yanitla(sorgu, parcalar, tohum=TOHUM, sicaklik=0.12): """KURGU uretim: baglamdan bir parca secilir, parcanin YERI agirligi degistirir.""" SAYAC[0] += 1 istem = YON_Y + " ".join(f"[{p['kod']}] {p['metin']} ." for p in parcalar) + " Soru: " + sorgu bel = belirtecle(istem) if len(bel) > PENCERE: return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "parca": None} r, qb, n = uretec(tohum ^ izno(istem)), set(belirtecle(sorgu)), len(parcalar) p = [(1.0 if i == 0 else 0.8 if i == n - 1 else 0.45) * (0.3 + len(qb & x["bel"]) / len(qb)) for i, x in enumerate(parcalar)] w = [math.exp(a / sicaklik) for a in p] se = parcalar[ayrik(r(), [a / sum(w) for a in w])] return {"durum": "tamam", "giris": len(bel), "parca": se, "cikis": len(belirtecle(f"{se['kod']} : {se['metin']}"))} a = u = 0 for s in SORGU: g = getir(s["metin"], 5) a += any(ilgili(s, p) for p in g) u += ilgili(s, yanitla(s["metin"], g)["parca"]) print("dagarcik %d belge %d parca ; ortalama parca %.1f belirtec ; ornek sorgu %r" % (len(BELGE), len(PARCA), sum(len(p["bel"]) for p in PARCA) / len(PARCA), SORGU[0]["metin"])) print("hedef parca kumesi ortalama %.1f parca" % (sum(len([p for p in PARCA if ilgili(s, p)]) for s in SORGU) / 40)) print("dizin dilinde yazilmis sorgu k=5 anma %.4f uretim %.4f" % (a / 40, u / 40))
dagarcik 200 belge 693 parca ; ortalama parca 15.3 belirtec ; ornek sorgu 'nasil kaydediliyor form' hedef parca kumesi ortalama 8.9 parca dizin dilinde yazilmis sorgu k=5 anma 0.8000 uretim 0.7000
Hedef kümesi ortalama 8,9 parçadır, altı yüz doksan üçün yüzde biraz üstü. Sorgu dizin dilinde yazıldığında ilk beş parça bu kümeden birini 0,8000 payla getiriyor, üretim bunun 0,7000’ini yanıta çeviriyor.
İki Yazım ve Dönüştürücü
Abone bu cümleleri yazmaz. “nasil kaydediliyor form” bir dizin sorgusudur; abone “kaydediliyor mu form” yazar ya da derdini uzun uzun anlatır. Aşağıdaki blok aynı kırk hedefin iki yazımını kurar ve üç kurulumu ikisinde de koşturur: taban (ham sorgu), genişletme (üzerine belge dilindeki terim eklenir) ve yeniden yazma (ham sorgu atılır, yerine belge dilinde bir cümle konur).
# KURGU: kullanicinin yazdigi kisa bicim -- dizinin tanidigi yuzeyi tasimaz KISA = {"basamak": "hangi dilim", "birim": "metrekup ucreti", "abonetip": "mesken mi isyeri", "gecis": "plan degisimi", "arizakod": "hata kodu", "sizinti": "kacagi olabilir", "basinc": "akis zayif", "ekip": "gorevli gelmedi", "endeks": "sayac rakami", "okuma": "kaydediliyor mu", "degisim": "cihaz yenilendi", "dogrula": "yanlis girilmis", "planli": "onceden duyurulan", "duyuru": "nereden bakarim", "sure": "kac saat surer", "geridonus": "tekrar gelir mi", "periyot": "duzenli bakim", "vana": "musluk kapatma", "filtre": "temizleme filtresi", "kalib": "olcum kalibrasyonu"} ONEK = ["gecen hafta", "birkac gundur", "sabahtan beri", "dun aksam"] BAG = ["bir de sunu soracaktim", "ayrica ilgili birime yazdim", "bu arada merak ettim", "daha once de aramistim"] KISASORGU, UZUNSORGU = [], [] for i, s in enumerate(SORGU): r = uretec(TOHUM + 31337 * i) y, o2 = ANAHTAR[int(r() * 20)], ORTAK[int(r() * 7)] z = ANAHTAR[int(r() * 20)] KISASORGU.append(dict(s, metin=f"{KISA[s['kavram']]} {s['kayit']}")) UZUNSORGU.append(dict(s, metin=f"{ONEK[int(r() * 4)]} {KAVRAM[y][2]} {o2} " f"{BAG[int(r() * 4)]} {s['metin']} {KAVRAM[z][2]}")) SORGU_IZ = {} # sorgu dili -> kavram for k in ANAHTAR: for t in belirtecle(KAVRAM[k][2]): if len(t) > 3: SORGU_IZ.setdefault(t, k) YON_D = "Sorguyu belge diline cevir . Sorgu: " def donustur(q, kip, tohum=TOHUM, sicaklik=0.5): """KURGU donusturucu: tek adimli bir model cagrisi, dongu ve planlama yok.""" SAYAC[0] += 1 bel = belirtecle(YON_D + q) if SAYAC[0] % 37 == 0: # hiz siniri: ham sorgu return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "metin": q, "kavram": None} r, p = uretec(tohum ^ izno(q)), {} for t in bel: if t in SORGU_IZ: p[SORGU_IZ[t]] = p.get(SORGU_IZ[t], 0.0) + 1.0 if not p: return {"durum": "bos", "giris": len(bel), "cikis": 0, "metin": q, "kavram": None} a = sorted(p) w = [math.exp(p[x] / sicaklik) for x in a] k = a[ayrik(r(), [x / sum(w) for x in w])] o = next((t for t in bel if t in ORTAK), "") y = f"{KAVRAM[k][1]} icin {o} tutulur" if kip == "yeniden yazma" else f"{q} {KAVRAM[k][1]}" return {"durum": "tamam", "giris": len(bel), "cikis": len(belirtecle(y)), "metin": y, "kavram": k} def olc(kume, kip, tohum=TOHUM, k=5): SAYAC[0] = 0 an = ur = ca = bt = ds = dk = 0 for s in kume: q = s["metin"] if kip != "taban": d = donustur(q, kip, tohum) q, ca, bt = d["metin"], ca + 1, bt + d["giris"] + d["cikis"] ds, dk = ds + (d["durum"] != "tamam"), dk + (d["kavram"] == s["kavram"]) g = getir(q, k) an += any(ilgili(s, p) for p in g) y = yanitla(s["metin"], g, tohum) ca, bt = ca + 1, bt + y["giris"] + y["cikis"] ur += y["parca"] is not None and ilgili(s, y["parca"]) return an / 40, ur / 40, ca, bt, ds, dk / 40 print("ortalama sorgu: kisa %.1f uzun %.1f belirtec" % (sum(len(belirtecle(s["metin"])) for s in KISASORGU) / 40, sum(len(belirtecle(s["metin"])) for s in UZUNSORGU) / 40)) print("sorgu kurulum anma@5 uretim cagri belirtec dogru kavram basarisiz") fark = [0.0, 0.0] for ad, kume in (("kisa ", KISASORGU), ("uzun ", UZUNSORGU)): for kip in ("taban", "genisletme", "yeniden yazma"): a, u, c, b, ds, dk = olc(kume, kip) a2, u2 = olc(kume, kip, TOHUM + 1)[:2] fark = [max(fark[0], abs(a - a2)), max(fark[1], abs(u - u2))] print("%s %-14s %.4f %.4f %5d %8d %12s %9d" % (ad, kip, a, u, c, b, "-" if kip == "taban" else "%.4f" % dk, ds)) print("iki kosum farki (tohum 20260219): anma en cok %.4f uretim en cok %.4f" % (fark[0], fark[1]))
ortalama sorgu: kisa 4.5 uzun 21.7 belirtec sorgu kurulum anma@5 uretim cagri belirtec dogru kavram basarisiz kisa taban 0.3750 0.2000 40 5366 - 0 kisa genisletme 0.7500 0.7000 80 6356 0.9500 1 kisa yeniden yazma 0.7500 0.7000 80 6335 0.9500 1 uzun taban 0.5500 0.3250 40 6166 - 0 uzun genisletme 0.3500 0.2000 80 8526 0.3500 1 uzun yeniden yazma 0.2500 0.0500 80 7842 0.3500 1 iki kosum farki (tohum 20260219): anma en cok 0.0500 uretim en cok 0.1000
Kısa Yazımda Kazanç
Kısa yazımın tabanı 0,3750 anma ve 0,2000 üretimdir. Üst sınırla arasındaki fark hattın kusuru değil, sorgunun dizine değmemesidir: “hangi dilim” hiçbir parçada geçmez, geriye kayıt türünün örtüşmesi kalır.
Dönüştürme boşluğu kapatıyor. Genişletme anmayı 0,7500’e, üretimi 0,7000’e çıkarıyor; ikisi de iki koşum farkının (0,0500 ve 0,1000) üstünde ve üretim üst sınıra birebir yetişiyor. Sebep tabloda yazılı: dönüştürücü doğru kavramı 0,9500 payla buluyor.
Genişletme ile yeniden yazmanın burada aynı sonucu vermesi rastlantı değildir: ham sorguyu tutmanın bedeli de kazancı da yoktur, çünkü atılacak bir sinyal yoktur.
Uzun Yazımda Kayıp
Uzun yazımın tabanı 0,5500’dür, kısa yazımınkinden yüksektir: abone derdini uzatırken dizinin tanıdığı ifadeyi de yazıyor. Dönüştürme tabanı düşürüyor — genişletmeyle 0,3500, yeniden yazmayla 0,2500 — ve ikisi de iki koşum farkının üstünde, ölçülmüş bir kayıptır.
Nedeni yine doğru kavram sütunundadır: isabet 0,3500’e iniyor. Uzun sorguda üç kavram yüzeyi ve iki kayıt türü var; tek adımlı bir çağrı hangisinin asıl soru olduğunu seçmek zorunda ve çoğu kez yanılıyor. Yanıldığında genişletme yanlış bir terim ekler ama ham sorgu yerinde kalır; yeniden yazma doğru olan tek şeyi, abonenin yazdığı ifadeyi siler ve üretim 0,0500’e iniyor. Kursun ikinci iddiasının bu derse düşen örneği budur: eklenen düzenek işi kötüleştirdi.
Dönüştürmenin Faturası
Çağrı sorgu başına birden ikiye, kırktan seksene çıkıyor. Belirteç kısa yazımda 5366’dan 6356’ya, uzun yazımda 6166’dan 8526’ya gidiyor; uzun sorguyu bir de modele okutmak hattın en pahalı satırıdır ve kırk çağrının biri hız sınırına takılıyor. Gecikme sınıf olarak sayılır: hat tek çağrılık bir adımdan iki aşamalı bir zincire dönüşüyor. Sorgu başına yirmi beş ek belirteç anmayı 0,3750’den 0,7500’e çıkarırken, elli dokuz ek belirteç onu 0,5500’den 0,3500’e indiriyor.
Özet
- Sorgunun hedefi hem kavram hem kayıt türüdür; ilk beşte ikisini taşıyan parça bulunma payı erişim, o parçanın yanıta dönme payı üretim ölçüsüdür.
- Kullanıcının yazdığı kısa biçim dizine değmediği için taban 0,3750 / 0,2000’dir; dizin dilindeki aynı sorgu 0,8000 / 0,7000 veriyor.
- Genişletme kısa yazımda anmayı 0,7500’e, üretimi 0,7000’e çıkarıyor; doğru kavramı bulma payı 0,9500’dür.
- Uzun yazımda aynı düzenek tabanı 0,5500’den 0,3500’e, yeniden yazma 0,2500’e düşürüyor; doğru kavram payı 0,3500’e iner ve yeniden yazma abonenin yazdığı ifadeyi de siler.
- Bedel sorgu başına bir çağrı ve 990 ile 2360 arası ek belirteçtir; hat zincire dönüşür.
Sonraki Adım
Bu dersin ölçümleri ilk beş parçayı birlikte sayıyor: içinde ilgili bir parça varsa anma yazılıyor, sıra sorulmuyor. Oysa kesinlik@5 ilk beşin çoğunun ilgisiz olduğunu söylüyor. Sonraki ders getirmeyi ikiye ayırır: geniş bir aday kümesi toplayan ucuz bir aşama ve her adayı sorguyla birlikte okuyan pahalı bir aşama.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.