Ders 02 / 14
Sayısal 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.
İçindekiler
Ö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.
# 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.
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,0366 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.
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.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.