Ders 04 / 14
Dizi Etiketleme
Etiketin belgeden alınıp her belirtece ayrı ayrı verilmesi ve doğruluğun neyi saydığının ölçülmesi: alanın tabanı olan en sık etiketi her belirtece yazmak 0,5061 belirteç doğruluğu veriyor ama varlık düzeyinde F1 0,0000 — hiçbir varlık bulunmuyor. Son üç karaktere bakan yordam iki etiketleme düzeninde de aynı 0,9824 belirteç doğruluğunu verirken varlık düzeyinde 0,9267 ve 0,9600 veriyor; belirteci ezberleyen yordam 1,0000 belirteç doğruluğuyla tür düzeninde 0,9665'te kalıyor. Sözcük türünde aynı biçimdeki taban 0,5473 verir ve orada yanıltmaz.
İçindekiler
Üç derste bir not tek bir satıra indirgendi ve verilen karar her seferinde belgenin bütününe
aitti. Notun içinde hangi belirtecin neyi adlandırdığı hiç sorulmadı. sayacin kapagi kirik
notunda ilk iki belirteç bir donanımı adlandırır ve üçüncüsü onun durumunu bildirir; oysa
boruda kelepce eksik notunda ilk iki belirteç iki ayrı donanımdır. Bu ders etiketi
belirteçlere dağıtır.
Etiket yer değiştirince ölçüt de değişir: belirteç düzeyinde doğruluk her belirteci ayrı sayar, varlık düzeyinde bir varlık ancak başlangıcı, bitişi ve türü birlikte tuttuğunda sayılır. Alanın tabanı burada en sık etiketi her belirtece yazmaktır ve belirteç düzeyinde şaşırtıcı biçimde yüksek çıkar.
- NL25. Belirteçleme
nlp/03’ün kararıdır: noktalama atma, küçük harfe inme, sayı katlama. Gövdeleme uygulanmaz, çünkü sınır kararının bir kısmı ekten okunur. - NL26. Varlık türleri kurgudur ve kurgunun kendi sözlüğünden türetilir: donanım yedi kök, konum dokuz kök, ölçüm iki kök ile sayı belirteci. Öteki belirteçler varlık dışıdır.
- NL27. Sınır kuralı: yalın ya da ilgi durumundaki bir adın ardından iyelik durumunda bir ad gelirse ikisi tek varlıktır; sayı belirteci önceki ölçüm belirtecine bağlanır. Öbür durumlarda her belirteç kendi varlığıdır.
- NL28. Sözcük türü etiketi de sözlükten okunur: ad, nitelik, eylem, taşıyıcı, sayı.
- NL29. Alanın tabanı en sık etiketi her belirtece yazmaktır, iki görevde de.
- NL30. Model ezber çizelgesidir: eğitim payında her anahtar için en sık etiket. İki anahtar denenir — belirtecin kendisi ve son üç karakteri.
- NL31. İki etiketleme düzeni vardır: yalnız tür, ve başlangıç ile iç ayrımı. Belirteç düzeyi doğruluk ikisinde de tür üzerinden sayılır, böylece iki düzen aynı ölçütle karşılaştırılır.
- NL32. Varlık düzeyi ölçüt tam eşleşmedir. Kesinlik, duyarlılık ve F1 tanımları M27/K03’te kuruldu ve tekrarlanmaz; buraya eklenen tek şey neyin sayıldığıdır.
Varlıklar ve İki Etiketleme Düzeni
Notlar nlp/01’in kurgusuyla aynı tohumdan ü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.
Varlıklar ve belirteç etiketleri kurgu sözlüğünden türetilir, iki düzende de aynı sınır kuralıyla. Kestirim yordamı ikisinde de aynıdır: anahtar başına en sık etiket.
from collections import Counter TIP = {"donanim": "sayac kapak muhur vana kelepce boru pano", "konum": "kapi zil bahce apartman bodrum giris adres ev sokak", "olcum": "okuma olcum"} KOK_TIP = {k: t for t, v in TIP.items() for k in v.split()} DURUM = {f: i for v in AD.values() for i, f in enumerate(v.split())} STUR = {f: "ad" for v in list(AD.values()) + [" ".join(s) for s in SEYREK] for f in v.split()} STUR.update({f: "nitelik" for f in NITELIK}) STUR.update({f: "eylem" for v in EYLEM.values() for f in v.split()}) STUR.update({f: "tasiyici" for f in TASIYICI}, **{"<sayi>": "sayi"}) for x in VERI: x["bel"] = [("<sayi>" if b.isdigit() else b) for b in (s.strip(",.").lower() for s in x["not"].split()) if b] def tipi(b): return "olcum" if b == "<sayi>" else KOK_TIP.get(KOKU.get(b)) def baglanir(a, b): # ilgi ya da yalin + iyelik tek varliktir; sayi okumaya baglanir return b == "<sayi>" or (DURUM.get(a) in (0, 1) and DURUM.get(b) == 3) def varliklar(bel): v, i = [], 0 while i < len(bel): if tipi(bel[i]) is None: i += 1 continue j = i + 1 while j < len(bel) and tipi(bel[j]) and baglanir(bel[j - 1], bel[j]): j += 1 v.append((i, j, tipi(bel[j - 1]))) i = j return v def etiketle(bel, ayrim): e = ["dis"] * len(bel) for i, j, t in varliklar(bel): for k in range(i, j): e[k] = (("B-" if k == i else "I-") + t) if ayrim else t return e def coz(bel, tah, ayrim): v, i = [], 0 while i < len(bel): t = tah[i] if t == "dis": i += 1 continue tip = t[2:] if ayrim else t j = i + 1 while j < len(bel) and tah[j] == ("I-" + tip if ayrim else tip): j += 1 v.append((i, j, tip)) i = j return v def cizelge(ayrim, anahtar): s = {} for x in EGT: for b, e in zip(x["bel"], etiketle(x["bel"], ayrim)): s.setdefault(anahtar(b), Counter())[e] += 1 g = Counter(e for x in EGT for e in etiketle(x["bel"], ayrim)).most_common(1)[0][0] return {b: c.most_common(1)[0][0] for b, c in s.items()}, g def degerlendir(ad, ayrim, anahtar=lambda b: b, sabit=None): c, g = cizelge(ayrim, anahtar) d = t = dv = tv = gv = 0 for x in AYR: bel = x["bel"] tah = [sabit] * len(bel) if sabit else [c.get(anahtar(b), g) for b in bel] tur = [e[2:] if ayrim and e != "dis" else e for e in tah] d += sum(a == b for a, b in zip(etiketle(bel, False), tur)) t += len(bel) p, y = coz(bel, tah, ayrim), varliklar(bel) dv += sum(v in y for v in p) tv += len(p) gv += len(y) k, u = dv / tv if tv else 0.0, dv / gv f = 2 * k * u / (k + u) if k + u else 0.0 print(f"{ad:<28} {d / t:>9.4f} {k:>9.4f} {u:>11.4f} {f:>7.4f}") ES = Counter(e for x in EGT for e in etiketle(x["bel"], False)).most_common(1)[0][0] print(f"{len(VERI)} notta {sum(len(varliklar(x['bel'])) for x in VERI)} varlik, " f"{sum(j - i > 1 for x in VERI for i, j, _ in varliklar(x['bel']))} tanesi cok belirtecli; " f"en sik belirtec etiketi '{ES}'") print(f"\n{'adlandirilmis varlik':<28} {'belirtec':>9} {'kesinlik':>9} {'duyarlilik':>11}" f" {'F1':>7}") EK = (lambda b: b[-3:]) degerlendir("en sik etiket", False, sabit=ES) degerlendir("son uc karakter, tur", False, EK) degerlendir("son uc karakter, ayrimli", True, EK) degerlendir("belirtec kimligi, tur", False) degerlendir("belirtec kimligi, ayrimli", True)
1800 notta 4378 varlik, 1583 tanesi cok belirtecli; en sik belirtec etiketi 'dis' adlandirilmis varlik belirtec kesinlik duyarlilik F1 en sik etiket 0.5061 0.0000 0.0000 0.0000 son uc karakter, tur 0.9824 0.9191 0.9343 0.9267 son uc karakter, ayrimli 0.9824 0.9421 0.9786 0.9600 belirtec kimligi, tur 1.0000 0.9774 0.9558 0.9665 belirtec kimligi, ayrimli 1.0000 1.0000 1.0000 1.0000
Kümede 4.378 varlık var ve 1.583’ü birden çok belirteç kaplıyor. En sık belirteç etiketi varlık dışıdır ve her belirtece onu yazmak ayrılmış payda 0,5061 doğruluk veriyor: belirteçlerin yarıdan fazlası doğru etiketleniyor. Aynı çıktının varlık düzeyi sayısı 0,0000’dır, çünkü tek bir varlık bile bulunmuyor. Kursun kuralı bundan daha keskin bir örnek vermez — 0,5061 tek başına okunursa yordamın yolun yarısını gittiği sanılır, oysa hiçbir şey bulmamıştır.
Ortadaki iki satır asıl ayrışmayı gösteriyor. Son üç karaktere bakan yordam iki düzende de aynı belirteç doğruluğunu veriyor: 0,9824. Varlık düzeyinde ise 0,9267 ve 0,9600 veriyor. İki düzen aynı belirteç kararlarını verir; ayrıldıkları tek yer sınırı nasıl okuduklarıdır ve belirteç düzeyi ölçüt bu farkı göremez. Aynı çıktının iki sayısı vardır ve hangisinin yazılacağı ölçütün tanımına bağlıdır.
Belirteç hatasının varlık hatasına dönüşme oranı da tabloda okunuyor: belirteç düzeyinde 0,0176
hata, tür düzeninde 0,0733 F1 kaybı veriyor. Bir varlık ancak bütün belirteçleri doğruysa sayılır,
yani hata varlık boyunca çarpılır. Son satır çifti bunu uçtan gösteriyor: ezber 1,0000 belirteç
doğruluğu verirken tür düzeninde 0,9665’te kalıyor. Kusursuz belirteç kararıyla bile kayıp vardır,
çünkü tür düzeni bitişik iki aynı türlü varlığı tek varlık sayar — boruda kelepce eksik notunda
iki ayrı donanım tek aralığa iniyor. Başlangıç ile iç ayrımı bunu etikete taşır ve 1,0000 verir.
Aynı Taban, Başka Bir Görev
İkinci görev sözcük türüdür ve varlık düzeyi yoktur: etiket belirteçle birebirdir.
SAY_TUR = Counter(STUR[b] for x in AYR for b in x["bel"]) EST = Counter(STUR[b] for x in EGT for b in x["bel"]).most_common(1)[0][0] def tur_olc(ad, anahtar=None): c = {} if anahtar: s = {} for x in EGT: for b in x["bel"]: s.setdefault(anahtar(b), Counter())[STUR[b]] += 1 c = {k: v.most_common(1)[0][0] for k, v in s.items()} d = t = 0 for x in AYR: for b in x["bel"]: d += (c.get(anahtar(b), EST) if anahtar else EST) == STUR[b] t += 1 print(f"{ad:<28} {d / t:>9.4f}") print("ayrilmis payda belirtec turu: " + ", ".join(f"{k} {v}" for k, v in SAY_TUR.most_common())) print(f"\n{'sozcuk turu':<28} {'belirtec':>9}") tur_olc(f"en sik etiket ({EST})") tur_olc("son uc karakter", EK) tur_olc("belirtec kimligi", lambda b: b)
ayrilmis payda belirtec turu: ad 2181, nitelik 622, eylem 603, sayi 312, tasiyici 267 sozcuk turu belirtec en sik etiket (ad) 0.5473 son uc karakter 0.9905 belirtec kimligi 1.0000
En sık etiketi her belirtece yazmak burada 0,5473 veriyor, yani adlandırılmış varlıktakinden de yüksek. Ayrılmış payın 3.985 belirtecinin 2.181’i addır ve tek başına bu oran tabanı belirliyor. Son üç karakter 0,9905, belirteç kimliği 1,0000 veriyor. Sayılar yüksektir çünkü görev bu kurguda kolaydır: bir yüzey biçiminin türü değişmez.
Asıl okuma iki görevin karşılaştırılmasındadır. Aynı biçimdeki taban iki görevde iki ayrı anlam taşıyor: sözcük türünde 0,5473 görevin zorluğunu dürüstçe bildiriyor, adlandırılmış varlıkta 0,5061 hiçbir şey bulmayan bir yordamı yarı yolda gösteriyor. Fark yordamda değil ölçüttedir — birinde etiketlenen birim ile sayılan birim aynı, ötekinde değil.
Özet
- Etiket belgeden alınıp belirteçlere dağıtıldı; 1.800 notta 4.378 varlık var ve 1.583’ü birden çok belirteç kaplıyor.
- Alanın tabanı en sık etiketi her belirtece yazmaktır: belirteç düzeyinde 0,5061, varlık düzeyinde F1 0,0000. Belirteç düzeyi sayı tek başına okunursa yordamın yarı yolu gittiği sanılır.
- Son üç karaktere bakan yordam iki etiketleme düzeninde de aynı belirteç doğruluğunu (0,9824) verirken varlık düzeyinde 0,9267 ve 0,9600 veriyor; fark yalnız sınırın okunmasındadır ve belirteç düzeyi ölçüt onu göremez.
- Belirteç düzeyinde 0,0176 hata tür düzeninde 0,0733 F1 kaybı verir; ezber 1,0000 belirteç doğruluğuyla tür düzeninde 0,9665’te kalır, çünkü bitişik iki aynı türlü varlık tek aralığa iner.
- Sözcük türünde aynı biçimdeki taban 0,5473 verir ve yanıltmaz: orada etiketlenen birim ile sayılan birim aynıdır.
Sonraki Adım
Dört derste metin sayıya çevrildi: belirteçlere bölündü, sütunlara açıldı, vektörlere gömüldü ve son derste etiket belirteçlere dağıtıldı. Belgenin bütününe verilen karar bu dizide yalnız bir kez, tek bir ikili soruyla soruldu ve orada ölçülen şey kararın kendisi değil temsildi: hangi temsilin ne kattığı. Notun bildirdiği olay türü ise dört sınıflıdır ve o karar hiç verilmedi. Boru hattının kendisi de hiç sökülmedi — belirteçleme, ağırlıklandırma ve sınıflandırıcı bir arada ölçüldü, her adımın kaç puan kattığı ayrı ayrı sorulmadı. Sonraki ders belgeyi bir bütün olarak sınıflandırır ve boru hattının her adımının payını tek tek sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.