Ders 14 / 15
Model Belgeleme
Modeli devralan kişinin sorularından kaçının yazılı beyanla kapandığının sayılması: aynı model sınama kümesinde bütünde 0,7778 doğruluk ve taban çizgisinin 0,0198 üstünü verirken, dört eksende kurulan 14 alt grubun ölçülebilen 12'sinde en iyi 0,9688 ve en kötü 0,6111 okunuyor, alt grup açıklığı 0,3576 ve üç alt grup kendi tabanının altında kalıyor. Yirmi iki soruluk devir soru kümesinden yalnız bütünde ölçülen sayıyı taşıyan beyan 5'ini, alt grup tablosunu ekleyen beyan 12'sini, kullanım sınırını da yazan beyan 18'ini kapatıyor; kalan 4 soru hiçbir sürümde kapanmıyor çünkü hiçbiri bir ölçüm sorusu değil. Beş kullanım kararında ilk sürüm 4, ikincisi 1 yanlış karar ürettiriyor, üçüncüsü ölçülmeyen alt grup için bilinmiyor diyebildiği için hiç yanlış karar ürettirmiyor.
İçindekiler
Üç ders zararı ölçtü ve azaltmayı denedi: yanlılığın üç kaynağı ayrı ayrı sayıldı, üç adalet ölçütünün aynı anda sağlanamadığı gösterildi, tek bir kaydın çıktıyı ne kadar oynattığı ve gürültünün doğruluktan ne götürdüğü yan yana basıldı. Bu ölçülerin hiçbiri modeli kullanacak kişiye ulaşmıyor. Ölçüm defterde kalıyor; karar başka bir masada veriliyor.
Bu ders o masaya ulaşan şeyi ölçer. Ulaşan şey model belgesidir: modelin ne ölçüldüğünü, kimin için ölçüldüğünü ve nerede kullanılmayacağını söyleyen yazılı beyan. Belgenin iyiliği niteliğiyle değil, kaç soruyu kapattığıyla sayılır. M26/K06 raporun okuyucuya ne geri okuttuğunu ölçmüştü; buradaki okuyucu bir rapor okuru değil, modeli devralan kişidir.
- ME31. Küme, etiket ve model M27/K01–K07’den devralınır ve kurgudur: 1.260 abone, 756/252/252 bölme, sınama kümesinde taban çizgisi 0,7579.
- ME32. Ölçü doğruluktur ve taban çizgisi eğitim kümesinin en sık sınıfıdır. İkisi de her alt grupta yeniden hesaplanır.
- ME33. Alt gruplar dört eksende tanımlıdır: bölge, tarife basamağı, hane büyüklüğü, okuma sayısı. Tanım bir karardır ve kaç alt gruba bakıldığı yazılır.
- ME34. Yirmi aboneden küçük alt grup ölçülmez; eşik bir karardır.
- ME35. Devralan kişinin soru kümesi kurgudur: yirmi iki soru. Her soru tek bir beyan kalemine bağlıdır ve o kalem beyanda varsa kapanmış sayılır.
- ME36. Üç beyan sürümü iç içedir: A yalnız bütünde ölçülen sayıyı, B alt grup tablosunu da, C kullanım sınırını da taşır. Hiçbiri bir şablon değildir; kalem listesidir.
- ME37. Kullanım kararı yordamı yalnız beyanı okur: alt grup satırı varsa onu, yoksa bütünde ölçülen sayıyı kullanır. Ölçülmemiş bir alt grup için doğru yanıt “bilinmiyor”dur.
Aynı Sayı, On İki Alt Grup
# belge.py — MODELDIR. M27/K01-K07'nin kurgu abone tablosu ayni tohumla (20260218) # uretilir, uzerine KURGU kacak/ariza suphesi etiketi eklenir ve ayni sayi once # butunde, sonra dort eksende tanimli alt gruplarda olculur. import math TOHUM, HAM, M32, ENAZ = 20260218, 1400, 0xFFFFFFFF, 20 BOLGE = [("kuzey", 0.28, 21, 0.00), ("guney", 0.22, 17, -0.10), ("dogu", 0.18, 26, 0.30), ("bati", 0.14, 14, -0.05), ("merkez", 0.18, 23, 0.05)] ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"] 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 VERI = [] for i in range(HAM): r = uretec(TOHUM + i) b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])] hane = 1 + ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05]) memnun = 1 + ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17]) if r() < 0.046: continue no = 10001 + i r, v = uretec(TOHUM + 7000 + no), [] for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])): v.append(0.0 if r() < 0.038 else math.floor( b[2] * math.exp((r() + r() + r() - 1.5) * 0.62) * (1 - d * 0.05) * 100 + 0.5) / 100) r() if not v: continue ort, oyn, r = sum(v) / len(v), max(v) - min(v), uretec(TOHUM + 51000 + no) z = (0.052 * (ort - 20) + 0.85 * (min(v) == 0.0) + 0.026 * oyn + 0.24 * (hane >= 5) - 0.20 * (memnun >= 4) + b[3] + 0.9 * (no - 10001) / 1399 + (r() + r() + r() - 1.5) * 1.30) x = {"hane": hane, "memnuniyet": memnun, "donem": len(v), "bolge": b[0], "ort_tuketim": round(ort, 2), "oynaklik": round(oyn, 2), "sifir_okuma": int(min(v) == 0.0), "supheli": int(z > 1.35)} for q in BOLGE: x["b_" + q[0]] = int(b[0] == q[0]) VERI.append(x) def karistir(dizi, tohum): r, s = uretec(tohum), list(dizi) for i in range(len(s) - 1, 0, -1): j = int(r() * (i + 1)) s[i], s[j] = s[j], s[i] return s K = karistir(VERI, TOHUM + 90000) EGT, SIN = K[:756], K[1008:] def agac(s, derinlik, enaz=2): def safsizlik(u): p = sum(x["supheli"] for x in u) / len(u) if u else 0.0 return 2 * p * (1 - p) p, en = sum(x["supheli"] for x in s) / len(s), None if derinlik and len(s) >= 2 * enaz and 0.0 < p < 1.0: for a in ALAN: d = sorted({x[a] for x in s}) for v in (d[1:] if len(d) < 10 else [d[int(i * len(d) / 10)] for i in range(1, 10)]): sol = [x for x in s if x[a] < v] sag = [x for x in s if x[a] >= v] if min(len(sol), len(sag)) < enaz: continue k = safsizlik(s) - (len(sol) * safsizlik(sol) + len(sag) * safsizlik(sag)) / len(s) if en is None or k > en[0]: en = (k, a, v, sol, sag) if en is None or en[0] <= 1e-9: return {"tahmin": int(p > 0.5)} return {"alan": en[1], "esik": en[2], "sol": agac(en[3], derinlik - 1, enaz), "sag": agac(en[4], derinlik - 1, enaz)} M = agac(EGT, 6) EN_SIK = int(sum(x["supheli"] for x in EGT) * 2 > len(EGT)) def olc(s): """Ayni kumede taban cizgisi (en sik sinif) ve modelin dogrulugu.""" d = 0 for x in s: u = M while "tahmin" not in u: u = u["sol"] if x[u["alan"]] < u["esik"] else u["sag"] d += u["tahmin"] == x["supheli"] return sum(x["supheli"] == EN_SIK for x in s) / len(s), d / len(s) EKSEN = [("bolge", lambda x: x["bolge"]), ("tarife basamagi", lambda x: "basamak %d" % ( 1 + (x["ort_tuketim"] >= 10) + (x["ort_tuketim"] >= 25) + (x["ort_tuketim"] >= 40))), ("hane buyuklugu", lambda x: "1-2 kisi" if x["hane"] <= 2 else ("3-4 kisi" if x["hane"] <= 4 else "5+ kisi")), ("okuma sayisi", lambda x: "az okuma" if x["donem"] <= 1 else "tam okuma")] t, m = olc(SIN) print(f"sinama kumesi {len(SIN)} abone; butunde taban {t:.4f}, model {m:.4f}, " f"fark {m - t:+.4f}") print(f"\n{'eksen':<16}{'alt grup':<12}{'abone':>6}{'taban':>8}{'model':>8}{'fark':>9}") ALTGRUP, OLCULMEYEN = [], [] for ad, f in EKSEN: for g in sorted({f(x) for x in SIN}): alt = [x for x in SIN if f(x) == g] if len(alt) < ENAZ: OLCULMEYEN.append((g, len(alt))) continue at, am = olc(alt) ALTGRUP.append((g, len(alt), at, am)) print(f"{ad:<16}{g:<12}{len(alt):>6}{at:>8.4f}{am:>8.4f}{am - at:>+9.4f}") iyi, kotu = max(ALTGRUP, key=lambda u: u[3]), min(ALTGRUP, key=lambda u: u[3]) print(f"\n{len(EKSEN)} eksende {len(ALTGRUP) + len(OLCULMEYEN)} alt grup kuruldu; " f"{ENAZ} aboneden kucuk {len(OLCULMEYEN)} tanesi olculmedi " f"({', '.join(g + ' ' + str(n) for g, n in OLCULMEYEN)})") print(f"olculen {len(ALTGRUP)} alt grupta en iyi {iyi[3]:.4f} ({iyi[0]}), en kotu " f"{kotu[3]:.4f} ({kotu[0]}), alt grup acikligi {iyi[3] - kotu[3]:.4f}; kendi " f"tabaninin altinda kalan {sum(1 for u in ALTGRUP if u[3] < u[2])} alt grup")
sinama kumesi 252 abone; butunde taban 0.7579, model 0.7778, fark +0.0198 eksen alt grup abone taban model fark bolge bati 32 1.0000 0.9688 -0.0312 bolge dogu 36 0.4722 0.6111 +0.1389 bolge guney 58 0.8276 0.8793 +0.0517 bolge kuzey 68 0.8235 0.7794 -0.0441 bolge merkez 58 0.6552 0.6724 +0.0172 tarife basamagi basamak 2 194 0.8402 0.8299 -0.0103 tarife basamagi basamak 3 46 0.4565 0.6304 +0.1739 hane buyuklugu 1-2 kisi 73 0.7534 0.7945 +0.0411 hane buyuklugu 3-4 kisi 143 0.7692 0.7762 +0.0070 hane buyuklugu 5+ kisi 36 0.7222 0.7500 +0.0278 okuma sayisi az okuma 22 0.8636 0.8636 +0.0000 okuma sayisi tam okuma 230 0.7478 0.7696 +0.0217 4 eksende 14 alt grup kuruldu; 20 aboneden kucuk 2 tanesi olculmedi (basamak 1 11, basamak 4 1) olculen 12 alt grupta en iyi 0.9688 (bati), en kotu 0.6111 (dogu), alt grup acikligi 0.3576; kendi tabaninin altinda kalan 3 alt grup
Bütünde okunan cümle tek satırdır: model 0,7778 doğruluk veriyor ve tabanı 0,0198 geçiyor. Alt grup tablosu aynı modeli on iki ayrı yerde ölçüyor ve tek satır on iki cümleye ayrılıyor. En iyi ile en kötü arasındaki alt grup açıklığı 0,3576; bütünde okunan farkın on sekiz katı. Üç alt grupta model kendi tabanının altında kalıyor: kuzeyde 0,0441, batıda 0,0312, tarife basamağı 2’de 0,0103 geride. Batıda taban 1,0000, yani orada hiç şüpheli abone yok ve model üç aboneyi boşuna işaretliyor. “Az okuma” alt grubunda fark tam 0,0000: model o yirmi iki abonede en sık sınıfı söylemekten farklı hiçbir şey yapmıyor. On dört alt grubun ikisi ise hiç ölçülmedi, çünkü sınama kümesinde on bir ve bir aboneye düşüyorlar — ama bu, orada model kullanılmayacağı anlamına gelmez.
Devralan Kişinin Yirmi İki Sorusu
# soru.py — modeli devralan kisinin soru kumesi KURGUDUR ve yirmi iki sorudur. # Her soru, kendisini kapatan tek bir beyan kalemine baglanir; belge surumu bir # kalem kumesidir ve kapanan soru sayisi kumeye bakilarak sayilir. SORU = [ ("model neyi tahmin ediyor", "olcu"), ("hangi sayi raporlandi", "butun"), ("bu sayi hangi kumede olculdu", "kume"), ("taban cizgisi ne ve model onu geciyor mu", "butun"), ("veri hangi donemleri kapsiyor", "kume"), ("modele hangi alanlar giriyor", "oznitelik"), ("etiket nasil uretildi", "etiket"), ("sayi hangi alt gruplarda olculdu", "altgrup_tanim"), ("kac eksende kac alt gruba bakildi", "altgrup_tanim"), ("en kotu alt grupta sayi ne", "altgrup_tablo"), ("alt grup acikligi ne kadar", "altgrup_tablo"), ("hangi alt grupta model kendi tabaninin altinda", "altgrup_tablo"), ("olculmeden birakilan alt grup var mi", "olculmeyen"), ("niye olculmedi", "olculmeyen"), ("model nerede kullanilmaz", "sinir"), ("cikti tek basina bir karar veriyor mu", "karar"), ("cikti hangi esikle karara ceviriliyor", "karar"), ("sayi ne zaman yeniden olculur", "yeniden"), ("abone cikti hakkinda nasil itiraz eder", "itiraz"), ("yanlis cikti aboneye ne yapar", "sonuc"), ("bu sayilari kim dogruladi", "dogrulayan"), ("model bozuldugunda kim geri alir", "geri_alma"), ] A = {"olcu", "butun", "kume"} B = A | {"oznitelik", "etiket", "altgrup_tanim", "altgrup_tablo"} C = B | {"olculmeyen", "sinir", "karar", "yeniden"} SURUM = [("A: yalniz butunde olculen sayi", A), ("B: A + alt grup tablosu", B), ("C: B + kullanim siniri beyani", C)] print(f"{'belge surumu':<32}{'kalem':>6}{'kapanan':>9}{'acik':>6}{'kapali pay':>12}") for ad, s in SURUM: k = sum(1 for _, alan in SORU if alan in s) print(f"{ad:<32}{len(s):>6}{k:>9}{len(SORU) - k:>6}" f"{k / len(SORU):>12.4f}") KAPANMAYAN = [q for q, alan in SORU if alan not in C] print(f"\nuc surumun hicbirinin kapatmadigi {len(KAPANMAYAN)} soru:") for q in KAPANMAYAN: print(f" - {q}")
belge surumu kalem kapanan acik kapali pay A: yalniz butunde olculen sayi 3 5 17 0.2273 B: A + alt grup tablosu 7 12 10 0.5455 C: B + kullanim siniri beyani 11 18 4 0.8182 uc surumun hicbirinin kapatmadigi 4 soru: - abone cikti hakkinda nasil itiraz eder - yanlis cikti aboneye ne yapar - bu sayilari kim dogruladi - model bozuldugunda kim geri alir
Üç kalemlik bir beyan yirmi iki sorunun beşini kapatıyor. Dört kalem eklemek kapanan soruyu on ikiye, dört kalem daha eklemek on sekize çıkarıyor. Kapanan soru sayısı kalem sayısıyla düzgün artmıyor: alt grup tablosu tek başına üç soruya birden yetiyor.
Asıl okunacak yer son listedir. Dört soru üç sürümün hiçbirinde kapanmıyor ve dördü de bir ölçüm sorusu değil. İtiraz yolu, yanlış çıktının aboneye ne yaptığı, sayıyı kimin doğruladığı ve modeli kimin geri alacağı — bunların yanıtı ne sınama kümesinde ne alt grup tablosunda vardır. Bir beyan bu dördünü kapatamaz, ama açık olduklarını yazabilir. Açık bırakılanın sayılması da beyanın ölçüsüdür.
Beyanın Değiştirdiği Karar
# karar.py — devralan kisi bes kullanim karari verir ve yalniz belgeyi okur. # Yordam once alt grup satirini arar; bulamazsa butunde olculen sayiya duser. # C surumu olculmeyen alt gruplari kaydettigi icin "bilinmiyor" diyebilir. SATIR = {u[0]: u for u in ALTGRUP} YOK = dict(OLCULMEYEN) BUTUN = "evet" if m > t else "hayir" def yanit(surum, grup): if "altgrup_tablo" in surum and grup in SATIR: return "evet" if SATIR[grup][3] > SATIR[grup][2] else "hayir" if "olculmeyen" in surum and grup in YOK: return "bilinmiyor" return BUTUN def gercek(grup): if grup in SATIR: return "evet" if SATIR[grup][3] > SATIR[grup][2] else "hayir" return "bilinmiyor" KARAR = ["kuzey", "dogu", "bati", "az okuma", "basamak 4"] print(f"{'alt grup':<12}{'olculen':>12}" + "".join(f"{'surum ' + ad.split(':')[0]:>12}" for ad, _ in SURUM)) for g in KARAR: print(f"{g:<12}{gercek(g):>12}" + "".join(f"{yanit(s, g):>12}" for _, s in SURUM)) print() for ad, s in SURUM: y = sum(1 for g in KARAR if yanit(s, g) != gercek(g)) print(f"{ad:<32}{len(KARAR) - y} dogru, {y} yanlis karar") print(f"\nbutunde model tabani {m - t:+.4f} geciyor; kuzeyde " f"{SATIR['kuzey'][3] - SATIR['kuzey'][2]:+.4f}, batida " f"{SATIR['bati'][3] - SATIR['bati'][2]:+.4f}, az okumada " f"{SATIR['az okuma'][3] - SATIR['az okuma'][2]:+.4f}")
alt grup olculen surum A surum B surum C kuzey hayir evet hayir hayir dogu evet evet evet evet bati hayir evet hayir hayir az okuma hayir evet hayir hayir basamak 4 bilinmiyor evet evet bilinmiyor A: yalniz butunde olculen sayi 1 dogru, 4 yanlis karar B: A + alt grup tablosu 4 dogru, 1 yanlis karar C: B + kullanim siniri beyani 5 dogru, 0 yanlis karar butunde model tabani +0.0198 geciyor; kuzeyde -0.0441, batida -0.0312, az okumada +0.0000
Soru “modeli bu alt grupta kullanmak taban çizgisinden iyi bir şey katıyor mu” sorusudur ve beş kez soruluyor. A sürümünü okuyan kişi beşinde de “evet” diyor, çünkü elinde tek bir sayı var ve o sayı bütün için doğru; dördü yanlış çıkıyor. B sürümü dört kararı düzeltiyor ama beşincisinde yanılıyor: tarife basamağı 4 tablosunda yok, yordam bütünde ölçülen sayıya düşüyor ve ölçülmemiş bir alt grup için ölçülmüş gibi yanıt veriyor.
Beşinci satır dersin sayısıdır. C sürümünün B’den tek farkı, ölçülmeyen iki alt grubu ve niçin ölçülmediğini kaydetmesidir. O kayıt yeni bir başarım getirmiyor; getirdiği tek şey “bilinmiyor” diyebilme yetkisidir ve yanlış kararı sıfıra indiriyor.
Kursun kuralı bu tablonun içinde çalışıyor. A sürümündeki 0,7778 yanlış hesaplanmış değil, kimin için ölçüldüğü yazılmadığı için okunamayan bir sayıdır.
Özet
- Aynı model sınama kümesinde bütünde 0,7778 doğruluk verip tabanı 0,0198 geçerken, dört eksende kurulan 14 alt grubun ölçülebilen 12’sinde en iyi 0,9688 ve en kötü 0,6111 okuyor; alt grup açıklığı 0,3576, yani bütünde okunan farkın on sekiz katı.
- Üç alt grupta model kendi tabanının altında kalıyor (kuzey 0,0441, batı 0,0312, tarife basamağı 2’de 0,0103 geride) ve “az okuma” alt grubunda fark tam 0,0000.
- Yirmi iki soruluk devir soru kümesinden A sürümü 5, B sürümü 12, C sürümü 18 soru kapatıyor; kalem sayısı arttıkça kapanan soru düzgün artmıyor.
- Dört soru hiçbir sürümde kapanmıyor ve dördü de ölçüm sorusu değil; bir beyan onları kapatamaz ama açık olduklarını yazabilir, ve açık bırakılanın sayılması da beyanın ölçüsüdür.
- Beş kullanım kararında A sürümü 4, B sürümü 1 yanlış karar ürettiriyor; C sürümünün tek üstünlüğü ölçülmeyen alt grubu kaydedip “bilinmiyor” diyebilmesi ve bu, yanlış kararı sıfıra indiriyor.
Sonraki Adım
Bu dersin belgesi ölçülen sayıyı taşıyor, ama o sayının ikinci kez üretilebileceğini hiçbir yerde söylemiyor. On dört dersin sayıları tek bir tohumla, tek bir bölmeyle, tek bir eşikle üretildi; bu kalemlerden biri sabitlenmezse hangi sayının ne kadar oynayacağı sorulmadı. Sonraki ders M26/K03’ün hazırlama defterinden M27/K05’in eğitim döngüsüne kadar biriken kalemleri toplar, sabitlenmemiş tek bir kalemin sınama sayısını kaç abone kaydırdığını ölçer ve M27’nin tam kalem listesini verir. O ders aynı zamanda kursu ve müfredatı kapatır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.