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